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.update(cx, |lsp_store, cx| {
  535                                    lsp_store.cleanup_lsp_data(server_id);
  536                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  537                                });
  538                            }
  539                        })?;
  540
  541                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  542                        did_change_configuration_params,
  543                    )?;
  544
  545                    anyhow::Ok(language_server)
  546                }
  547                .await;
  548
  549                match result {
  550                    Ok(server) => {
  551                        lsp_store
  552                            .update(cx, |lsp_store, cx| {
  553                                lsp_store.insert_newly_running_language_server(
  554                                    adapter,
  555                                    server.clone(),
  556                                    server_id,
  557                                    key,
  558                                    pending_workspace_folders,
  559                                    cx,
  560                                );
  561                            })
  562                            .ok();
  563                        stderr_capture.lock().take();
  564                        Some(server)
  565                    }
  566
  567                    Err(err) => {
  568                        let log = stderr_capture.lock().take().unwrap_or_default();
  569                        delegate.update_status(
  570                            adapter.name(),
  571                            BinaryStatus::Failed {
  572                                error: if log.is_empty() {
  573                                    format!("{err:#}")
  574                                } else {
  575                                    format!("{err:#}\n-- stderr --\n{log}")
  576                                },
  577                            },
  578                        );
  579                        log::error!(
  580                            "Failed to start language server {server_name:?}: {}",
  581                            redact_command(&format!("{err:?}"))
  582                        );
  583                        if !log.is_empty() {
  584                            log::error!("server stderr: {}", redact_command(&log));
  585                        }
  586                        None
  587                    }
  588                }
  589            })
  590        };
  591        let state = LanguageServerState::Starting {
  592            startup,
  593            pending_workspace_folders,
  594        };
  595
  596        if update_binary_status {
  597            self.languages
  598                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  599        }
  600
  601        self.language_servers.insert(server_id, state);
  602        self.language_server_ids
  603            .entry(key)
  604            .or_insert(UnifiedLanguageServer {
  605                id: server_id,
  606                project_roots: Default::default(),
  607            });
  608        server_id
  609    }
  610
  611    fn get_language_server_binary(
  612        &self,
  613        worktree_abs_path: Arc<Path>,
  614        adapter: Arc<CachedLspAdapter>,
  615        settings: Arc<LspSettings>,
  616        toolchain: Option<Toolchain>,
  617        delegate: Arc<dyn LspAdapterDelegate>,
  618        allow_binary_download: bool,
  619        untrusted_worktree_task: Option<Receiver<()>>,
  620        cx: &mut App,
  621    ) -> Task<Result<LanguageServerBinary>> {
  622        if let Some(settings) = &settings.binary
  623            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  624        {
  625            let settings = settings.clone();
  626            let languages = self.languages.clone();
  627            return cx.background_spawn(async move {
  628                if let Some(untrusted_worktree_task) = untrusted_worktree_task {
  629                    log::info!(
  630                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  631                        adapter.name(),
  632                    );
  633                    untrusted_worktree_task.recv().await.ok();
  634                    log::info!(
  635                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  636                        adapter.name(),
  637                    );
  638                    languages
  639                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  640                }
  641                let mut env = delegate.shell_env().await;
  642                env.extend(settings.env.unwrap_or_default());
  643
  644                Ok(LanguageServerBinary {
  645                    path: delegate.resolve_executable_path(path),
  646                    env: Some(env),
  647                    arguments: settings
  648                        .arguments
  649                        .unwrap_or_default()
  650                        .iter()
  651                        .map(Into::into)
  652                        .collect(),
  653                })
  654            });
  655        }
  656        let lsp_binary_options = LanguageServerBinaryOptions {
  657            allow_path_lookup: !settings
  658                .binary
  659                .as_ref()
  660                .and_then(|b| b.ignore_system_version)
  661                .unwrap_or_default(),
  662            allow_binary_download,
  663            pre_release: settings
  664                .fetch
  665                .as_ref()
  666                .and_then(|f| f.pre_release)
  667                .unwrap_or(false),
  668        };
  669
  670        cx.spawn(async move |cx| {
  671            if let Some(untrusted_worktree_task) = untrusted_worktree_task {
  672                log::info!(
  673                    "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  674                    adapter.name(),
  675                );
  676                untrusted_worktree_task.recv().await.ok();
  677                log::info!(
  678                    "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  679                    adapter.name(),
  680                );
  681            }
  682
  683            let (existing_binary, maybe_download_binary) = adapter
  684                .clone()
  685                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  686                .await
  687                .await;
  688
  689            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  690
  691            let mut binary = match (existing_binary, maybe_download_binary) {
  692                (binary, None) => binary?,
  693                (Err(_), Some(downloader)) => downloader.await?,
  694                (Ok(existing_binary), Some(downloader)) => {
  695                    let mut download_timeout = cx
  696                        .background_executor()
  697                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  698                        .fuse();
  699                    let mut downloader = downloader.fuse();
  700                    futures::select! {
  701                        _ = download_timeout => {
  702                            // Return existing binary and kick the existing work to the background.
  703                            cx.spawn(async move |_| downloader.await).detach();
  704                            Ok(existing_binary)
  705                        },
  706                        downloaded_or_existing_binary = downloader => {
  707                            // If download fails, this results in the existing binary.
  708                            downloaded_or_existing_binary
  709                        }
  710                    }?
  711                }
  712            };
  713            let mut shell_env = delegate.shell_env().await;
  714
  715            shell_env.extend(binary.env.unwrap_or_default());
  716
  717            if let Some(settings) = settings.binary.as_ref() {
  718                if let Some(arguments) = &settings.arguments {
  719                    binary.arguments = arguments.iter().map(Into::into).collect();
  720                }
  721                if let Some(env) = &settings.env {
  722                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  723                }
  724            }
  725
  726            binary.env = Some(shell_env);
  727            Ok(binary)
  728        })
  729    }
  730
  731    fn setup_lsp_messages(
  732        lsp_store: WeakEntity<LspStore>,
  733        language_server: &LanguageServer,
  734        delegate: Arc<dyn LspAdapterDelegate>,
  735        adapter: Arc<CachedLspAdapter>,
  736    ) {
  737        let name = language_server.name();
  738        let server_id = language_server.server_id();
  739        language_server
  740            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  741                let adapter = adapter.clone();
  742                let this = lsp_store.clone();
  743                move |mut params, cx| {
  744                    let adapter = adapter.clone();
  745                    if let Some(this) = this.upgrade() {
  746                        this.update(cx, |this, cx| {
  747                            {
  748                                let buffer = params
  749                                    .uri
  750                                    .to_file_path()
  751                                    .map(|file_path| this.get_buffer(&file_path, cx))
  752                                    .ok()
  753                                    .flatten();
  754                                adapter.process_diagnostics(&mut params, server_id, buffer);
  755                            }
  756
  757                            this.merge_lsp_diagnostics(
  758                                DiagnosticSourceKind::Pushed,
  759                                vec![DocumentDiagnosticsUpdate {
  760                                    server_id,
  761                                    diagnostics: params,
  762                                    result_id: None,
  763                                    disk_based_sources: Cow::Borrowed(
  764                                        &adapter.disk_based_diagnostic_sources,
  765                                    ),
  766                                    registration_id: None,
  767                                }],
  768                                |_, diagnostic, cx| match diagnostic.source_kind {
  769                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  770                                        adapter.retain_old_diagnostic(diagnostic, cx)
  771                                    }
  772                                    DiagnosticSourceKind::Pulled => true,
  773                                },
  774                                cx,
  775                            )
  776                            .log_err();
  777                        });
  778                    }
  779                }
  780            })
  781            .detach();
  782        language_server
  783            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  784                let adapter = adapter.adapter.clone();
  785                let delegate = delegate.clone();
  786                let this = lsp_store.clone();
  787                move |params, cx| {
  788                    let adapter = adapter.clone();
  789                    let delegate = delegate.clone();
  790                    let this = this.clone();
  791                    let mut cx = cx.clone();
  792                    async move {
  793                        let toolchain_for_id = this
  794                            .update(&mut cx, |this, _| {
  795                                this.as_local()?.language_server_ids.iter().find_map(
  796                                    |(seed, value)| {
  797                                        (value.id == server_id).then(|| seed.toolchain.clone())
  798                                    },
  799                                )
  800                            })?
  801                            .context("Expected the LSP store to be in a local mode")?;
  802
  803                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  804                        for item in &params.items {
  805                            let scope_uri = item.scope_uri.clone();
  806                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  807                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  808                            else {
  809                                // We've already queried workspace configuration of this URI.
  810                                continue;
  811                            };
  812                            let workspace_config = Self::workspace_configuration_for_adapter(
  813                                adapter.clone(),
  814                                &delegate,
  815                                toolchain_for_id.clone(),
  816                                scope_uri,
  817                                &mut cx,
  818                            )
  819                            .await?;
  820                            new_scope_uri.insert(workspace_config);
  821                        }
  822
  823                        Ok(params
  824                            .items
  825                            .into_iter()
  826                            .filter_map(|item| {
  827                                let workspace_config =
  828                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  829                                if let Some(section) = &item.section {
  830                                    Some(
  831                                        workspace_config
  832                                            .get(section)
  833                                            .cloned()
  834                                            .unwrap_or(serde_json::Value::Null),
  835                                    )
  836                                } else {
  837                                    Some(workspace_config.clone())
  838                                }
  839                            })
  840                            .collect())
  841                    }
  842                }
  843            })
  844            .detach();
  845
  846        language_server
  847            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  848                let this = lsp_store.clone();
  849                move |_, cx| {
  850                    let this = this.clone();
  851                    let cx = cx.clone();
  852                    async move {
  853                        let Some(server) =
  854                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  855                        else {
  856                            return Ok(None);
  857                        };
  858                        let root = server.workspace_folders();
  859                        Ok(Some(
  860                            root.into_iter()
  861                                .map(|uri| WorkspaceFolder {
  862                                    uri,
  863                                    name: Default::default(),
  864                                })
  865                                .collect(),
  866                        ))
  867                    }
  868                }
  869            })
  870            .detach();
  871        // Even though we don't have handling for these requests, respond to them to
  872        // avoid stalling any language server like `gopls` which waits for a response
  873        // to these requests when initializing.
  874        language_server
  875            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  876                let this = lsp_store.clone();
  877                move |params, cx| {
  878                    let this = this.clone();
  879                    let mut cx = cx.clone();
  880                    async move {
  881                        this.update(&mut cx, |this, _| {
  882                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  883                            {
  884                                status
  885                                    .progress_tokens
  886                                    .insert(ProgressToken::from_lsp(params.token));
  887                            }
  888                        })?;
  889
  890                        Ok(())
  891                    }
  892                }
  893            })
  894            .detach();
  895
  896        language_server
  897            .on_request::<lsp::request::RegisterCapability, _, _>({
  898                let lsp_store = lsp_store.clone();
  899                move |params, cx| {
  900                    let lsp_store = lsp_store.clone();
  901                    let mut cx = cx.clone();
  902                    async move {
  903                        lsp_store
  904                            .update(&mut cx, |lsp_store, cx| {
  905                                if lsp_store.as_local().is_some() {
  906                                    match lsp_store
  907                                        .register_server_capabilities(server_id, params, cx)
  908                                    {
  909                                        Ok(()) => {}
  910                                        Err(e) => {
  911                                            log::error!(
  912                                                "Failed to register server capabilities: {e:#}"
  913                                            );
  914                                        }
  915                                    };
  916                                }
  917                            })
  918                            .ok();
  919                        Ok(())
  920                    }
  921                }
  922            })
  923            .detach();
  924
  925        language_server
  926            .on_request::<lsp::request::UnregisterCapability, _, _>({
  927                let lsp_store = lsp_store.clone();
  928                move |params, cx| {
  929                    let lsp_store = lsp_store.clone();
  930                    let mut cx = cx.clone();
  931                    async move {
  932                        lsp_store
  933                            .update(&mut cx, |lsp_store, cx| {
  934                                if lsp_store.as_local().is_some() {
  935                                    match lsp_store
  936                                        .unregister_server_capabilities(server_id, params, cx)
  937                                    {
  938                                        Ok(()) => {}
  939                                        Err(e) => {
  940                                            log::error!(
  941                                                "Failed to unregister server capabilities: {e:#}"
  942                                            );
  943                                        }
  944                                    }
  945                                }
  946                            })
  947                            .ok();
  948                        Ok(())
  949                    }
  950                }
  951            })
  952            .detach();
  953
  954        language_server
  955            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  956                let this = lsp_store.clone();
  957                move |params, cx| {
  958                    let mut cx = cx.clone();
  959                    let this = this.clone();
  960                    async move {
  961                        LocalLspStore::on_lsp_workspace_edit(
  962                            this.clone(),
  963                            params,
  964                            server_id,
  965                            &mut cx,
  966                        )
  967                        .await
  968                    }
  969                }
  970            })
  971            .detach();
  972
  973        language_server
  974            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  975                let lsp_store = lsp_store.clone();
  976                let request_id = Arc::new(AtomicUsize::new(0));
  977                move |(), cx| {
  978                    let lsp_store = lsp_store.clone();
  979                    let request_id = request_id.clone();
  980                    let mut cx = cx.clone();
  981                    async move {
  982                        lsp_store
  983                            .update(&mut cx, |lsp_store, cx| {
  984                                let request_id =
  985                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
  986                                cx.emit(LspStoreEvent::RefreshInlayHints {
  987                                    server_id,
  988                                    request_id,
  989                                });
  990                                lsp_store
  991                                    .downstream_client
  992                                    .as_ref()
  993                                    .map(|(client, project_id)| {
  994                                        client.send(proto::RefreshInlayHints {
  995                                            project_id: *project_id,
  996                                            server_id: server_id.to_proto(),
  997                                            request_id: request_id.map(|id| id as u64),
  998                                        })
  999                                    })
 1000                            })?
 1001                            .transpose()?;
 1002                        Ok(())
 1003                    }
 1004                }
 1005            })
 1006            .detach();
 1007
 1008        language_server
 1009            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1010                let this = lsp_store.clone();
 1011                move |(), cx| {
 1012                    let this = this.clone();
 1013                    let mut cx = cx.clone();
 1014                    async move {
 1015                        this.update(&mut cx, |this, cx| {
 1016                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1017                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1018                                client.send(proto::RefreshCodeLens {
 1019                                    project_id: *project_id,
 1020                                })
 1021                            })
 1022                        })?
 1023                        .transpose()?;
 1024                        Ok(())
 1025                    }
 1026                }
 1027            })
 1028            .detach();
 1029
 1030        language_server
 1031            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1032                let this = lsp_store.clone();
 1033                move |(), cx| {
 1034                    let this = this.clone();
 1035                    let mut cx = cx.clone();
 1036                    async move {
 1037                        this.update(&mut cx, |lsp_store, cx| {
 1038                            lsp_store.pull_workspace_diagnostics(server_id);
 1039                            lsp_store
 1040                                .downstream_client
 1041                                .as_ref()
 1042                                .map(|(client, project_id)| {
 1043                                    client.send(proto::PullWorkspaceDiagnostics {
 1044                                        project_id: *project_id,
 1045                                        server_id: server_id.to_proto(),
 1046                                    })
 1047                                })
 1048                                .transpose()?;
 1049                            anyhow::Ok(
 1050                                lsp_store.pull_document_diagnostics_for_server(server_id, cx),
 1051                            )
 1052                        })??
 1053                        .await;
 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                    }
 1155                }
 1156            })
 1157            .detach();
 1158
 1159        language_server
 1160            .on_notification::<lsp::notification::LogMessage, _>({
 1161                let this = lsp_store.clone();
 1162                move |params, cx| {
 1163                    if let Some(this) = this.upgrade() {
 1164                        this.update(cx, |_, cx| {
 1165                            cx.emit(LspStoreEvent::LanguageServerLog(
 1166                                server_id,
 1167                                LanguageServerLogType::Log(params.typ),
 1168                                params.message,
 1169                            ));
 1170                        });
 1171                    }
 1172                }
 1173            })
 1174            .detach();
 1175
 1176        language_server
 1177            .on_notification::<lsp::notification::LogTrace, _>({
 1178                let this = lsp_store.clone();
 1179                move |params, cx| {
 1180                    let mut cx = cx.clone();
 1181                    if let Some(this) = this.upgrade() {
 1182                        this.update(&mut cx, |_, cx| {
 1183                            cx.emit(LspStoreEvent::LanguageServerLog(
 1184                                server_id,
 1185                                LanguageServerLogType::Trace {
 1186                                    verbose_info: params.verbose,
 1187                                },
 1188                                params.message,
 1189                            ));
 1190                        });
 1191                    }
 1192                }
 1193            })
 1194            .detach();
 1195
 1196        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1197        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1198        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1199        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1200    }
 1201
 1202    fn shutdown_language_servers_on_quit(
 1203        &mut self,
 1204        _: &mut Context<LspStore>,
 1205    ) -> impl Future<Output = ()> + use<> {
 1206        let shutdown_futures = self
 1207            .language_servers
 1208            .drain()
 1209            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1210            .collect::<Vec<_>>();
 1211
 1212        async move {
 1213            join_all(shutdown_futures).await;
 1214        }
 1215    }
 1216
 1217    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1218        match server_state {
 1219            LanguageServerState::Running { server, .. } => {
 1220                if let Some(shutdown) = server.shutdown() {
 1221                    shutdown.await;
 1222                }
 1223            }
 1224            LanguageServerState::Starting { startup, .. } => {
 1225                if let Some(server) = startup.await
 1226                    && let Some(shutdown) = server.shutdown()
 1227                {
 1228                    shutdown.await;
 1229                }
 1230            }
 1231        }
 1232        Ok(())
 1233    }
 1234
 1235    fn language_servers_for_worktree(
 1236        &self,
 1237        worktree_id: WorktreeId,
 1238    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1239        self.language_server_ids
 1240            .iter()
 1241            .filter_map(move |(seed, state)| {
 1242                if seed.worktree_id != worktree_id {
 1243                    return None;
 1244                }
 1245
 1246                if let Some(LanguageServerState::Running { server, .. }) =
 1247                    self.language_servers.get(&state.id)
 1248                {
 1249                    Some(server)
 1250                } else {
 1251                    None
 1252                }
 1253            })
 1254    }
 1255
 1256    fn language_server_ids_for_project_path(
 1257        &self,
 1258        project_path: ProjectPath,
 1259        language: &Language,
 1260        cx: &mut App,
 1261    ) -> Vec<LanguageServerId> {
 1262        let Some(worktree) = self
 1263            .worktree_store
 1264            .read(cx)
 1265            .worktree_for_id(project_path.worktree_id, cx)
 1266        else {
 1267            return Vec::new();
 1268        };
 1269        let delegate: Arc<dyn ManifestDelegate> =
 1270            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1271
 1272        self.lsp_tree
 1273            .get(
 1274                project_path,
 1275                language.name(),
 1276                language.manifest(),
 1277                &delegate,
 1278                cx,
 1279            )
 1280            .collect::<Vec<_>>()
 1281    }
 1282
 1283    fn language_server_ids_for_buffer(
 1284        &self,
 1285        buffer: &Buffer,
 1286        cx: &mut App,
 1287    ) -> Vec<LanguageServerId> {
 1288        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1289            let worktree_id = file.worktree_id(cx);
 1290
 1291            let path: Arc<RelPath> = file
 1292                .path()
 1293                .parent()
 1294                .map(Arc::from)
 1295                .unwrap_or_else(|| file.path().clone());
 1296            let worktree_path = ProjectPath { worktree_id, path };
 1297            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1298        } else {
 1299            Vec::new()
 1300        }
 1301    }
 1302
 1303    fn language_servers_for_buffer<'a>(
 1304        &'a self,
 1305        buffer: &'a Buffer,
 1306        cx: &'a mut App,
 1307    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1308        self.language_server_ids_for_buffer(buffer, cx)
 1309            .into_iter()
 1310            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1311                LanguageServerState::Running {
 1312                    adapter, server, ..
 1313                } => Some((adapter, server)),
 1314                _ => None,
 1315            })
 1316    }
 1317
 1318    async fn execute_code_action_kind_locally(
 1319        lsp_store: WeakEntity<LspStore>,
 1320        mut buffers: Vec<Entity<Buffer>>,
 1321        kind: CodeActionKind,
 1322        push_to_history: bool,
 1323        cx: &mut AsyncApp,
 1324    ) -> anyhow::Result<ProjectTransaction> {
 1325        // Do not allow multiple concurrent code actions requests for the
 1326        // same buffer.
 1327        lsp_store.update(cx, |this, cx| {
 1328            let this = this.as_local_mut().unwrap();
 1329            buffers.retain(|buffer| {
 1330                this.buffers_being_formatted
 1331                    .insert(buffer.read(cx).remote_id())
 1332            });
 1333        })?;
 1334        let _cleanup = defer({
 1335            let this = lsp_store.clone();
 1336            let mut cx = cx.clone();
 1337            let buffers = &buffers;
 1338            move || {
 1339                this.update(&mut cx, |this, cx| {
 1340                    let this = this.as_local_mut().unwrap();
 1341                    for buffer in buffers {
 1342                        this.buffers_being_formatted
 1343                            .remove(&buffer.read(cx).remote_id());
 1344                    }
 1345                })
 1346                .ok();
 1347            }
 1348        });
 1349        let mut project_transaction = ProjectTransaction::default();
 1350
 1351        for buffer in &buffers {
 1352            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1353                buffer.update(cx, |buffer, cx| {
 1354                    lsp_store
 1355                        .as_local()
 1356                        .unwrap()
 1357                        .language_servers_for_buffer(buffer, cx)
 1358                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1359                        .collect::<Vec<_>>()
 1360                })
 1361            })?;
 1362            for (_, language_server) in adapters_and_servers.iter() {
 1363                let actions = Self::get_server_code_actions_from_action_kinds(
 1364                    &lsp_store,
 1365                    language_server.server_id(),
 1366                    vec![kind.clone()],
 1367                    buffer,
 1368                    cx,
 1369                )
 1370                .await?;
 1371                Self::execute_code_actions_on_server(
 1372                    &lsp_store,
 1373                    language_server,
 1374                    actions,
 1375                    push_to_history,
 1376                    &mut project_transaction,
 1377                    cx,
 1378                )
 1379                .await?;
 1380            }
 1381        }
 1382        Ok(project_transaction)
 1383    }
 1384
 1385    async fn format_locally(
 1386        lsp_store: WeakEntity<LspStore>,
 1387        mut buffers: Vec<FormattableBuffer>,
 1388        push_to_history: bool,
 1389        trigger: FormatTrigger,
 1390        logger: zlog::Logger,
 1391        cx: &mut AsyncApp,
 1392    ) -> anyhow::Result<ProjectTransaction> {
 1393        // Do not allow multiple concurrent formatting requests for the
 1394        // same buffer.
 1395        lsp_store.update(cx, |this, cx| {
 1396            let this = this.as_local_mut().unwrap();
 1397            buffers.retain(|buffer| {
 1398                this.buffers_being_formatted
 1399                    .insert(buffer.handle.read(cx).remote_id())
 1400            });
 1401        })?;
 1402
 1403        let _cleanup = defer({
 1404            let this = lsp_store.clone();
 1405            let mut cx = cx.clone();
 1406            let buffers = &buffers;
 1407            move || {
 1408                this.update(&mut cx, |this, cx| {
 1409                    let this = this.as_local_mut().unwrap();
 1410                    for buffer in buffers {
 1411                        this.buffers_being_formatted
 1412                            .remove(&buffer.handle.read(cx).remote_id());
 1413                    }
 1414                })
 1415                .ok();
 1416            }
 1417        });
 1418
 1419        let mut project_transaction = ProjectTransaction::default();
 1420
 1421        for buffer in &buffers {
 1422            zlog::debug!(
 1423                logger =>
 1424                "formatting buffer '{:?}'",
 1425                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1426            );
 1427            // Create an empty transaction to hold all of the formatting edits.
 1428            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1429                // ensure no transactions created while formatting are
 1430                // grouped with the previous transaction in the history
 1431                // based on the transaction group interval
 1432                buffer.finalize_last_transaction();
 1433                buffer
 1434                    .start_transaction()
 1435                    .context("transaction already open")?;
 1436                buffer.end_transaction(cx);
 1437                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1438                buffer.finalize_last_transaction();
 1439                anyhow::Ok(transaction_id)
 1440            })?;
 1441
 1442            let result = Self::format_buffer_locally(
 1443                lsp_store.clone(),
 1444                buffer,
 1445                formatting_transaction_id,
 1446                trigger,
 1447                logger,
 1448                cx,
 1449            )
 1450            .await;
 1451
 1452            buffer.handle.update(cx, |buffer, cx| {
 1453                let Some(formatting_transaction) =
 1454                    buffer.get_transaction(formatting_transaction_id).cloned()
 1455                else {
 1456                    zlog::warn!(logger => "no formatting transaction");
 1457                    return;
 1458                };
 1459                if formatting_transaction.edit_ids.is_empty() {
 1460                    zlog::debug!(logger => "no changes made while formatting");
 1461                    buffer.forget_transaction(formatting_transaction_id);
 1462                    return;
 1463                }
 1464                if !push_to_history {
 1465                    zlog::trace!(logger => "forgetting format transaction");
 1466                    buffer.forget_transaction(formatting_transaction.id);
 1467                }
 1468                project_transaction
 1469                    .0
 1470                    .insert(cx.entity(), formatting_transaction);
 1471            });
 1472
 1473            result?;
 1474        }
 1475
 1476        Ok(project_transaction)
 1477    }
 1478
 1479    async fn format_buffer_locally(
 1480        lsp_store: WeakEntity<LspStore>,
 1481        buffer: &FormattableBuffer,
 1482        formatting_transaction_id: clock::Lamport,
 1483        trigger: FormatTrigger,
 1484        logger: zlog::Logger,
 1485        cx: &mut AsyncApp,
 1486    ) -> Result<()> {
 1487        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1488            buffer.handle.update(cx, |buffer, cx| {
 1489                let adapters_and_servers = lsp_store
 1490                    .as_local()
 1491                    .unwrap()
 1492                    .language_servers_for_buffer(buffer, cx)
 1493                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1494                    .collect::<Vec<_>>();
 1495                let settings =
 1496                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1497                        .into_owned();
 1498                (adapters_and_servers, settings)
 1499            })
 1500        })?;
 1501
 1502        /// Apply edits to the buffer that will become part of the formatting transaction.
 1503        /// Fails if the buffer has been edited since the start of that transaction.
 1504        fn extend_formatting_transaction(
 1505            buffer: &FormattableBuffer,
 1506            formatting_transaction_id: text::TransactionId,
 1507            cx: &mut AsyncApp,
 1508            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1509        ) -> anyhow::Result<()> {
 1510            buffer.handle.update(cx, |buffer, cx| {
 1511                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1512                if last_transaction_id != Some(formatting_transaction_id) {
 1513                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1514                }
 1515                buffer.start_transaction();
 1516                operation(buffer, cx);
 1517                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1518                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1519                }
 1520                Ok(())
 1521            })
 1522        }
 1523
 1524        // handle whitespace formatting
 1525        if settings.remove_trailing_whitespace_on_save {
 1526            zlog::trace!(logger => "removing trailing whitespace");
 1527            let diff = buffer
 1528                .handle
 1529                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1530                .await;
 1531            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1532                buffer.apply_diff(diff, cx);
 1533            })?;
 1534        }
 1535
 1536        if settings.ensure_final_newline_on_save {
 1537            zlog::trace!(logger => "ensuring final newline");
 1538            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1539                buffer.ensure_final_newline(cx);
 1540            })?;
 1541        }
 1542
 1543        // Formatter for `code_actions_on_format` that runs before
 1544        // the rest of the formatters
 1545        let mut code_actions_on_format_formatters = None;
 1546        let should_run_code_actions_on_format = !matches!(
 1547            (trigger, &settings.format_on_save),
 1548            (FormatTrigger::Save, &FormatOnSave::Off)
 1549        );
 1550        if should_run_code_actions_on_format {
 1551            let have_code_actions_to_run_on_format = settings
 1552                .code_actions_on_format
 1553                .values()
 1554                .any(|enabled| *enabled);
 1555            if have_code_actions_to_run_on_format {
 1556                zlog::trace!(logger => "going to run code actions on format");
 1557                code_actions_on_format_formatters = Some(
 1558                    settings
 1559                        .code_actions_on_format
 1560                        .iter()
 1561                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1562                        .cloned()
 1563                        .map(Formatter::CodeAction)
 1564                        .collect::<Vec<_>>(),
 1565                );
 1566            }
 1567        }
 1568
 1569        let formatters = match (trigger, &settings.format_on_save) {
 1570            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1571            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1572                settings.formatter.as_ref()
 1573            }
 1574        };
 1575
 1576        let formatters = code_actions_on_format_formatters
 1577            .iter()
 1578            .flatten()
 1579            .chain(formatters);
 1580
 1581        for formatter in formatters {
 1582            let formatter = if formatter == &Formatter::Auto {
 1583                if settings.prettier.allowed {
 1584                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1585                    &Formatter::Prettier
 1586                } else {
 1587                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1588                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1589                }
 1590            } else {
 1591                formatter
 1592            };
 1593            match formatter {
 1594                Formatter::Auto => unreachable!("Auto resolved above"),
 1595                Formatter::Prettier => {
 1596                    let logger = zlog::scoped!(logger => "prettier");
 1597                    zlog::trace!(logger => "formatting");
 1598                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1599
 1600                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1601                        lsp_store.prettier_store().unwrap().downgrade()
 1602                    })?;
 1603                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1604                        .await
 1605                        .transpose()?;
 1606                    let Some(diff) = diff else {
 1607                        zlog::trace!(logger => "No changes");
 1608                        continue;
 1609                    };
 1610
 1611                    extend_formatting_transaction(
 1612                        buffer,
 1613                        formatting_transaction_id,
 1614                        cx,
 1615                        |buffer, cx| {
 1616                            buffer.apply_diff(diff, cx);
 1617                        },
 1618                    )?;
 1619                }
 1620                Formatter::External { command, arguments } => {
 1621                    let logger = zlog::scoped!(logger => "command");
 1622                    zlog::trace!(logger => "formatting");
 1623                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1624
 1625                    let diff = Self::format_via_external_command(
 1626                        buffer,
 1627                        command.as_ref(),
 1628                        arguments.as_deref(),
 1629                        cx,
 1630                    )
 1631                    .await
 1632                    .with_context(|| {
 1633                        format!("Failed to format buffer via external command: {}", command)
 1634                    })?;
 1635                    let Some(diff) = diff else {
 1636                        zlog::trace!(logger => "No changes");
 1637                        continue;
 1638                    };
 1639
 1640                    extend_formatting_transaction(
 1641                        buffer,
 1642                        formatting_transaction_id,
 1643                        cx,
 1644                        |buffer, cx| {
 1645                            buffer.apply_diff(diff, cx);
 1646                        },
 1647                    )?;
 1648                }
 1649                Formatter::LanguageServer(specifier) => {
 1650                    let logger = zlog::scoped!(logger => "language-server");
 1651                    zlog::trace!(logger => "formatting");
 1652                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1653
 1654                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1655                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1656                        continue;
 1657                    };
 1658
 1659                    let language_server = match specifier {
 1660                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1661                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1662                                if adapter.name.0.as_ref() == name {
 1663                                    Some(server.clone())
 1664                                } else {
 1665                                    None
 1666                                }
 1667                            })
 1668                        }
 1669                        settings::LanguageServerFormatterSpecifier::Current => {
 1670                            adapters_and_servers.first().map(|e| e.1.clone())
 1671                        }
 1672                    };
 1673
 1674                    let Some(language_server) = language_server else {
 1675                        log::debug!(
 1676                            "No language server found to format buffer '{:?}'. Skipping",
 1677                            buffer_path_abs.as_path().to_string_lossy()
 1678                        );
 1679                        continue;
 1680                    };
 1681
 1682                    zlog::trace!(
 1683                        logger =>
 1684                        "Formatting buffer '{:?}' using language server '{:?}'",
 1685                        buffer_path_abs.as_path().to_string_lossy(),
 1686                        language_server.name()
 1687                    );
 1688
 1689                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1690                        zlog::trace!(logger => "formatting ranges");
 1691                        Self::format_ranges_via_lsp(
 1692                            &lsp_store,
 1693                            &buffer.handle,
 1694                            ranges,
 1695                            buffer_path_abs,
 1696                            &language_server,
 1697                            &settings,
 1698                            cx,
 1699                        )
 1700                        .await
 1701                        .context("Failed to format ranges via language server")?
 1702                    } else {
 1703                        zlog::trace!(logger => "formatting full");
 1704                        Self::format_via_lsp(
 1705                            &lsp_store,
 1706                            &buffer.handle,
 1707                            buffer_path_abs,
 1708                            &language_server,
 1709                            &settings,
 1710                            cx,
 1711                        )
 1712                        .await
 1713                        .context("failed to format via language server")?
 1714                    };
 1715
 1716                    if edits.is_empty() {
 1717                        zlog::trace!(logger => "No changes");
 1718                        continue;
 1719                    }
 1720                    extend_formatting_transaction(
 1721                        buffer,
 1722                        formatting_transaction_id,
 1723                        cx,
 1724                        |buffer, cx| {
 1725                            buffer.edit(edits, None, cx);
 1726                        },
 1727                    )?;
 1728                }
 1729                Formatter::CodeAction(code_action_name) => {
 1730                    let logger = zlog::scoped!(logger => "code-actions");
 1731                    zlog::trace!(logger => "formatting");
 1732                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1733
 1734                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1735                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1736                        continue;
 1737                    };
 1738
 1739                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1740                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1741
 1742                    let mut actions_and_servers = Vec::new();
 1743
 1744                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1745                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1746                            &lsp_store,
 1747                            language_server.server_id(),
 1748                            vec![code_action_kind.clone()],
 1749                            &buffer.handle,
 1750                            cx,
 1751                        )
 1752                        .await
 1753                        .with_context(|| {
 1754                            format!(
 1755                                "Failed to resolve code action {:?} with language server {}",
 1756                                code_action_kind,
 1757                                language_server.name()
 1758                            )
 1759                        });
 1760                        let Ok(actions) = actions_result else {
 1761                            // note: it may be better to set result to the error and break formatters here
 1762                            // but for now we try to execute the actions that we can resolve and skip the rest
 1763                            zlog::error!(
 1764                                logger =>
 1765                                "Failed to resolve code action {:?} with language server {}",
 1766                                code_action_kind,
 1767                                language_server.name()
 1768                            );
 1769                            continue;
 1770                        };
 1771                        for action in actions {
 1772                            actions_and_servers.push((action, index));
 1773                        }
 1774                    }
 1775
 1776                    if actions_and_servers.is_empty() {
 1777                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1778                        continue;
 1779                    }
 1780
 1781                    'actions: for (mut action, server_index) in actions_and_servers {
 1782                        let server = &adapters_and_servers[server_index].1;
 1783
 1784                        let describe_code_action = |action: &CodeAction| {
 1785                            format!(
 1786                                "code action '{}' with title \"{}\" on server {}",
 1787                                action
 1788                                    .lsp_action
 1789                                    .action_kind()
 1790                                    .unwrap_or("unknown".into())
 1791                                    .as_str(),
 1792                                action.lsp_action.title(),
 1793                                server.name(),
 1794                            )
 1795                        };
 1796
 1797                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1798
 1799                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1800                            zlog::error!(
 1801                                logger =>
 1802                                "Failed to resolve {}. Error: {}",
 1803                                describe_code_action(&action),
 1804                                err
 1805                            );
 1806                            continue;
 1807                        }
 1808
 1809                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1810                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1811                            // but filters out and logs warnings for code actions that require unreasonably
 1812                            // difficult handling on our part, such as:
 1813                            // - applying edits that call commands
 1814                            //   which can result in arbitrary workspace edits being sent from the server that
 1815                            //   have no way of being tied back to the command that initiated them (i.e. we
 1816                            //   can't know which edits are part of the format request, or if the server is done sending
 1817                            //   actions in response to the command)
 1818                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1819                            //   as we then would need to handle such changes correctly in the local history as well
 1820                            //   as the remote history through the ProjectTransaction
 1821                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1822                            // Supporting these actions is not impossible, but not supported as of yet.
 1823                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1824                                zlog::trace!(
 1825                                    logger =>
 1826                                    "No changes for code action. Skipping {}",
 1827                                    describe_code_action(&action),
 1828                                );
 1829                                continue;
 1830                            }
 1831
 1832                            let mut operations = Vec::new();
 1833                            if let Some(document_changes) = edit.document_changes {
 1834                                match document_changes {
 1835                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1836                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1837                                    ),
 1838                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1839                                }
 1840                            } else if let Some(changes) = edit.changes {
 1841                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1842                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1843                                        text_document:
 1844                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1845                                                uri,
 1846                                                version: None,
 1847                                            },
 1848                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1849                                    })
 1850                                }));
 1851                            }
 1852
 1853                            let mut edits = Vec::with_capacity(operations.len());
 1854
 1855                            if operations.is_empty() {
 1856                                zlog::trace!(
 1857                                    logger =>
 1858                                    "No changes for code action. Skipping {}",
 1859                                    describe_code_action(&action),
 1860                                );
 1861                                continue;
 1862                            }
 1863                            for operation in operations {
 1864                                let op = match operation {
 1865                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1866                                    lsp::DocumentChangeOperation::Op(_) => {
 1867                                        zlog::warn!(
 1868                                            logger =>
 1869                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1870                                            describe_code_action(&action),
 1871                                        );
 1872                                        continue 'actions;
 1873                                    }
 1874                                };
 1875                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1876                                    zlog::warn!(
 1877                                        logger =>
 1878                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1879                                        &op.text_document.uri,
 1880                                        describe_code_action(&action),
 1881                                    );
 1882                                    continue 'actions;
 1883                                };
 1884                                if &file_path != buffer_path_abs {
 1885                                    zlog::warn!(
 1886                                        logger =>
 1887                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1888                                        file_path,
 1889                                        buffer_path_abs,
 1890                                        describe_code_action(&action),
 1891                                    );
 1892                                    continue 'actions;
 1893                                }
 1894
 1895                                let mut lsp_edits = Vec::new();
 1896                                for edit in op.edits {
 1897                                    match edit {
 1898                                        Edit::Plain(edit) => {
 1899                                            if !lsp_edits.contains(&edit) {
 1900                                                lsp_edits.push(edit);
 1901                                            }
 1902                                        }
 1903                                        Edit::Annotated(edit) => {
 1904                                            if !lsp_edits.contains(&edit.text_edit) {
 1905                                                lsp_edits.push(edit.text_edit);
 1906                                            }
 1907                                        }
 1908                                        Edit::Snippet(_) => {
 1909                                            zlog::warn!(
 1910                                                logger =>
 1911                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1912                                                describe_code_action(&action),
 1913                                            );
 1914                                            continue 'actions;
 1915                                        }
 1916                                    }
 1917                                }
 1918                                let edits_result = lsp_store
 1919                                    .update(cx, |lsp_store, cx| {
 1920                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1921                                            &buffer.handle,
 1922                                            lsp_edits,
 1923                                            server.server_id(),
 1924                                            op.text_document.version,
 1925                                            cx,
 1926                                        )
 1927                                    })?
 1928                                    .await;
 1929                                let Ok(resolved_edits) = edits_result else {
 1930                                    zlog::warn!(
 1931                                        logger =>
 1932                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1933                                        buffer_path_abs.as_path(),
 1934                                        describe_code_action(&action),
 1935                                    );
 1936                                    continue 'actions;
 1937                                };
 1938                                edits.extend(resolved_edits);
 1939                            }
 1940
 1941                            if edits.is_empty() {
 1942                                zlog::warn!(logger => "No edits resolved from LSP");
 1943                                continue;
 1944                            }
 1945
 1946                            extend_formatting_transaction(
 1947                                buffer,
 1948                                formatting_transaction_id,
 1949                                cx,
 1950                                |buffer, cx| {
 1951                                    zlog::info!(
 1952                                        "Applying edits {edits:?}. Content: {:?}",
 1953                                        buffer.text()
 1954                                    );
 1955                                    buffer.edit(edits, None, cx);
 1956                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1957                                },
 1958                            )?;
 1959                        }
 1960
 1961                        if let Some(command) = action.lsp_action.command() {
 1962                            zlog::warn!(
 1963                                logger =>
 1964                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1965                                &command.command,
 1966                            );
 1967
 1968                            // bail early if command is invalid
 1969                            let server_capabilities = server.capabilities();
 1970                            let available_commands = server_capabilities
 1971                                .execute_command_provider
 1972                                .as_ref()
 1973                                .map(|options| options.commands.as_slice())
 1974                                .unwrap_or_default();
 1975                            if !available_commands.contains(&command.command) {
 1976                                zlog::warn!(
 1977                                    logger =>
 1978                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1979                                    command.command,
 1980                                    server.name(),
 1981                                );
 1982                                continue;
 1983                            }
 1984
 1985                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1986                            extend_formatting_transaction(
 1987                                buffer,
 1988                                formatting_transaction_id,
 1989                                cx,
 1990                                |_, _| {},
 1991                            )?;
 1992                            zlog::info!(logger => "Executing command {}", &command.command);
 1993
 1994                            lsp_store.update(cx, |this, _| {
 1995                                this.as_local_mut()
 1996                                    .unwrap()
 1997                                    .last_workspace_edits_by_language_server
 1998                                    .remove(&server.server_id());
 1999                            })?;
 2000
 2001                            let execute_command_result = server
 2002                                .request::<lsp::request::ExecuteCommand>(
 2003                                    lsp::ExecuteCommandParams {
 2004                                        command: command.command.clone(),
 2005                                        arguments: command.arguments.clone().unwrap_or_default(),
 2006                                        ..Default::default()
 2007                                    },
 2008                                )
 2009                                .await
 2010                                .into_response();
 2011
 2012                            if execute_command_result.is_err() {
 2013                                zlog::error!(
 2014                                    logger =>
 2015                                    "Failed to execute command '{}' as part of {}",
 2016                                    &command.command,
 2017                                    describe_code_action(&action),
 2018                                );
 2019                                continue 'actions;
 2020                            }
 2021
 2022                            let mut project_transaction_command =
 2023                                lsp_store.update(cx, |this, _| {
 2024                                    this.as_local_mut()
 2025                                        .unwrap()
 2026                                        .last_workspace_edits_by_language_server
 2027                                        .remove(&server.server_id())
 2028                                        .unwrap_or_default()
 2029                                })?;
 2030
 2031                            if let Some(transaction) =
 2032                                project_transaction_command.0.remove(&buffer.handle)
 2033                            {
 2034                                zlog::trace!(
 2035                                    logger =>
 2036                                    "Successfully captured {} edits that resulted from command {}",
 2037                                    transaction.edit_ids.len(),
 2038                                    &command.command,
 2039                                );
 2040                                let transaction_id_project_transaction = transaction.id;
 2041                                buffer.handle.update(cx, |buffer, _| {
 2042                                    // it may have been removed from history if push_to_history was
 2043                                    // false in deserialize_workspace_edit. If so push it so we
 2044                                    // can merge it with the format transaction
 2045                                    // and pop the combined transaction off the history stack
 2046                                    // later if push_to_history is false
 2047                                    if buffer.get_transaction(transaction.id).is_none() {
 2048                                        buffer.push_transaction(transaction, Instant::now());
 2049                                    }
 2050                                    buffer.merge_transactions(
 2051                                        transaction_id_project_transaction,
 2052                                        formatting_transaction_id,
 2053                                    );
 2054                                });
 2055                            }
 2056
 2057                            if !project_transaction_command.0.is_empty() {
 2058                                let mut extra_buffers = String::new();
 2059                                for buffer in project_transaction_command.0.keys() {
 2060                                    buffer.read_with(cx, |b, cx| {
 2061                                        if let Some(path) = b.project_path(cx) {
 2062                                            if !extra_buffers.is_empty() {
 2063                                                extra_buffers.push_str(", ");
 2064                                            }
 2065                                            extra_buffers.push_str(path.path.as_unix_str());
 2066                                        }
 2067                                    });
 2068                                }
 2069                                zlog::warn!(
 2070                                    logger =>
 2071                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2072                                    &command.command,
 2073                                    extra_buffers,
 2074                                );
 2075                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2076                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2077                                // add it so it's included, and merge it into the format transaction when its created later
 2078                            }
 2079                        }
 2080                    }
 2081                }
 2082            }
 2083        }
 2084
 2085        Ok(())
 2086    }
 2087
 2088    pub async fn format_ranges_via_lsp(
 2089        this: &WeakEntity<LspStore>,
 2090        buffer_handle: &Entity<Buffer>,
 2091        ranges: &[Range<Anchor>],
 2092        abs_path: &Path,
 2093        language_server: &Arc<LanguageServer>,
 2094        settings: &LanguageSettings,
 2095        cx: &mut AsyncApp,
 2096    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2097        let capabilities = &language_server.capabilities();
 2098        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2099        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2100            anyhow::bail!(
 2101                "{} language server does not support range formatting",
 2102                language_server.name()
 2103            );
 2104        }
 2105
 2106        let uri = file_path_to_lsp_url(abs_path)?;
 2107        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2108
 2109        let lsp_edits = {
 2110            let mut lsp_ranges = Vec::new();
 2111            this.update(cx, |_this, cx| {
 2112                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2113                // not have been sent to the language server. This seems like a fairly systemic
 2114                // issue, though, the resolution probably is not specific to formatting.
 2115                //
 2116                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2117                // LSP.
 2118                let snapshot = buffer_handle.read(cx).snapshot();
 2119                for range in ranges {
 2120                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2121                }
 2122                anyhow::Ok(())
 2123            })??;
 2124
 2125            let mut edits = None;
 2126            for range in lsp_ranges {
 2127                if let Some(mut edit) = language_server
 2128                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2129                        text_document: text_document.clone(),
 2130                        range,
 2131                        options: lsp_command::lsp_formatting_options(settings),
 2132                        work_done_progress_params: Default::default(),
 2133                    })
 2134                    .await
 2135                    .into_response()?
 2136                {
 2137                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2138                }
 2139            }
 2140            edits
 2141        };
 2142
 2143        if let Some(lsp_edits) = lsp_edits {
 2144            this.update(cx, |this, cx| {
 2145                this.as_local_mut().unwrap().edits_from_lsp(
 2146                    buffer_handle,
 2147                    lsp_edits,
 2148                    language_server.server_id(),
 2149                    None,
 2150                    cx,
 2151                )
 2152            })?
 2153            .await
 2154        } else {
 2155            Ok(Vec::with_capacity(0))
 2156        }
 2157    }
 2158
 2159    async fn format_via_lsp(
 2160        this: &WeakEntity<LspStore>,
 2161        buffer: &Entity<Buffer>,
 2162        abs_path: &Path,
 2163        language_server: &Arc<LanguageServer>,
 2164        settings: &LanguageSettings,
 2165        cx: &mut AsyncApp,
 2166    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2167        let logger = zlog::scoped!("lsp_format");
 2168        zlog::debug!(logger => "Formatting via LSP");
 2169
 2170        let uri = file_path_to_lsp_url(abs_path)?;
 2171        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2172        let capabilities = &language_server.capabilities();
 2173
 2174        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2175        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2176
 2177        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2178            let _timer = zlog::time!(logger => "format-full");
 2179            language_server
 2180                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2181                    text_document,
 2182                    options: lsp_command::lsp_formatting_options(settings),
 2183                    work_done_progress_params: Default::default(),
 2184                })
 2185                .await
 2186                .into_response()?
 2187        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2188            let _timer = zlog::time!(logger => "format-range");
 2189            let buffer_start = lsp::Position::new(0, 0);
 2190            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2191            language_server
 2192                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2193                    text_document: text_document.clone(),
 2194                    range: lsp::Range::new(buffer_start, buffer_end),
 2195                    options: lsp_command::lsp_formatting_options(settings),
 2196                    work_done_progress_params: Default::default(),
 2197                })
 2198                .await
 2199                .into_response()?
 2200        } else {
 2201            None
 2202        };
 2203
 2204        if let Some(lsp_edits) = lsp_edits {
 2205            this.update(cx, |this, cx| {
 2206                this.as_local_mut().unwrap().edits_from_lsp(
 2207                    buffer,
 2208                    lsp_edits,
 2209                    language_server.server_id(),
 2210                    None,
 2211                    cx,
 2212                )
 2213            })?
 2214            .await
 2215        } else {
 2216            Ok(Vec::with_capacity(0))
 2217        }
 2218    }
 2219
 2220    async fn format_via_external_command(
 2221        buffer: &FormattableBuffer,
 2222        command: &str,
 2223        arguments: Option<&[String]>,
 2224        cx: &mut AsyncApp,
 2225    ) -> Result<Option<Diff>> {
 2226        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2227            let file = File::from_dyn(buffer.file())?;
 2228            let worktree = file.worktree.read(cx);
 2229            let mut worktree_path = worktree.abs_path().to_path_buf();
 2230            if worktree.root_entry()?.is_file() {
 2231                worktree_path.pop();
 2232            }
 2233            Some(worktree_path)
 2234        });
 2235
 2236        let mut child = util::command::new_smol_command(command);
 2237
 2238        if let Some(buffer_env) = buffer.env.as_ref() {
 2239            child.envs(buffer_env);
 2240        }
 2241
 2242        if let Some(working_dir_path) = working_dir_path {
 2243            child.current_dir(working_dir_path);
 2244        }
 2245
 2246        if let Some(arguments) = arguments {
 2247            child.args(arguments.iter().map(|arg| {
 2248                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2249                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2250                } else {
 2251                    arg.replace("{buffer_path}", "Untitled")
 2252                }
 2253            }));
 2254        }
 2255
 2256        let mut child = child
 2257            .stdin(smol::process::Stdio::piped())
 2258            .stdout(smol::process::Stdio::piped())
 2259            .stderr(smol::process::Stdio::piped())
 2260            .spawn()?;
 2261
 2262        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2263        let text = buffer
 2264            .handle
 2265            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2266        for chunk in text.chunks() {
 2267            stdin.write_all(chunk.as_bytes()).await?;
 2268        }
 2269        stdin.flush().await?;
 2270
 2271        let output = child.output().await?;
 2272        anyhow::ensure!(
 2273            output.status.success(),
 2274            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2275            output.status.code(),
 2276            String::from_utf8_lossy(&output.stdout),
 2277            String::from_utf8_lossy(&output.stderr),
 2278        );
 2279
 2280        let stdout = String::from_utf8(output.stdout)?;
 2281        Ok(Some(
 2282            buffer
 2283                .handle
 2284                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2285                .await,
 2286        ))
 2287    }
 2288
 2289    async fn try_resolve_code_action(
 2290        lang_server: &LanguageServer,
 2291        action: &mut CodeAction,
 2292    ) -> anyhow::Result<()> {
 2293        match &mut action.lsp_action {
 2294            LspAction::Action(lsp_action) => {
 2295                if !action.resolved
 2296                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2297                    && lsp_action.data.is_some()
 2298                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2299                {
 2300                    **lsp_action = lang_server
 2301                        .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2302                        .await
 2303                        .into_response()?;
 2304                }
 2305            }
 2306            LspAction::CodeLens(lens) => {
 2307                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2308                    *lens = lang_server
 2309                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2310                        .await
 2311                        .into_response()?;
 2312                }
 2313            }
 2314            LspAction::Command(_) => {}
 2315        }
 2316
 2317        action.resolved = true;
 2318        anyhow::Ok(())
 2319    }
 2320
 2321    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2322        let buffer = buffer_handle.read(cx);
 2323
 2324        let file = buffer.file().cloned();
 2325
 2326        let Some(file) = File::from_dyn(file.as_ref()) else {
 2327            return;
 2328        };
 2329        if !file.is_local() {
 2330            return;
 2331        }
 2332        let path = ProjectPath::from_file(file, cx);
 2333        let worktree_id = file.worktree_id(cx);
 2334        let language = buffer.language().cloned();
 2335
 2336        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2337            for (server_id, diagnostics) in
 2338                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2339            {
 2340                self.update_buffer_diagnostics(
 2341                    buffer_handle,
 2342                    server_id,
 2343                    None,
 2344                    None,
 2345                    None,
 2346                    Vec::new(),
 2347                    diagnostics,
 2348                    cx,
 2349                )
 2350                .log_err();
 2351            }
 2352        }
 2353        let Some(language) = language else {
 2354            return;
 2355        };
 2356        let Some(snapshot) = self
 2357            .worktree_store
 2358            .read(cx)
 2359            .worktree_for_id(worktree_id, cx)
 2360            .map(|worktree| worktree.read(cx).snapshot())
 2361        else {
 2362            return;
 2363        };
 2364        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2365
 2366        for server_id in
 2367            self.lsp_tree
 2368                .get(path, language.name(), language.manifest(), &delegate, cx)
 2369        {
 2370            let server = self
 2371                .language_servers
 2372                .get(&server_id)
 2373                .and_then(|server_state| {
 2374                    if let LanguageServerState::Running { server, .. } = server_state {
 2375                        Some(server.clone())
 2376                    } else {
 2377                        None
 2378                    }
 2379                });
 2380            let server = match server {
 2381                Some(server) => server,
 2382                None => continue,
 2383            };
 2384
 2385            buffer_handle.update(cx, |buffer, cx| {
 2386                buffer.set_completion_triggers(
 2387                    server.server_id(),
 2388                    server
 2389                        .capabilities()
 2390                        .completion_provider
 2391                        .as_ref()
 2392                        .and_then(|provider| {
 2393                            provider
 2394                                .trigger_characters
 2395                                .as_ref()
 2396                                .map(|characters| characters.iter().cloned().collect())
 2397                        })
 2398                        .unwrap_or_default(),
 2399                    cx,
 2400                );
 2401            });
 2402        }
 2403    }
 2404
 2405    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2406        buffer.update(cx, |buffer, cx| {
 2407            let Some(language) = buffer.language() else {
 2408                return;
 2409            };
 2410            let path = ProjectPath {
 2411                worktree_id: old_file.worktree_id(cx),
 2412                path: old_file.path.clone(),
 2413            };
 2414            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2415                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2416                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2417            }
 2418        });
 2419    }
 2420
 2421    fn update_buffer_diagnostics(
 2422        &mut self,
 2423        buffer: &Entity<Buffer>,
 2424        server_id: LanguageServerId,
 2425        registration_id: Option<Option<SharedString>>,
 2426        result_id: Option<SharedString>,
 2427        version: Option<i32>,
 2428        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2429        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2430        cx: &mut Context<LspStore>,
 2431    ) -> Result<()> {
 2432        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2433            Ordering::Equal
 2434                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2435                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2436                .then_with(|| a.severity.cmp(&b.severity))
 2437                .then_with(|| a.message.cmp(&b.message))
 2438        }
 2439
 2440        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2441        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2442        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2443
 2444        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2445            Ordering::Equal
 2446                .then_with(|| a.range.start.cmp(&b.range.start))
 2447                .then_with(|| b.range.end.cmp(&a.range.end))
 2448                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2449        });
 2450
 2451        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2452
 2453        let edits_since_save = std::cell::LazyCell::new(|| {
 2454            let saved_version = buffer.read(cx).saved_version();
 2455            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2456        });
 2457
 2458        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2459
 2460        for (new_diagnostic, entry) in diagnostics {
 2461            let start;
 2462            let end;
 2463            if new_diagnostic && entry.diagnostic.is_disk_based {
 2464                // Some diagnostics are based on files on disk instead of buffers'
 2465                // current contents. Adjust these diagnostics' ranges to reflect
 2466                // any unsaved edits.
 2467                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2468                // and were properly adjusted on reuse.
 2469                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2470                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2471            } else {
 2472                start = entry.range.start;
 2473                end = entry.range.end;
 2474            }
 2475
 2476            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2477                ..snapshot.clip_point_utf16(end, Bias::Right);
 2478
 2479            // Expand empty ranges by one codepoint
 2480            if range.start == range.end {
 2481                // This will be go to the next boundary when being clipped
 2482                range.end.column += 1;
 2483                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2484                if range.start == range.end && range.end.column > 0 {
 2485                    range.start.column -= 1;
 2486                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2487                }
 2488            }
 2489
 2490            sanitized_diagnostics.push(DiagnosticEntry {
 2491                range,
 2492                diagnostic: entry.diagnostic,
 2493            });
 2494        }
 2495        drop(edits_since_save);
 2496
 2497        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2498        buffer.update(cx, |buffer, cx| {
 2499            if let Some(registration_id) = registration_id {
 2500                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2501                    self.buffer_pull_diagnostics_result_ids
 2502                        .entry(server_id)
 2503                        .or_default()
 2504                        .entry(registration_id)
 2505                        .or_default()
 2506                        .insert(abs_path, result_id);
 2507                }
 2508            }
 2509
 2510            buffer.update_diagnostics(server_id, set, cx)
 2511        });
 2512
 2513        Ok(())
 2514    }
 2515
 2516    fn register_language_server_for_invisible_worktree(
 2517        &mut self,
 2518        worktree: &Entity<Worktree>,
 2519        language_server_id: LanguageServerId,
 2520        cx: &mut App,
 2521    ) {
 2522        let worktree = worktree.read(cx);
 2523        let worktree_id = worktree.id();
 2524        debug_assert!(!worktree.is_visible());
 2525        let Some(mut origin_seed) = self
 2526            .language_server_ids
 2527            .iter()
 2528            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2529        else {
 2530            return;
 2531        };
 2532        origin_seed.worktree_id = worktree_id;
 2533        self.language_server_ids
 2534            .entry(origin_seed)
 2535            .or_insert_with(|| UnifiedLanguageServer {
 2536                id: language_server_id,
 2537                project_roots: Default::default(),
 2538            });
 2539    }
 2540
 2541    fn register_buffer_with_language_servers(
 2542        &mut self,
 2543        buffer_handle: &Entity<Buffer>,
 2544        only_register_servers: HashSet<LanguageServerSelector>,
 2545        cx: &mut Context<LspStore>,
 2546    ) {
 2547        let buffer = buffer_handle.read(cx);
 2548        let buffer_id = buffer.remote_id();
 2549
 2550        let Some(file) = File::from_dyn(buffer.file()) else {
 2551            return;
 2552        };
 2553        if !file.is_local() {
 2554            return;
 2555        }
 2556
 2557        let abs_path = file.abs_path(cx);
 2558        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2559            return;
 2560        };
 2561        let initial_snapshot = buffer.text_snapshot();
 2562        let worktree_id = file.worktree_id(cx);
 2563
 2564        let Some(language) = buffer.language().cloned() else {
 2565            return;
 2566        };
 2567        let path: Arc<RelPath> = file
 2568            .path()
 2569            .parent()
 2570            .map(Arc::from)
 2571            .unwrap_or_else(|| file.path().clone());
 2572        let Some(worktree) = self
 2573            .worktree_store
 2574            .read(cx)
 2575            .worktree_for_id(worktree_id, cx)
 2576        else {
 2577            return;
 2578        };
 2579        let language_name = language.name();
 2580        let (reused, delegate, servers) = self
 2581            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2582            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2583            .unwrap_or_else(|| {
 2584                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2585                let delegate: Arc<dyn ManifestDelegate> =
 2586                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2587
 2588                let servers = self
 2589                    .lsp_tree
 2590                    .walk(
 2591                        ProjectPath { worktree_id, path },
 2592                        language.name(),
 2593                        language.manifest(),
 2594                        &delegate,
 2595                        cx,
 2596                    )
 2597                    .collect::<Vec<_>>();
 2598                (false, lsp_delegate, servers)
 2599            });
 2600        let servers_and_adapters = servers
 2601            .into_iter()
 2602            .filter_map(|server_node| {
 2603                if reused && server_node.server_id().is_none() {
 2604                    return None;
 2605                }
 2606                if !only_register_servers.is_empty() {
 2607                    if let Some(server_id) = server_node.server_id()
 2608                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2609                    {
 2610                        return None;
 2611                    }
 2612                    if let Some(name) = server_node.name()
 2613                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2614                    {
 2615                        return None;
 2616                    }
 2617                }
 2618
 2619                let server_id = server_node.server_id_or_init(|disposition| {
 2620                    let path = &disposition.path;
 2621
 2622                    {
 2623                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2624
 2625                        let server_id = self.get_or_insert_language_server(
 2626                            &worktree,
 2627                            delegate.clone(),
 2628                            disposition,
 2629                            &language_name,
 2630                            cx,
 2631                        );
 2632
 2633                        if let Some(state) = self.language_servers.get(&server_id)
 2634                            && let Ok(uri) = uri
 2635                        {
 2636                            state.add_workspace_folder(uri);
 2637                        };
 2638                        server_id
 2639                    }
 2640                })?;
 2641                let server_state = self.language_servers.get(&server_id)?;
 2642                if let LanguageServerState::Running {
 2643                    server, adapter, ..
 2644                } = server_state
 2645                {
 2646                    Some((server.clone(), adapter.clone()))
 2647                } else {
 2648                    None
 2649                }
 2650            })
 2651            .collect::<Vec<_>>();
 2652        for (server, adapter) in servers_and_adapters {
 2653            buffer_handle.update(cx, |buffer, cx| {
 2654                buffer.set_completion_triggers(
 2655                    server.server_id(),
 2656                    server
 2657                        .capabilities()
 2658                        .completion_provider
 2659                        .as_ref()
 2660                        .and_then(|provider| {
 2661                            provider
 2662                                .trigger_characters
 2663                                .as_ref()
 2664                                .map(|characters| characters.iter().cloned().collect())
 2665                        })
 2666                        .unwrap_or_default(),
 2667                    cx,
 2668                );
 2669            });
 2670
 2671            let snapshot = LspBufferSnapshot {
 2672                version: 0,
 2673                snapshot: initial_snapshot.clone(),
 2674            };
 2675
 2676            let mut registered = false;
 2677            self.buffer_snapshots
 2678                .entry(buffer_id)
 2679                .or_default()
 2680                .entry(server.server_id())
 2681                .or_insert_with(|| {
 2682                    registered = true;
 2683                    server.register_buffer(
 2684                        uri.clone(),
 2685                        adapter.language_id(&language.name()),
 2686                        0,
 2687                        initial_snapshot.text(),
 2688                    );
 2689
 2690                    vec![snapshot]
 2691                });
 2692
 2693            self.buffers_opened_in_servers
 2694                .entry(buffer_id)
 2695                .or_default()
 2696                .insert(server.server_id());
 2697            if registered {
 2698                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2699                    language_server_id: server.server_id(),
 2700                    name: None,
 2701                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2702                        proto::RegisteredForBuffer {
 2703                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2704                            buffer_id: buffer_id.to_proto(),
 2705                        },
 2706                    ),
 2707                });
 2708            }
 2709        }
 2710    }
 2711
 2712    fn reuse_existing_language_server<'lang_name>(
 2713        &self,
 2714        server_tree: &LanguageServerTree,
 2715        worktree: &Entity<Worktree>,
 2716        language_name: &'lang_name LanguageName,
 2717        cx: &mut App,
 2718    ) -> Option<(
 2719        Arc<LocalLspAdapterDelegate>,
 2720        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2721    )> {
 2722        if worktree.read(cx).is_visible() {
 2723            return None;
 2724        }
 2725
 2726        let worktree_store = self.worktree_store.read(cx);
 2727        let servers = server_tree
 2728            .instances
 2729            .iter()
 2730            .filter(|(worktree_id, _)| {
 2731                worktree_store
 2732                    .worktree_for_id(**worktree_id, cx)
 2733                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2734            })
 2735            .flat_map(|(worktree_id, servers)| {
 2736                servers
 2737                    .roots
 2738                    .iter()
 2739                    .flat_map(|(_, language_servers)| language_servers)
 2740                    .map(move |(_, (server_node, server_languages))| {
 2741                        (worktree_id, server_node, server_languages)
 2742                    })
 2743                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2744                    .map(|(worktree_id, server_node, _)| {
 2745                        (
 2746                            *worktree_id,
 2747                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2748                        )
 2749                    })
 2750            })
 2751            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2752                acc.entry(worktree_id)
 2753                    .or_insert_with(Vec::new)
 2754                    .push(server_node);
 2755                acc
 2756            })
 2757            .into_values()
 2758            .max_by_key(|servers| servers.len())?;
 2759
 2760        let worktree_id = worktree.read(cx).id();
 2761        let apply = move |tree: &mut LanguageServerTree| {
 2762            for server_node in &servers {
 2763                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2764            }
 2765            servers
 2766        };
 2767
 2768        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2769        Some((delegate, apply))
 2770    }
 2771
 2772    pub(crate) fn unregister_old_buffer_from_language_servers(
 2773        &mut self,
 2774        buffer: &Entity<Buffer>,
 2775        old_file: &File,
 2776        cx: &mut App,
 2777    ) {
 2778        let old_path = match old_file.as_local() {
 2779            Some(local) => local.abs_path(cx),
 2780            None => return,
 2781        };
 2782
 2783        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2784            debug_panic!("{old_path:?} is not parseable as an URI");
 2785            return;
 2786        };
 2787        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2788    }
 2789
 2790    pub(crate) fn unregister_buffer_from_language_servers(
 2791        &mut self,
 2792        buffer: &Entity<Buffer>,
 2793        file_url: &lsp::Uri,
 2794        cx: &mut App,
 2795    ) {
 2796        buffer.update(cx, |buffer, cx| {
 2797            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2798
 2799            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2800                if snapshots
 2801                    .as_mut()
 2802                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2803                {
 2804                    language_server.unregister_buffer(file_url.clone());
 2805                }
 2806            }
 2807        });
 2808    }
 2809
 2810    fn buffer_snapshot_for_lsp_version(
 2811        &mut self,
 2812        buffer: &Entity<Buffer>,
 2813        server_id: LanguageServerId,
 2814        version: Option<i32>,
 2815        cx: &App,
 2816    ) -> Result<TextBufferSnapshot> {
 2817        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2818
 2819        if let Some(version) = version {
 2820            let buffer_id = buffer.read(cx).remote_id();
 2821            let snapshots = if let Some(snapshots) = self
 2822                .buffer_snapshots
 2823                .get_mut(&buffer_id)
 2824                .and_then(|m| m.get_mut(&server_id))
 2825            {
 2826                snapshots
 2827            } else if version == 0 {
 2828                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2829                // We detect this case and treat it as if the version was `None`.
 2830                return Ok(buffer.read(cx).text_snapshot());
 2831            } else {
 2832                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2833            };
 2834
 2835            let found_snapshot = snapshots
 2836                    .binary_search_by_key(&version, |e| e.version)
 2837                    .map(|ix| snapshots[ix].snapshot.clone())
 2838                    .map_err(|_| {
 2839                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2840                    })?;
 2841
 2842            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2843            Ok(found_snapshot)
 2844        } else {
 2845            Ok((buffer.read(cx)).text_snapshot())
 2846        }
 2847    }
 2848
 2849    async fn get_server_code_actions_from_action_kinds(
 2850        lsp_store: &WeakEntity<LspStore>,
 2851        language_server_id: LanguageServerId,
 2852        code_action_kinds: Vec<lsp::CodeActionKind>,
 2853        buffer: &Entity<Buffer>,
 2854        cx: &mut AsyncApp,
 2855    ) -> Result<Vec<CodeAction>> {
 2856        let actions = lsp_store
 2857            .update(cx, move |this, cx| {
 2858                let request = GetCodeActions {
 2859                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 2860                    kinds: Some(code_action_kinds),
 2861                };
 2862                let server = LanguageServerToQuery::Other(language_server_id);
 2863                this.request_lsp(buffer.clone(), server, request, cx)
 2864            })?
 2865            .await?;
 2866        Ok(actions)
 2867    }
 2868
 2869    pub async fn execute_code_actions_on_server(
 2870        lsp_store: &WeakEntity<LspStore>,
 2871        language_server: &Arc<LanguageServer>,
 2872
 2873        actions: Vec<CodeAction>,
 2874        push_to_history: bool,
 2875        project_transaction: &mut ProjectTransaction,
 2876        cx: &mut AsyncApp,
 2877    ) -> anyhow::Result<()> {
 2878        for mut action in actions {
 2879            Self::try_resolve_code_action(language_server, &mut action)
 2880                .await
 2881                .context("resolving a formatting code action")?;
 2882
 2883            if let Some(edit) = action.lsp_action.edit() {
 2884                if edit.changes.is_none() && edit.document_changes.is_none() {
 2885                    continue;
 2886                }
 2887
 2888                let new = Self::deserialize_workspace_edit(
 2889                    lsp_store.upgrade().context("project dropped")?,
 2890                    edit.clone(),
 2891                    push_to_history,
 2892                    language_server.clone(),
 2893                    cx,
 2894                )
 2895                .await?;
 2896                project_transaction.0.extend(new.0);
 2897            }
 2898
 2899            if let Some(command) = action.lsp_action.command() {
 2900                let server_capabilities = language_server.capabilities();
 2901                let available_commands = server_capabilities
 2902                    .execute_command_provider
 2903                    .as_ref()
 2904                    .map(|options| options.commands.as_slice())
 2905                    .unwrap_or_default();
 2906                if available_commands.contains(&command.command) {
 2907                    lsp_store.update(cx, |lsp_store, _| {
 2908                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2909                            mode.last_workspace_edits_by_language_server
 2910                                .remove(&language_server.server_id());
 2911                        }
 2912                    })?;
 2913
 2914                    language_server
 2915                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2916                            command: command.command.clone(),
 2917                            arguments: command.arguments.clone().unwrap_or_default(),
 2918                            ..Default::default()
 2919                        })
 2920                        .await
 2921                        .into_response()
 2922                        .context("execute command")?;
 2923
 2924                    lsp_store.update(cx, |this, _| {
 2925                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2926                            project_transaction.0.extend(
 2927                                mode.last_workspace_edits_by_language_server
 2928                                    .remove(&language_server.server_id())
 2929                                    .unwrap_or_default()
 2930                                    .0,
 2931                            )
 2932                        }
 2933                    })?;
 2934                } else {
 2935                    log::warn!(
 2936                        "Cannot execute a command {} not listed in the language server capabilities",
 2937                        command.command
 2938                    )
 2939                }
 2940            }
 2941        }
 2942        Ok(())
 2943    }
 2944
 2945    pub async fn deserialize_text_edits(
 2946        this: Entity<LspStore>,
 2947        buffer_to_edit: Entity<Buffer>,
 2948        edits: Vec<lsp::TextEdit>,
 2949        push_to_history: bool,
 2950        _: Arc<CachedLspAdapter>,
 2951        language_server: Arc<LanguageServer>,
 2952        cx: &mut AsyncApp,
 2953    ) -> Result<Option<Transaction>> {
 2954        let edits = this
 2955            .update(cx, |this, cx| {
 2956                this.as_local_mut().unwrap().edits_from_lsp(
 2957                    &buffer_to_edit,
 2958                    edits,
 2959                    language_server.server_id(),
 2960                    None,
 2961                    cx,
 2962                )
 2963            })
 2964            .await?;
 2965
 2966        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2967            buffer.finalize_last_transaction();
 2968            buffer.start_transaction();
 2969            for (range, text) in edits {
 2970                buffer.edit([(range, text)], None, cx);
 2971            }
 2972
 2973            if buffer.end_transaction(cx).is_some() {
 2974                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2975                if !push_to_history {
 2976                    buffer.forget_transaction(transaction.id);
 2977                }
 2978                Some(transaction)
 2979            } else {
 2980                None
 2981            }
 2982        });
 2983
 2984        Ok(transaction)
 2985    }
 2986
 2987    #[allow(clippy::type_complexity)]
 2988    pub(crate) fn edits_from_lsp(
 2989        &mut self,
 2990        buffer: &Entity<Buffer>,
 2991        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2992        server_id: LanguageServerId,
 2993        version: Option<i32>,
 2994        cx: &mut Context<LspStore>,
 2995    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2996        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2997        cx.background_spawn(async move {
 2998            let snapshot = snapshot?;
 2999            let mut lsp_edits = lsp_edits
 3000                .into_iter()
 3001                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3002                .collect::<Vec<_>>();
 3003
 3004            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 3005
 3006            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3007            let mut edits = Vec::new();
 3008            while let Some((range, mut new_text)) = lsp_edits.next() {
 3009                // Clip invalid ranges provided by the language server.
 3010                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3011                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3012
 3013                // Combine any LSP edits that are adjacent.
 3014                //
 3015                // Also, combine LSP edits that are separated from each other by only
 3016                // a newline. This is important because for some code actions,
 3017                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3018                // are separated by unchanged newline characters.
 3019                //
 3020                // In order for the diffing logic below to work properly, any edits that
 3021                // cancel each other out must be combined into one.
 3022                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3023                    if next_range.start.0 > range.end {
 3024                        if next_range.start.0.row > range.end.row + 1
 3025                            || next_range.start.0.column > 0
 3026                            || snapshot.clip_point_utf16(
 3027                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3028                                Bias::Left,
 3029                            ) > range.end
 3030                        {
 3031                            break;
 3032                        }
 3033                        new_text.push('\n');
 3034                    }
 3035                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3036                    new_text.push_str(next_text);
 3037                    lsp_edits.next();
 3038                }
 3039
 3040                // For multiline edits, perform a diff of the old and new text so that
 3041                // we can identify the changes more precisely, preserving the locations
 3042                // of any anchors positioned in the unchanged regions.
 3043                if range.end.row > range.start.row {
 3044                    let offset = range.start.to_offset(&snapshot);
 3045                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3046                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3047                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3048                        (
 3049                            snapshot.anchor_after(offset + range.start)
 3050                                ..snapshot.anchor_before(offset + range.end),
 3051                            replacement,
 3052                        )
 3053                    }));
 3054                } else if range.end == range.start {
 3055                    let anchor = snapshot.anchor_after(range.start);
 3056                    edits.push((anchor..anchor, new_text.into()));
 3057                } else {
 3058                    let edit_start = snapshot.anchor_after(range.start);
 3059                    let edit_end = snapshot.anchor_before(range.end);
 3060                    edits.push((edit_start..edit_end, new_text.into()));
 3061                }
 3062            }
 3063
 3064            Ok(edits)
 3065        })
 3066    }
 3067
 3068    pub(crate) async fn deserialize_workspace_edit(
 3069        this: Entity<LspStore>,
 3070        edit: lsp::WorkspaceEdit,
 3071        push_to_history: bool,
 3072        language_server: Arc<LanguageServer>,
 3073        cx: &mut AsyncApp,
 3074    ) -> Result<ProjectTransaction> {
 3075        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3076
 3077        let mut operations = Vec::new();
 3078        if let Some(document_changes) = edit.document_changes {
 3079            match document_changes {
 3080                lsp::DocumentChanges::Edits(edits) => {
 3081                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3082                }
 3083                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3084            }
 3085        } else if let Some(changes) = edit.changes {
 3086            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3087                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3088                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3089                        uri,
 3090                        version: None,
 3091                    },
 3092                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3093                })
 3094            }));
 3095        }
 3096
 3097        let mut project_transaction = ProjectTransaction::default();
 3098        for operation in operations {
 3099            match operation {
 3100                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3101                    let abs_path = op
 3102                        .uri
 3103                        .to_file_path()
 3104                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3105
 3106                    if let Some(parent_path) = abs_path.parent() {
 3107                        fs.create_dir(parent_path).await?;
 3108                    }
 3109                    if abs_path.ends_with("/") {
 3110                        fs.create_dir(&abs_path).await?;
 3111                    } else {
 3112                        fs.create_file(
 3113                            &abs_path,
 3114                            op.options
 3115                                .map(|options| fs::CreateOptions {
 3116                                    overwrite: options.overwrite.unwrap_or(false),
 3117                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3118                                })
 3119                                .unwrap_or_default(),
 3120                        )
 3121                        .await?;
 3122                    }
 3123                }
 3124
 3125                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3126                    let source_abs_path = op
 3127                        .old_uri
 3128                        .to_file_path()
 3129                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3130                    let target_abs_path = op
 3131                        .new_uri
 3132                        .to_file_path()
 3133                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3134
 3135                    let options = fs::RenameOptions {
 3136                        overwrite: op
 3137                            .options
 3138                            .as_ref()
 3139                            .and_then(|options| options.overwrite)
 3140                            .unwrap_or(false),
 3141                        ignore_if_exists: op
 3142                            .options
 3143                            .as_ref()
 3144                            .and_then(|options| options.ignore_if_exists)
 3145                            .unwrap_or(false),
 3146                        create_parents: true,
 3147                    };
 3148
 3149                    fs.rename(&source_abs_path, &target_abs_path, options)
 3150                        .await?;
 3151                }
 3152
 3153                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3154                    let abs_path = op
 3155                        .uri
 3156                        .to_file_path()
 3157                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3158                    let options = op
 3159                        .options
 3160                        .map(|options| fs::RemoveOptions {
 3161                            recursive: options.recursive.unwrap_or(false),
 3162                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3163                        })
 3164                        .unwrap_or_default();
 3165                    if abs_path.ends_with("/") {
 3166                        fs.remove_dir(&abs_path, options).await?;
 3167                    } else {
 3168                        fs.remove_file(&abs_path, options).await?;
 3169                    }
 3170                }
 3171
 3172                lsp::DocumentChangeOperation::Edit(op) => {
 3173                    let buffer_to_edit = this
 3174                        .update(cx, |this, cx| {
 3175                            this.open_local_buffer_via_lsp(
 3176                                op.text_document.uri.clone(),
 3177                                language_server.server_id(),
 3178                                cx,
 3179                            )
 3180                        })
 3181                        .await?;
 3182
 3183                    let edits = this
 3184                        .update(cx, |this, cx| {
 3185                            let path = buffer_to_edit.read(cx).project_path(cx);
 3186                            let active_entry = this.active_entry;
 3187                            let is_active_entry = path.is_some_and(|project_path| {
 3188                                this.worktree_store
 3189                                    .read(cx)
 3190                                    .entry_for_path(&project_path, cx)
 3191                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3192                            });
 3193                            let local = this.as_local_mut().unwrap();
 3194
 3195                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3196                            for edit in op.edits {
 3197                                match edit {
 3198                                    Edit::Plain(edit) => {
 3199                                        if !edits.contains(&edit) {
 3200                                            edits.push(edit)
 3201                                        }
 3202                                    }
 3203                                    Edit::Annotated(edit) => {
 3204                                        if !edits.contains(&edit.text_edit) {
 3205                                            edits.push(edit.text_edit)
 3206                                        }
 3207                                    }
 3208                                    Edit::Snippet(edit) => {
 3209                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3210                                        else {
 3211                                            continue;
 3212                                        };
 3213
 3214                                        if is_active_entry {
 3215                                            snippet_edits.push((edit.range, snippet));
 3216                                        } else {
 3217                                            // Since this buffer is not focused, apply a normal edit.
 3218                                            let new_edit = TextEdit {
 3219                                                range: edit.range,
 3220                                                new_text: snippet.text,
 3221                                            };
 3222                                            if !edits.contains(&new_edit) {
 3223                                                edits.push(new_edit);
 3224                                            }
 3225                                        }
 3226                                    }
 3227                                }
 3228                            }
 3229                            if !snippet_edits.is_empty() {
 3230                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3231                                let version = if let Some(buffer_version) = op.text_document.version
 3232                                {
 3233                                    local
 3234                                        .buffer_snapshot_for_lsp_version(
 3235                                            &buffer_to_edit,
 3236                                            language_server.server_id(),
 3237                                            Some(buffer_version),
 3238                                            cx,
 3239                                        )
 3240                                        .ok()
 3241                                        .map(|snapshot| snapshot.version)
 3242                                } else {
 3243                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3244                                };
 3245
 3246                                let most_recent_edit =
 3247                                    version.and_then(|version| version.most_recent());
 3248                                // Check if the edit that triggered that edit has been made by this participant.
 3249
 3250                                if let Some(most_recent_edit) = most_recent_edit {
 3251                                    cx.emit(LspStoreEvent::SnippetEdit {
 3252                                        buffer_id,
 3253                                        edits: snippet_edits,
 3254                                        most_recent_edit,
 3255                                    });
 3256                                }
 3257                            }
 3258
 3259                            local.edits_from_lsp(
 3260                                &buffer_to_edit,
 3261                                edits,
 3262                                language_server.server_id(),
 3263                                op.text_document.version,
 3264                                cx,
 3265                            )
 3266                        })
 3267                        .await?;
 3268
 3269                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3270                        buffer.finalize_last_transaction();
 3271                        buffer.start_transaction();
 3272                        for (range, text) in edits {
 3273                            buffer.edit([(range, text)], None, cx);
 3274                        }
 3275
 3276                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3277                            if push_to_history {
 3278                                buffer.finalize_last_transaction();
 3279                                buffer.get_transaction(transaction_id).cloned()
 3280                            } else {
 3281                                buffer.forget_transaction(transaction_id)
 3282                            }
 3283                        })
 3284                    });
 3285                    if let Some(transaction) = transaction {
 3286                        project_transaction.0.insert(buffer_to_edit, transaction);
 3287                    }
 3288                }
 3289            }
 3290        }
 3291
 3292        Ok(project_transaction)
 3293    }
 3294
 3295    async fn on_lsp_workspace_edit(
 3296        this: WeakEntity<LspStore>,
 3297        params: lsp::ApplyWorkspaceEditParams,
 3298        server_id: LanguageServerId,
 3299        cx: &mut AsyncApp,
 3300    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3301        let this = this.upgrade().context("project project closed")?;
 3302        let language_server = this
 3303            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3304            .context("language server not found")?;
 3305        let transaction = Self::deserialize_workspace_edit(
 3306            this.clone(),
 3307            params.edit,
 3308            true,
 3309            language_server.clone(),
 3310            cx,
 3311        )
 3312        .await
 3313        .log_err();
 3314        this.update(cx, |this, cx| {
 3315            if let Some(transaction) = transaction {
 3316                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3317
 3318                this.as_local_mut()
 3319                    .unwrap()
 3320                    .last_workspace_edits_by_language_server
 3321                    .insert(server_id, transaction);
 3322            }
 3323        });
 3324        Ok(lsp::ApplyWorkspaceEditResponse {
 3325            applied: true,
 3326            failed_change: None,
 3327            failure_reason: None,
 3328        })
 3329    }
 3330
 3331    fn remove_worktree(
 3332        &mut self,
 3333        id_to_remove: WorktreeId,
 3334        cx: &mut Context<LspStore>,
 3335    ) -> Vec<LanguageServerId> {
 3336        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3337        self.diagnostics.remove(&id_to_remove);
 3338        self.prettier_store.update(cx, |prettier_store, cx| {
 3339            prettier_store.remove_worktree(id_to_remove, cx);
 3340        });
 3341
 3342        let mut servers_to_remove = BTreeSet::default();
 3343        let mut servers_to_preserve = HashSet::default();
 3344        for (seed, state) in &self.language_server_ids {
 3345            if seed.worktree_id == id_to_remove {
 3346                servers_to_remove.insert(state.id);
 3347            } else {
 3348                servers_to_preserve.insert(state.id);
 3349            }
 3350        }
 3351        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3352        self.language_server_ids
 3353            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3354        for server_id_to_remove in &servers_to_remove {
 3355            self.language_server_watched_paths
 3356                .remove(server_id_to_remove);
 3357            self.language_server_paths_watched_for_rename
 3358                .remove(server_id_to_remove);
 3359            self.last_workspace_edits_by_language_server
 3360                .remove(server_id_to_remove);
 3361            self.language_servers.remove(server_id_to_remove);
 3362            self.buffer_pull_diagnostics_result_ids
 3363                .remove(server_id_to_remove);
 3364            self.workspace_pull_diagnostics_result_ids
 3365                .remove(server_id_to_remove);
 3366            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3367                buffer_servers.remove(server_id_to_remove);
 3368            }
 3369            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3370        }
 3371        servers_to_remove.into_iter().collect()
 3372    }
 3373
 3374    fn rebuild_watched_paths_inner<'a>(
 3375        &'a self,
 3376        language_server_id: LanguageServerId,
 3377        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3378        cx: &mut Context<LspStore>,
 3379    ) -> LanguageServerWatchedPathsBuilder {
 3380        let worktrees = self
 3381            .worktree_store
 3382            .read(cx)
 3383            .worktrees()
 3384            .filter_map(|worktree| {
 3385                self.language_servers_for_worktree(worktree.read(cx).id())
 3386                    .find(|server| server.server_id() == language_server_id)
 3387                    .map(|_| worktree)
 3388            })
 3389            .collect::<Vec<_>>();
 3390
 3391        let mut worktree_globs = HashMap::default();
 3392        let mut abs_globs = HashMap::default();
 3393        log::trace!(
 3394            "Processing new watcher paths for language server with id {}",
 3395            language_server_id
 3396        );
 3397
 3398        for watcher in watchers {
 3399            if let Some((worktree, literal_prefix, pattern)) =
 3400                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3401            {
 3402                worktree.update(cx, |worktree, _| {
 3403                    if let Some((tree, glob)) =
 3404                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3405                    {
 3406                        tree.add_path_prefix_to_scan(literal_prefix);
 3407                        worktree_globs
 3408                            .entry(tree.id())
 3409                            .or_insert_with(GlobSetBuilder::new)
 3410                            .add(glob);
 3411                    }
 3412                });
 3413            } else {
 3414                let (path, pattern) = match &watcher.glob_pattern {
 3415                    lsp::GlobPattern::String(s) => {
 3416                        let watcher_path = SanitizedPath::new(s);
 3417                        let path = glob_literal_prefix(watcher_path.as_path());
 3418                        let pattern = watcher_path
 3419                            .as_path()
 3420                            .strip_prefix(&path)
 3421                            .map(|p| p.to_string_lossy().into_owned())
 3422                            .unwrap_or_else(|e| {
 3423                                debug_panic!(
 3424                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3425                                    s,
 3426                                    path.display(),
 3427                                    e
 3428                                );
 3429                                watcher_path.as_path().to_string_lossy().into_owned()
 3430                            });
 3431                        (path, pattern)
 3432                    }
 3433                    lsp::GlobPattern::Relative(rp) => {
 3434                        let Ok(mut base_uri) = match &rp.base_uri {
 3435                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3436                            lsp::OneOf::Right(base_uri) => base_uri,
 3437                        }
 3438                        .to_file_path() else {
 3439                            continue;
 3440                        };
 3441
 3442                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3443                        let pattern = Path::new(&rp.pattern)
 3444                            .strip_prefix(&path)
 3445                            .map(|p| p.to_string_lossy().into_owned())
 3446                            .unwrap_or_else(|e| {
 3447                                debug_panic!(
 3448                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3449                                    rp.pattern,
 3450                                    path.display(),
 3451                                    e
 3452                                );
 3453                                rp.pattern.clone()
 3454                            });
 3455                        base_uri.push(path);
 3456                        (base_uri, pattern)
 3457                    }
 3458                };
 3459
 3460                if let Some(glob) = Glob::new(&pattern).log_err() {
 3461                    if !path
 3462                        .components()
 3463                        .any(|c| matches!(c, path::Component::Normal(_)))
 3464                    {
 3465                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3466                        // rather than adding a new watcher for `/`.
 3467                        for worktree in &worktrees {
 3468                            worktree_globs
 3469                                .entry(worktree.read(cx).id())
 3470                                .or_insert_with(GlobSetBuilder::new)
 3471                                .add(glob.clone());
 3472                        }
 3473                    } else {
 3474                        abs_globs
 3475                            .entry(path.into())
 3476                            .or_insert_with(GlobSetBuilder::new)
 3477                            .add(glob);
 3478                    }
 3479                }
 3480            }
 3481        }
 3482
 3483        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3484        for (worktree_id, builder) in worktree_globs {
 3485            if let Ok(globset) = builder.build() {
 3486                watch_builder.watch_worktree(worktree_id, globset);
 3487            }
 3488        }
 3489        for (abs_path, builder) in abs_globs {
 3490            if let Ok(globset) = builder.build() {
 3491                watch_builder.watch_abs_path(abs_path, globset);
 3492            }
 3493        }
 3494        watch_builder
 3495    }
 3496
 3497    fn worktree_and_path_for_file_watcher(
 3498        worktrees: &[Entity<Worktree>],
 3499        watcher: &FileSystemWatcher,
 3500        cx: &App,
 3501    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3502        worktrees.iter().find_map(|worktree| {
 3503            let tree = worktree.read(cx);
 3504            let worktree_root_path = tree.abs_path();
 3505            let path_style = tree.path_style();
 3506            match &watcher.glob_pattern {
 3507                lsp::GlobPattern::String(s) => {
 3508                    let watcher_path = SanitizedPath::new(s);
 3509                    let relative = watcher_path
 3510                        .as_path()
 3511                        .strip_prefix(&worktree_root_path)
 3512                        .ok()?;
 3513                    let literal_prefix = glob_literal_prefix(relative);
 3514                    Some((
 3515                        worktree.clone(),
 3516                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3517                        relative.to_string_lossy().into_owned(),
 3518                    ))
 3519                }
 3520                lsp::GlobPattern::Relative(rp) => {
 3521                    let base_uri = match &rp.base_uri {
 3522                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3523                        lsp::OneOf::Right(base_uri) => base_uri,
 3524                    }
 3525                    .to_file_path()
 3526                    .ok()?;
 3527                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3528                    let mut literal_prefix = relative.to_owned();
 3529                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3530                    Some((
 3531                        worktree.clone(),
 3532                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3533                        rp.pattern.clone(),
 3534                    ))
 3535                }
 3536            }
 3537        })
 3538    }
 3539
 3540    fn rebuild_watched_paths(
 3541        &mut self,
 3542        language_server_id: LanguageServerId,
 3543        cx: &mut Context<LspStore>,
 3544    ) {
 3545        let Some(registrations) = self
 3546            .language_server_dynamic_registrations
 3547            .get(&language_server_id)
 3548        else {
 3549            return;
 3550        };
 3551
 3552        let watch_builder = self.rebuild_watched_paths_inner(
 3553            language_server_id,
 3554            registrations.did_change_watched_files.values().flatten(),
 3555            cx,
 3556        );
 3557        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3558        self.language_server_watched_paths
 3559            .insert(language_server_id, watcher);
 3560
 3561        cx.notify();
 3562    }
 3563
 3564    fn on_lsp_did_change_watched_files(
 3565        &mut self,
 3566        language_server_id: LanguageServerId,
 3567        registration_id: &str,
 3568        params: DidChangeWatchedFilesRegistrationOptions,
 3569        cx: &mut Context<LspStore>,
 3570    ) {
 3571        let registrations = self
 3572            .language_server_dynamic_registrations
 3573            .entry(language_server_id)
 3574            .or_default();
 3575
 3576        registrations
 3577            .did_change_watched_files
 3578            .insert(registration_id.to_string(), params.watchers);
 3579
 3580        self.rebuild_watched_paths(language_server_id, cx);
 3581    }
 3582
 3583    fn on_lsp_unregister_did_change_watched_files(
 3584        &mut self,
 3585        language_server_id: LanguageServerId,
 3586        registration_id: &str,
 3587        cx: &mut Context<LspStore>,
 3588    ) {
 3589        let registrations = self
 3590            .language_server_dynamic_registrations
 3591            .entry(language_server_id)
 3592            .or_default();
 3593
 3594        if registrations
 3595            .did_change_watched_files
 3596            .remove(registration_id)
 3597            .is_some()
 3598        {
 3599            log::info!(
 3600                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3601                language_server_id,
 3602                registration_id
 3603            );
 3604        } else {
 3605            log::warn!(
 3606                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3607                language_server_id,
 3608                registration_id
 3609            );
 3610        }
 3611
 3612        self.rebuild_watched_paths(language_server_id, cx);
 3613    }
 3614
 3615    async fn initialization_options_for_adapter(
 3616        adapter: Arc<dyn LspAdapter>,
 3617        delegate: &Arc<dyn LspAdapterDelegate>,
 3618    ) -> Result<Option<serde_json::Value>> {
 3619        let Some(mut initialization_config) =
 3620            adapter.clone().initialization_options(delegate).await?
 3621        else {
 3622            return Ok(None);
 3623        };
 3624
 3625        for other_adapter in delegate.registered_lsp_adapters() {
 3626            if other_adapter.name() == adapter.name() {
 3627                continue;
 3628            }
 3629            if let Ok(Some(target_config)) = other_adapter
 3630                .clone()
 3631                .additional_initialization_options(adapter.name(), delegate)
 3632                .await
 3633            {
 3634                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3635            }
 3636        }
 3637
 3638        Ok(Some(initialization_config))
 3639    }
 3640
 3641    async fn workspace_configuration_for_adapter(
 3642        adapter: Arc<dyn LspAdapter>,
 3643        delegate: &Arc<dyn LspAdapterDelegate>,
 3644        toolchain: Option<Toolchain>,
 3645        requested_uri: Option<Uri>,
 3646        cx: &mut AsyncApp,
 3647    ) -> Result<serde_json::Value> {
 3648        let mut workspace_config = adapter
 3649            .clone()
 3650            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3651            .await?;
 3652
 3653        for other_adapter in delegate.registered_lsp_adapters() {
 3654            if other_adapter.name() == adapter.name() {
 3655                continue;
 3656            }
 3657            if let Ok(Some(target_config)) = other_adapter
 3658                .clone()
 3659                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3660                .await
 3661            {
 3662                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3663            }
 3664        }
 3665
 3666        Ok(workspace_config)
 3667    }
 3668
 3669    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3670        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3671            Some(server.clone())
 3672        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3673            Some(Arc::clone(server))
 3674        } else {
 3675            None
 3676        }
 3677    }
 3678}
 3679
 3680fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3681    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3682        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3683            language_server_id: server.server_id(),
 3684            name: Some(server.name()),
 3685            message: proto::update_language_server::Variant::MetadataUpdated(
 3686                proto::ServerMetadataUpdated {
 3687                    capabilities: Some(capabilities),
 3688                    binary: Some(proto::LanguageServerBinaryInfo {
 3689                        path: server.binary().path.to_string_lossy().into_owned(),
 3690                        arguments: server
 3691                            .binary()
 3692                            .arguments
 3693                            .iter()
 3694                            .map(|arg| arg.to_string_lossy().into_owned())
 3695                            .collect(),
 3696                    }),
 3697                    configuration: serde_json::to_string(server.configuration()).ok(),
 3698                    workspace_folders: server
 3699                        .workspace_folders()
 3700                        .iter()
 3701                        .map(|uri| uri.to_string())
 3702                        .collect(),
 3703                },
 3704            ),
 3705        });
 3706    }
 3707}
 3708
 3709#[derive(Debug)]
 3710pub struct FormattableBuffer {
 3711    handle: Entity<Buffer>,
 3712    abs_path: Option<PathBuf>,
 3713    env: Option<HashMap<String, String>>,
 3714    ranges: Option<Vec<Range<Anchor>>>,
 3715}
 3716
 3717pub struct RemoteLspStore {
 3718    upstream_client: Option<AnyProtoClient>,
 3719    upstream_project_id: u64,
 3720}
 3721
 3722pub(crate) enum LspStoreMode {
 3723    Local(LocalLspStore),   // ssh host and collab host
 3724    Remote(RemoteLspStore), // collab guest
 3725}
 3726
 3727impl LspStoreMode {
 3728    fn is_local(&self) -> bool {
 3729        matches!(self, LspStoreMode::Local(_))
 3730    }
 3731}
 3732
 3733pub struct LspStore {
 3734    mode: LspStoreMode,
 3735    last_formatting_failure: Option<String>,
 3736    downstream_client: Option<(AnyProtoClient, u64)>,
 3737    nonce: u128,
 3738    buffer_store: Entity<BufferStore>,
 3739    worktree_store: Entity<WorktreeStore>,
 3740    pub languages: Arc<LanguageRegistry>,
 3741    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3742    active_entry: Option<ProjectEntryId>,
 3743    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3744    _maintain_buffer_languages: Task<()>,
 3745    diagnostic_summaries:
 3746        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3747    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3748    lsp_data: HashMap<BufferId, BufferLspData>,
 3749    next_hint_id: Arc<AtomicUsize>,
 3750}
 3751
 3752#[derive(Debug)]
 3753pub struct BufferLspData {
 3754    buffer_version: Global,
 3755    document_colors: Option<DocumentColorData>,
 3756    code_lens: Option<CodeLensData>,
 3757    inlay_hints: BufferInlayHints,
 3758    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3759    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3760}
 3761
 3762#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3763struct LspKey {
 3764    request_type: TypeId,
 3765    server_queried: Option<LanguageServerId>,
 3766}
 3767
 3768impl BufferLspData {
 3769    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3770        Self {
 3771            buffer_version: buffer.read(cx).version(),
 3772            document_colors: None,
 3773            code_lens: None,
 3774            inlay_hints: BufferInlayHints::new(buffer, cx),
 3775            lsp_requests: HashMap::default(),
 3776            chunk_lsp_requests: HashMap::default(),
 3777        }
 3778    }
 3779
 3780    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3781        if let Some(document_colors) = &mut self.document_colors {
 3782            document_colors.colors.remove(&for_server);
 3783            document_colors.cache_version += 1;
 3784        }
 3785
 3786        if let Some(code_lens) = &mut self.code_lens {
 3787            code_lens.lens.remove(&for_server);
 3788        }
 3789
 3790        self.inlay_hints.remove_server_data(for_server);
 3791    }
 3792
 3793    #[cfg(any(test, feature = "test-support"))]
 3794    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3795        &self.inlay_hints
 3796    }
 3797}
 3798
 3799#[derive(Debug, Default, Clone)]
 3800pub struct DocumentColors {
 3801    pub colors: HashSet<DocumentColor>,
 3802    pub cache_version: Option<usize>,
 3803}
 3804
 3805type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3806type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3807
 3808#[derive(Debug, Default)]
 3809struct DocumentColorData {
 3810    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3811    cache_version: usize,
 3812    colors_update: Option<(Global, DocumentColorTask)>,
 3813}
 3814
 3815#[derive(Debug, Default)]
 3816struct CodeLensData {
 3817    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3818    update: Option<(Global, CodeLensTask)>,
 3819}
 3820
 3821#[derive(Debug)]
 3822pub enum LspStoreEvent {
 3823    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3824    LanguageServerRemoved(LanguageServerId),
 3825    LanguageServerUpdate {
 3826        language_server_id: LanguageServerId,
 3827        name: Option<LanguageServerName>,
 3828        message: proto::update_language_server::Variant,
 3829    },
 3830    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3831    LanguageServerPrompt(LanguageServerPromptRequest),
 3832    LanguageDetected {
 3833        buffer: Entity<Buffer>,
 3834        new_language: Option<Arc<Language>>,
 3835    },
 3836    Notification(String),
 3837    RefreshInlayHints {
 3838        server_id: LanguageServerId,
 3839        request_id: Option<usize>,
 3840    },
 3841    RefreshCodeLens,
 3842    DiagnosticsUpdated {
 3843        server_id: LanguageServerId,
 3844        paths: Vec<ProjectPath>,
 3845    },
 3846    DiskBasedDiagnosticsStarted {
 3847        language_server_id: LanguageServerId,
 3848    },
 3849    DiskBasedDiagnosticsFinished {
 3850        language_server_id: LanguageServerId,
 3851    },
 3852    SnippetEdit {
 3853        buffer_id: BufferId,
 3854        edits: Vec<(lsp::Range, Snippet)>,
 3855        most_recent_edit: clock::Lamport,
 3856    },
 3857    WorkspaceEditApplied(ProjectTransaction),
 3858}
 3859
 3860#[derive(Clone, Debug, Serialize)]
 3861pub struct LanguageServerStatus {
 3862    pub name: LanguageServerName,
 3863    pub server_version: Option<SharedString>,
 3864    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3865    pub has_pending_diagnostic_updates: bool,
 3866    pub progress_tokens: HashSet<ProgressToken>,
 3867    pub worktree: Option<WorktreeId>,
 3868    pub binary: Option<LanguageServerBinary>,
 3869    pub configuration: Option<Value>,
 3870    pub workspace_folders: BTreeSet<Uri>,
 3871}
 3872
 3873#[derive(Clone, Debug)]
 3874struct CoreSymbol {
 3875    pub language_server_name: LanguageServerName,
 3876    pub source_worktree_id: WorktreeId,
 3877    pub source_language_server_id: LanguageServerId,
 3878    pub path: SymbolLocation,
 3879    pub name: String,
 3880    pub kind: lsp::SymbolKind,
 3881    pub range: Range<Unclipped<PointUtf16>>,
 3882}
 3883
 3884#[derive(Clone, Debug, PartialEq, Eq)]
 3885pub enum SymbolLocation {
 3886    InProject(ProjectPath),
 3887    OutsideProject {
 3888        abs_path: Arc<Path>,
 3889        signature: [u8; 32],
 3890    },
 3891}
 3892
 3893impl SymbolLocation {
 3894    fn file_name(&self) -> Option<&str> {
 3895        match self {
 3896            Self::InProject(path) => path.path.file_name(),
 3897            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3898        }
 3899    }
 3900}
 3901
 3902impl LspStore {
 3903    pub fn init(client: &AnyProtoClient) {
 3904        client.add_entity_request_handler(Self::handle_lsp_query);
 3905        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3906        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3907        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3908        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3909        client.add_entity_message_handler(Self::handle_start_language_server);
 3910        client.add_entity_message_handler(Self::handle_update_language_server);
 3911        client.add_entity_message_handler(Self::handle_language_server_log);
 3912        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3913        client.add_entity_request_handler(Self::handle_format_buffers);
 3914        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3915        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3916        client.add_entity_request_handler(Self::handle_apply_code_action);
 3917        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3918        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3919        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3920        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3921        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3922        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3923        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3924        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3925        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3926        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3927        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3928        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3929        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3930        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3931        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3932        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3933        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3934
 3935        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3936        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3937        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3938        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3939        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3940        client.add_entity_request_handler(
 3941            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3942        );
 3943        client.add_entity_request_handler(
 3944            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3945        );
 3946        client.add_entity_request_handler(
 3947            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3948        );
 3949    }
 3950
 3951    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3952        match &self.mode {
 3953            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3954            _ => None,
 3955        }
 3956    }
 3957
 3958    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3959        match &self.mode {
 3960            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3961            _ => None,
 3962        }
 3963    }
 3964
 3965    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3966        match &mut self.mode {
 3967            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3968            _ => None,
 3969        }
 3970    }
 3971
 3972    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3973        match &self.mode {
 3974            LspStoreMode::Remote(RemoteLspStore {
 3975                upstream_client: Some(upstream_client),
 3976                upstream_project_id,
 3977                ..
 3978            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3979
 3980            LspStoreMode::Remote(RemoteLspStore {
 3981                upstream_client: None,
 3982                ..
 3983            }) => None,
 3984            LspStoreMode::Local(_) => None,
 3985        }
 3986    }
 3987
 3988    pub fn new_local(
 3989        buffer_store: Entity<BufferStore>,
 3990        worktree_store: Entity<WorktreeStore>,
 3991        prettier_store: Entity<PrettierStore>,
 3992        toolchain_store: Entity<LocalToolchainStore>,
 3993        environment: Entity<ProjectEnvironment>,
 3994        manifest_tree: Entity<ManifestTree>,
 3995        languages: Arc<LanguageRegistry>,
 3996        http_client: Arc<dyn HttpClient>,
 3997        fs: Arc<dyn Fs>,
 3998        cx: &mut Context<Self>,
 3999    ) -> Self {
 4000        let yarn = YarnPathStore::new(fs.clone(), cx);
 4001        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4002            .detach();
 4003        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4004            .detach();
 4005        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4006            .detach();
 4007        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4008            .detach();
 4009        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4010            .detach();
 4011        subscribe_to_binary_statuses(&languages, cx).detach();
 4012
 4013        let _maintain_workspace_config = {
 4014            let (sender, receiver) = watch::channel();
 4015            (Self::maintain_workspace_config(receiver, cx), sender)
 4016        };
 4017
 4018        Self {
 4019            mode: LspStoreMode::Local(LocalLspStore {
 4020                weak: cx.weak_entity(),
 4021                worktree_store: worktree_store.clone(),
 4022
 4023                supplementary_language_servers: Default::default(),
 4024                languages: languages.clone(),
 4025                language_server_ids: Default::default(),
 4026                language_servers: Default::default(),
 4027                last_workspace_edits_by_language_server: Default::default(),
 4028                language_server_watched_paths: Default::default(),
 4029                language_server_paths_watched_for_rename: Default::default(),
 4030                language_server_dynamic_registrations: Default::default(),
 4031                buffers_being_formatted: Default::default(),
 4032                buffer_snapshots: Default::default(),
 4033                prettier_store,
 4034                environment,
 4035                http_client,
 4036                fs,
 4037                yarn,
 4038                next_diagnostic_group_id: Default::default(),
 4039                diagnostics: Default::default(),
 4040                _subscription: cx.on_app_quit(|this, cx| {
 4041                    this.as_local_mut()
 4042                        .unwrap()
 4043                        .shutdown_language_servers_on_quit(cx)
 4044                }),
 4045                lsp_tree: LanguageServerTree::new(
 4046                    manifest_tree,
 4047                    languages.clone(),
 4048                    toolchain_store.clone(),
 4049                ),
 4050                toolchain_store,
 4051                registered_buffers: HashMap::default(),
 4052                buffers_opened_in_servers: HashMap::default(),
 4053                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4054                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4055                restricted_worktrees_tasks: HashMap::default(),
 4056                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4057                    .manifest_file_names(),
 4058            }),
 4059            last_formatting_failure: None,
 4060            downstream_client: None,
 4061            buffer_store,
 4062            worktree_store,
 4063            languages: languages.clone(),
 4064            language_server_statuses: Default::default(),
 4065            nonce: StdRng::from_os_rng().random(),
 4066            diagnostic_summaries: HashMap::default(),
 4067            lsp_server_capabilities: HashMap::default(),
 4068            lsp_data: HashMap::default(),
 4069            next_hint_id: Arc::default(),
 4070            active_entry: None,
 4071            _maintain_workspace_config,
 4072            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4073        }
 4074    }
 4075
 4076    fn send_lsp_proto_request<R: LspCommand>(
 4077        &self,
 4078        buffer: Entity<Buffer>,
 4079        client: AnyProtoClient,
 4080        upstream_project_id: u64,
 4081        request: R,
 4082        cx: &mut Context<LspStore>,
 4083    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4084        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4085            return Task::ready(Ok(R::Response::default()));
 4086        }
 4087        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4088        cx.spawn(async move |this, cx| {
 4089            let response = client.request(message).await?;
 4090            let this = this.upgrade().context("project dropped")?;
 4091            request
 4092                .response_from_proto(response, this, buffer, cx.clone())
 4093                .await
 4094        })
 4095    }
 4096
 4097    pub(super) fn new_remote(
 4098        buffer_store: Entity<BufferStore>,
 4099        worktree_store: Entity<WorktreeStore>,
 4100        languages: Arc<LanguageRegistry>,
 4101        upstream_client: AnyProtoClient,
 4102        project_id: u64,
 4103        cx: &mut Context<Self>,
 4104    ) -> Self {
 4105        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4106            .detach();
 4107        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4108            .detach();
 4109        subscribe_to_binary_statuses(&languages, cx).detach();
 4110        let _maintain_workspace_config = {
 4111            let (sender, receiver) = watch::channel();
 4112            (Self::maintain_workspace_config(receiver, cx), sender)
 4113        };
 4114        Self {
 4115            mode: LspStoreMode::Remote(RemoteLspStore {
 4116                upstream_client: Some(upstream_client),
 4117                upstream_project_id: project_id,
 4118            }),
 4119            downstream_client: None,
 4120            last_formatting_failure: None,
 4121            buffer_store,
 4122            worktree_store,
 4123            languages: languages.clone(),
 4124            language_server_statuses: Default::default(),
 4125            nonce: StdRng::from_os_rng().random(),
 4126            diagnostic_summaries: HashMap::default(),
 4127            lsp_server_capabilities: HashMap::default(),
 4128            next_hint_id: Arc::default(),
 4129            lsp_data: HashMap::default(),
 4130            active_entry: None,
 4131
 4132            _maintain_workspace_config,
 4133            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4134        }
 4135    }
 4136
 4137    fn on_buffer_store_event(
 4138        &mut self,
 4139        _: Entity<BufferStore>,
 4140        event: &BufferStoreEvent,
 4141        cx: &mut Context<Self>,
 4142    ) {
 4143        match event {
 4144            BufferStoreEvent::BufferAdded(buffer) => {
 4145                self.on_buffer_added(buffer, cx).log_err();
 4146            }
 4147            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4148                let buffer_id = buffer.read(cx).remote_id();
 4149                if let Some(local) = self.as_local_mut()
 4150                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4151                {
 4152                    local.reset_buffer(buffer, old_file, cx);
 4153
 4154                    if local.registered_buffers.contains_key(&buffer_id) {
 4155                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4156                    }
 4157                }
 4158
 4159                self.detect_language_for_buffer(buffer, cx);
 4160                if let Some(local) = self.as_local_mut() {
 4161                    local.initialize_buffer(buffer, cx);
 4162                    if local.registered_buffers.contains_key(&buffer_id) {
 4163                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4164                    }
 4165                }
 4166            }
 4167            _ => {}
 4168        }
 4169    }
 4170
 4171    fn on_worktree_store_event(
 4172        &mut self,
 4173        _: Entity<WorktreeStore>,
 4174        event: &WorktreeStoreEvent,
 4175        cx: &mut Context<Self>,
 4176    ) {
 4177        match event {
 4178            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4179                if !worktree.read(cx).is_local() {
 4180                    return;
 4181                }
 4182                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4183                    worktree::Event::UpdatedEntries(changes) => {
 4184                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4185                    }
 4186                    worktree::Event::UpdatedGitRepositories(_)
 4187                    | worktree::Event::DeletedEntry(_) => {}
 4188                })
 4189                .detach()
 4190            }
 4191            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4192            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4193                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4194            }
 4195            WorktreeStoreEvent::WorktreeReleased(..)
 4196            | WorktreeStoreEvent::WorktreeOrderChanged
 4197            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4198            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4199            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4200        }
 4201    }
 4202
 4203    fn on_prettier_store_event(
 4204        &mut self,
 4205        _: Entity<PrettierStore>,
 4206        event: &PrettierStoreEvent,
 4207        cx: &mut Context<Self>,
 4208    ) {
 4209        match event {
 4210            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4211                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4212            }
 4213            PrettierStoreEvent::LanguageServerAdded {
 4214                new_server_id,
 4215                name,
 4216                prettier_server,
 4217            } => {
 4218                self.register_supplementary_language_server(
 4219                    *new_server_id,
 4220                    name.clone(),
 4221                    prettier_server.clone(),
 4222                    cx,
 4223                );
 4224            }
 4225        }
 4226    }
 4227
 4228    fn on_toolchain_store_event(
 4229        &mut self,
 4230        _: Entity<LocalToolchainStore>,
 4231        event: &ToolchainStoreEvent,
 4232        _: &mut Context<Self>,
 4233    ) {
 4234        if let ToolchainStoreEvent::ToolchainActivated = event {
 4235            self.request_workspace_config_refresh()
 4236        }
 4237    }
 4238
 4239    fn request_workspace_config_refresh(&mut self) {
 4240        *self._maintain_workspace_config.1.borrow_mut() = ();
 4241    }
 4242
 4243    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4244        self.as_local().map(|local| local.prettier_store.clone())
 4245    }
 4246
 4247    fn on_buffer_event(
 4248        &mut self,
 4249        buffer: Entity<Buffer>,
 4250        event: &language::BufferEvent,
 4251        cx: &mut Context<Self>,
 4252    ) {
 4253        match event {
 4254            language::BufferEvent::Edited => {
 4255                self.on_buffer_edited(buffer, cx);
 4256            }
 4257
 4258            language::BufferEvent::Saved => {
 4259                self.on_buffer_saved(buffer, cx);
 4260            }
 4261
 4262            _ => {}
 4263        }
 4264    }
 4265
 4266    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4267        buffer
 4268            .read(cx)
 4269            .set_language_registry(self.languages.clone());
 4270
 4271        cx.subscribe(buffer, |this, buffer, event, cx| {
 4272            this.on_buffer_event(buffer, event, cx);
 4273        })
 4274        .detach();
 4275
 4276        self.detect_language_for_buffer(buffer, cx);
 4277        if let Some(local) = self.as_local_mut() {
 4278            local.initialize_buffer(buffer, cx);
 4279        }
 4280
 4281        Ok(())
 4282    }
 4283
 4284    pub(crate) fn register_buffer_with_language_servers(
 4285        &mut self,
 4286        buffer: &Entity<Buffer>,
 4287        only_register_servers: HashSet<LanguageServerSelector>,
 4288        ignore_refcounts: bool,
 4289        cx: &mut Context<Self>,
 4290    ) -> OpenLspBufferHandle {
 4291        let buffer_id = buffer.read(cx).remote_id();
 4292        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4293        if let Some(local) = self.as_local_mut() {
 4294            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4295            if !ignore_refcounts {
 4296                *refcount += 1;
 4297            }
 4298
 4299            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4300            // 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
 4301            // 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
 4302            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4303            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4304                return handle;
 4305            };
 4306            if !file.is_local() {
 4307                return handle;
 4308            }
 4309
 4310            if ignore_refcounts || *refcount == 1 {
 4311                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4312            }
 4313            if !ignore_refcounts {
 4314                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4315                    let refcount = {
 4316                        let local = lsp_store.as_local_mut().unwrap();
 4317                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4318                            debug_panic!("bad refcounting");
 4319                            return;
 4320                        };
 4321
 4322                        *refcount -= 1;
 4323                        *refcount
 4324                    };
 4325                    if refcount == 0 {
 4326                        lsp_store.lsp_data.remove(&buffer_id);
 4327                        let local = lsp_store.as_local_mut().unwrap();
 4328                        local.registered_buffers.remove(&buffer_id);
 4329
 4330                        local.buffers_opened_in_servers.remove(&buffer_id);
 4331                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4332                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4333
 4334                            let buffer_abs_path = file.abs_path(cx);
 4335                            for (_, buffer_pull_diagnostics_result_ids) in
 4336                                &mut local.buffer_pull_diagnostics_result_ids
 4337                            {
 4338                                buffer_pull_diagnostics_result_ids.retain(
 4339                                    |_, buffer_result_ids| {
 4340                                        buffer_result_ids.remove(&buffer_abs_path);
 4341                                        !buffer_result_ids.is_empty()
 4342                                    },
 4343                                );
 4344                            }
 4345
 4346                            let diagnostic_updates = local
 4347                                .language_servers
 4348                                .keys()
 4349                                .cloned()
 4350                                .map(|server_id| DocumentDiagnosticsUpdate {
 4351                                    diagnostics: DocumentDiagnostics {
 4352                                        document_abs_path: buffer_abs_path.clone(),
 4353                                        version: None,
 4354                                        diagnostics: Vec::new(),
 4355                                    },
 4356                                    result_id: None,
 4357                                    registration_id: None,
 4358                                    server_id: server_id,
 4359                                    disk_based_sources: Cow::Borrowed(&[]),
 4360                                })
 4361                                .collect::<Vec<_>>();
 4362
 4363                            lsp_store
 4364                                .merge_diagnostic_entries(
 4365                                    diagnostic_updates,
 4366                                    |_, diagnostic, _| {
 4367                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4368                                    },
 4369                                    cx,
 4370                                )
 4371                                .context("Clearing diagnostics for the closed buffer")
 4372                                .log_err();
 4373                        }
 4374                    }
 4375                })
 4376                .detach();
 4377            }
 4378        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4379            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4380            cx.background_spawn(async move {
 4381                upstream_client
 4382                    .request(proto::RegisterBufferWithLanguageServers {
 4383                        project_id: upstream_project_id,
 4384                        buffer_id,
 4385                        only_servers: only_register_servers
 4386                            .into_iter()
 4387                            .map(|selector| {
 4388                                let selector = match selector {
 4389                                    LanguageServerSelector::Id(language_server_id) => {
 4390                                        proto::language_server_selector::Selector::ServerId(
 4391                                            language_server_id.to_proto(),
 4392                                        )
 4393                                    }
 4394                                    LanguageServerSelector::Name(language_server_name) => {
 4395                                        proto::language_server_selector::Selector::Name(
 4396                                            language_server_name.to_string(),
 4397                                        )
 4398                                    }
 4399                                };
 4400                                proto::LanguageServerSelector {
 4401                                    selector: Some(selector),
 4402                                }
 4403                            })
 4404                            .collect(),
 4405                    })
 4406                    .await
 4407            })
 4408            .detach();
 4409        } else {
 4410            // Our remote connection got closed
 4411        }
 4412        handle
 4413    }
 4414
 4415    fn maintain_buffer_languages(
 4416        languages: Arc<LanguageRegistry>,
 4417        cx: &mut Context<Self>,
 4418    ) -> Task<()> {
 4419        let mut subscription = languages.subscribe();
 4420        let mut prev_reload_count = languages.reload_count();
 4421        cx.spawn(async move |this, cx| {
 4422            while let Some(()) = subscription.next().await {
 4423                if let Some(this) = this.upgrade() {
 4424                    // If the language registry has been reloaded, then remove and
 4425                    // re-assign the languages on all open buffers.
 4426                    let reload_count = languages.reload_count();
 4427                    if reload_count > prev_reload_count {
 4428                        prev_reload_count = reload_count;
 4429                        this.update(cx, |this, cx| {
 4430                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4431                                for buffer in buffer_store.buffers() {
 4432                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4433                                    {
 4434                                        buffer.update(cx, |buffer, cx| {
 4435                                            buffer.set_language_async(None, cx)
 4436                                        });
 4437                                        if let Some(local) = this.as_local_mut() {
 4438                                            local.reset_buffer(&buffer, &f, cx);
 4439
 4440                                            if local
 4441                                                .registered_buffers
 4442                                                .contains_key(&buffer.read(cx).remote_id())
 4443                                                && let Some(file_url) =
 4444                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4445                                            {
 4446                                                local.unregister_buffer_from_language_servers(
 4447                                                    &buffer, &file_url, cx,
 4448                                                );
 4449                                            }
 4450                                        }
 4451                                    }
 4452                                }
 4453                            });
 4454                        });
 4455                    }
 4456
 4457                    this.update(cx, |this, cx| {
 4458                        let mut plain_text_buffers = Vec::new();
 4459                        let mut buffers_with_unknown_injections = Vec::new();
 4460                        for handle in this.buffer_store.read(cx).buffers() {
 4461                            let buffer = handle.read(cx);
 4462                            if buffer.language().is_none()
 4463                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4464                            {
 4465                                plain_text_buffers.push(handle);
 4466                            } else if buffer.contains_unknown_injections() {
 4467                                buffers_with_unknown_injections.push(handle);
 4468                            }
 4469                        }
 4470
 4471                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4472                        // and reused later in the invisible worktrees.
 4473                        plain_text_buffers.sort_by_key(|buffer| {
 4474                            Reverse(
 4475                                File::from_dyn(buffer.read(cx).file())
 4476                                    .map(|file| file.worktree.read(cx).is_visible()),
 4477                            )
 4478                        });
 4479
 4480                        for buffer in plain_text_buffers {
 4481                            this.detect_language_for_buffer(&buffer, cx);
 4482                            if let Some(local) = this.as_local_mut() {
 4483                                local.initialize_buffer(&buffer, cx);
 4484                                if local
 4485                                    .registered_buffers
 4486                                    .contains_key(&buffer.read(cx).remote_id())
 4487                                {
 4488                                    local.register_buffer_with_language_servers(
 4489                                        &buffer,
 4490                                        HashSet::default(),
 4491                                        cx,
 4492                                    );
 4493                                }
 4494                            }
 4495                        }
 4496
 4497                        for buffer in buffers_with_unknown_injections {
 4498                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4499                        }
 4500                    });
 4501                }
 4502            }
 4503        })
 4504    }
 4505
 4506    fn detect_language_for_buffer(
 4507        &mut self,
 4508        buffer_handle: &Entity<Buffer>,
 4509        cx: &mut Context<Self>,
 4510    ) -> Option<language::AvailableLanguage> {
 4511        // If the buffer has a language, set it and start the language server if we haven't already.
 4512        let buffer = buffer_handle.read(cx);
 4513        let file = buffer.file()?;
 4514
 4515        let content = buffer.as_rope();
 4516        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4517        if let Some(available_language) = &available_language {
 4518            if let Some(Ok(Ok(new_language))) = self
 4519                .languages
 4520                .load_language(available_language)
 4521                .now_or_never()
 4522            {
 4523                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4524            }
 4525        } else {
 4526            cx.emit(LspStoreEvent::LanguageDetected {
 4527                buffer: buffer_handle.clone(),
 4528                new_language: None,
 4529            });
 4530        }
 4531
 4532        available_language
 4533    }
 4534
 4535    pub(crate) fn set_language_for_buffer(
 4536        &mut self,
 4537        buffer_entity: &Entity<Buffer>,
 4538        new_language: Arc<Language>,
 4539        cx: &mut Context<Self>,
 4540    ) {
 4541        let buffer = buffer_entity.read(cx);
 4542        let buffer_file = buffer.file().cloned();
 4543        let buffer_id = buffer.remote_id();
 4544        if let Some(local_store) = self.as_local_mut()
 4545            && local_store.registered_buffers.contains_key(&buffer_id)
 4546            && let Some(abs_path) =
 4547                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4548            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4549        {
 4550            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4551        }
 4552        buffer_entity.update(cx, |buffer, cx| {
 4553            if buffer
 4554                .language()
 4555                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4556            {
 4557                buffer.set_language_async(Some(new_language.clone()), cx);
 4558            }
 4559        });
 4560
 4561        let settings =
 4562            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4563        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4564
 4565        let worktree_id = if let Some(file) = buffer_file {
 4566            let worktree = file.worktree.clone();
 4567
 4568            if let Some(local) = self.as_local_mut()
 4569                && local.registered_buffers.contains_key(&buffer_id)
 4570            {
 4571                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4572            }
 4573            Some(worktree.read(cx).id())
 4574        } else {
 4575            None
 4576        };
 4577
 4578        if settings.prettier.allowed
 4579            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4580        {
 4581            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4582            if let Some(prettier_store) = prettier_store {
 4583                prettier_store.update(cx, |prettier_store, cx| {
 4584                    prettier_store.install_default_prettier(
 4585                        worktree_id,
 4586                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4587                        cx,
 4588                    )
 4589                })
 4590            }
 4591        }
 4592
 4593        cx.emit(LspStoreEvent::LanguageDetected {
 4594            buffer: buffer_entity.clone(),
 4595            new_language: Some(new_language),
 4596        })
 4597    }
 4598
 4599    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4600        self.buffer_store.clone()
 4601    }
 4602
 4603    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4604        self.active_entry = active_entry;
 4605    }
 4606
 4607    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4608        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4609            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4610        {
 4611            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4612                summaries
 4613                    .iter()
 4614                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4615            });
 4616            if let Some(summary) = summaries.next() {
 4617                client
 4618                    .send(proto::UpdateDiagnosticSummary {
 4619                        project_id: downstream_project_id,
 4620                        worktree_id: worktree.id().to_proto(),
 4621                        summary: Some(summary),
 4622                        more_summaries: summaries.collect(),
 4623                    })
 4624                    .log_err();
 4625            }
 4626        }
 4627    }
 4628
 4629    fn is_capable_for_proto_request<R>(
 4630        &self,
 4631        buffer: &Entity<Buffer>,
 4632        request: &R,
 4633        cx: &App,
 4634    ) -> bool
 4635    where
 4636        R: LspCommand,
 4637    {
 4638        self.check_if_capable_for_proto_request(
 4639            buffer,
 4640            |capabilities| {
 4641                request.check_capabilities(AdapterServerCapabilities {
 4642                    server_capabilities: capabilities.clone(),
 4643                    code_action_kinds: None,
 4644                })
 4645            },
 4646            cx,
 4647        )
 4648    }
 4649
 4650    fn check_if_capable_for_proto_request<F>(
 4651        &self,
 4652        buffer: &Entity<Buffer>,
 4653        check: F,
 4654        cx: &App,
 4655    ) -> bool
 4656    where
 4657        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4658    {
 4659        let Some(language) = buffer.read(cx).language().cloned() else {
 4660            return false;
 4661        };
 4662        let registered_language_servers = self
 4663            .languages
 4664            .lsp_adapters(&language.name())
 4665            .into_iter()
 4666            .map(|lsp_adapter| lsp_adapter.name())
 4667            .collect::<HashSet<_>>();
 4668        self.language_server_statuses
 4669            .iter()
 4670            .filter_map(|(server_id, server_status)| {
 4671                // Include servers that are either registered for this language OR
 4672                // available to be loaded (for SSH remote mode where adapters like
 4673                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4674                // but only loaded on the server side)
 4675                let is_relevant = registered_language_servers.contains(&server_status.name)
 4676                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4677                is_relevant.then_some(server_id)
 4678            })
 4679            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4680            .any(check)
 4681    }
 4682
 4683    fn all_capable_for_proto_request<F>(
 4684        &self,
 4685        buffer: &Entity<Buffer>,
 4686        mut check: F,
 4687        cx: &App,
 4688    ) -> Vec<lsp::LanguageServerId>
 4689    where
 4690        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4691    {
 4692        let Some(language) = buffer.read(cx).language().cloned() else {
 4693            return Vec::default();
 4694        };
 4695        let registered_language_servers = self
 4696            .languages
 4697            .lsp_adapters(&language.name())
 4698            .into_iter()
 4699            .map(|lsp_adapter| lsp_adapter.name())
 4700            .collect::<HashSet<_>>();
 4701        self.language_server_statuses
 4702            .iter()
 4703            .filter_map(|(server_id, server_status)| {
 4704                // Include servers that are either registered for this language OR
 4705                // available to be loaded (for SSH remote mode where adapters like
 4706                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4707                // but only loaded on the server side)
 4708                let is_relevant = registered_language_servers.contains(&server_status.name)
 4709                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4710                is_relevant.then_some((server_id, &server_status.name))
 4711            })
 4712            .filter_map(|(server_id, server_name)| {
 4713                self.lsp_server_capabilities
 4714                    .get(server_id)
 4715                    .map(|c| (server_id, server_name, c))
 4716            })
 4717            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4718            .map(|(server_id, _, _)| *server_id)
 4719            .collect()
 4720    }
 4721
 4722    pub fn request_lsp<R>(
 4723        &mut self,
 4724        buffer: Entity<Buffer>,
 4725        server: LanguageServerToQuery,
 4726        request: R,
 4727        cx: &mut Context<Self>,
 4728    ) -> Task<Result<R::Response>>
 4729    where
 4730        R: LspCommand,
 4731        <R::LspRequest as lsp::request::Request>::Result: Send,
 4732        <R::LspRequest as lsp::request::Request>::Params: Send,
 4733    {
 4734        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4735            return self.send_lsp_proto_request(
 4736                buffer,
 4737                upstream_client,
 4738                upstream_project_id,
 4739                request,
 4740                cx,
 4741            );
 4742        }
 4743
 4744        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4745            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4746                local
 4747                    .language_servers_for_buffer(buffer, cx)
 4748                    .find(|(_, server)| {
 4749                        request.check_capabilities(server.adapter_server_capabilities())
 4750                    })
 4751                    .map(|(_, server)| server.clone())
 4752            }),
 4753            LanguageServerToQuery::Other(id) => self
 4754                .language_server_for_local_buffer(buffer, id, cx)
 4755                .and_then(|(_, server)| {
 4756                    request
 4757                        .check_capabilities(server.adapter_server_capabilities())
 4758                        .then(|| Arc::clone(server))
 4759                }),
 4760        }) else {
 4761            return Task::ready(Ok(Default::default()));
 4762        };
 4763
 4764        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4765
 4766        let Some(file) = file else {
 4767            return Task::ready(Ok(Default::default()));
 4768        };
 4769
 4770        let lsp_params = match request.to_lsp_params_or_response(
 4771            &file.abs_path(cx),
 4772            buffer.read(cx),
 4773            &language_server,
 4774            cx,
 4775        ) {
 4776            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4777            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4778            Err(err) => {
 4779                let message = format!(
 4780                    "{} via {} failed: {}",
 4781                    request.display_name(),
 4782                    language_server.name(),
 4783                    err
 4784                );
 4785                // rust-analyzer likes to error with this when its still loading up
 4786                if !message.ends_with("content modified") {
 4787                    log::warn!("{message}");
 4788                }
 4789                return Task::ready(Err(anyhow!(message)));
 4790            }
 4791        };
 4792
 4793        let status = request.status();
 4794        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4795            return Task::ready(Ok(Default::default()));
 4796        }
 4797        cx.spawn(async move |this, cx| {
 4798            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4799
 4800            let id = lsp_request.id();
 4801            let _cleanup = if status.is_some() {
 4802                cx.update(|cx| {
 4803                    this.update(cx, |this, cx| {
 4804                        this.on_lsp_work_start(
 4805                            language_server.server_id(),
 4806                            ProgressToken::Number(id),
 4807                            LanguageServerProgress {
 4808                                is_disk_based_diagnostics_progress: false,
 4809                                is_cancellable: false,
 4810                                title: None,
 4811                                message: status.clone(),
 4812                                percentage: None,
 4813                                last_update_at: cx.background_executor().now(),
 4814                            },
 4815                            cx,
 4816                        );
 4817                    })
 4818                })
 4819                .log_err();
 4820
 4821                Some(defer(|| {
 4822                    cx.update(|cx| {
 4823                        this.update(cx, |this, cx| {
 4824                            this.on_lsp_work_end(
 4825                                language_server.server_id(),
 4826                                ProgressToken::Number(id),
 4827                                cx,
 4828                            );
 4829                        })
 4830                    })
 4831                    .log_err();
 4832                }))
 4833            } else {
 4834                None
 4835            };
 4836
 4837            let result = lsp_request.await.into_response();
 4838
 4839            let response = result.map_err(|err| {
 4840                let message = format!(
 4841                    "{} via {} failed: {}",
 4842                    request.display_name(),
 4843                    language_server.name(),
 4844                    err
 4845                );
 4846                // rust-analyzer likes to error with this when its still loading up
 4847                if !message.ends_with("content modified") {
 4848                    log::warn!("{message}");
 4849                }
 4850                anyhow::anyhow!(message)
 4851            })?;
 4852
 4853            request
 4854                .response_from_lsp(
 4855                    response,
 4856                    this.upgrade().context("no app context")?,
 4857                    buffer,
 4858                    language_server.server_id(),
 4859                    cx.clone(),
 4860                )
 4861                .await
 4862        })
 4863    }
 4864
 4865    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4866        let mut language_formatters_to_check = Vec::new();
 4867        for buffer in self.buffer_store.read(cx).buffers() {
 4868            let buffer = buffer.read(cx);
 4869            let buffer_file = File::from_dyn(buffer.file());
 4870            let buffer_language = buffer.language();
 4871            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4872            if buffer_language.is_some() {
 4873                language_formatters_to_check.push((
 4874                    buffer_file.map(|f| f.worktree_id(cx)),
 4875                    settings.into_owned(),
 4876                ));
 4877            }
 4878        }
 4879
 4880        self.request_workspace_config_refresh();
 4881
 4882        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4883            prettier_store.update(cx, |prettier_store, cx| {
 4884                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4885            })
 4886        }
 4887
 4888        cx.notify();
 4889    }
 4890
 4891    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4892        let buffer_store = self.buffer_store.clone();
 4893        let Some(local) = self.as_local_mut() else {
 4894            return;
 4895        };
 4896        let mut adapters = BTreeMap::default();
 4897        let get_adapter = {
 4898            let languages = local.languages.clone();
 4899            let environment = local.environment.clone();
 4900            let weak = local.weak.clone();
 4901            let worktree_store = local.worktree_store.clone();
 4902            let http_client = local.http_client.clone();
 4903            let fs = local.fs.clone();
 4904            move |worktree_id, cx: &mut App| {
 4905                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4906                Some(LocalLspAdapterDelegate::new(
 4907                    languages.clone(),
 4908                    &environment,
 4909                    weak.clone(),
 4910                    &worktree,
 4911                    http_client.clone(),
 4912                    fs.clone(),
 4913                    cx,
 4914                ))
 4915            }
 4916        };
 4917
 4918        let mut messages_to_report = Vec::new();
 4919        let (new_tree, to_stop) = {
 4920            let mut rebase = local.lsp_tree.rebase();
 4921            let buffers = buffer_store
 4922                .read(cx)
 4923                .buffers()
 4924                .filter_map(|buffer| {
 4925                    let raw_buffer = buffer.read(cx);
 4926                    if !local
 4927                        .registered_buffers
 4928                        .contains_key(&raw_buffer.remote_id())
 4929                    {
 4930                        return None;
 4931                    }
 4932                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4933                    let language = raw_buffer.language().cloned()?;
 4934                    Some((file, language, raw_buffer.remote_id()))
 4935                })
 4936                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4937            for (file, language, buffer_id) in buffers {
 4938                let worktree_id = file.worktree_id(cx);
 4939                let Some(worktree) = local
 4940                    .worktree_store
 4941                    .read(cx)
 4942                    .worktree_for_id(worktree_id, cx)
 4943                else {
 4944                    continue;
 4945                };
 4946
 4947                if let Some((_, apply)) = local.reuse_existing_language_server(
 4948                    rebase.server_tree(),
 4949                    &worktree,
 4950                    &language.name(),
 4951                    cx,
 4952                ) {
 4953                    (apply)(rebase.server_tree());
 4954                } else if let Some(lsp_delegate) = adapters
 4955                    .entry(worktree_id)
 4956                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4957                    .clone()
 4958                {
 4959                    let delegate =
 4960                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4961                    let path = file
 4962                        .path()
 4963                        .parent()
 4964                        .map(Arc::from)
 4965                        .unwrap_or_else(|| file.path().clone());
 4966                    let worktree_path = ProjectPath { worktree_id, path };
 4967                    let abs_path = file.abs_path(cx);
 4968                    let nodes = rebase
 4969                        .walk(
 4970                            worktree_path,
 4971                            language.name(),
 4972                            language.manifest(),
 4973                            delegate.clone(),
 4974                            cx,
 4975                        )
 4976                        .collect::<Vec<_>>();
 4977                    for node in nodes {
 4978                        let server_id = node.server_id_or_init(|disposition| {
 4979                            let path = &disposition.path;
 4980                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4981                            let key = LanguageServerSeed {
 4982                                worktree_id,
 4983                                name: disposition.server_name.clone(),
 4984                                settings: disposition.settings.clone(),
 4985                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4986                                    path.worktree_id,
 4987                                    &path.path,
 4988                                    language.name(),
 4989                                ),
 4990                            };
 4991                            local.language_server_ids.remove(&key);
 4992
 4993                            let server_id = local.get_or_insert_language_server(
 4994                                &worktree,
 4995                                lsp_delegate.clone(),
 4996                                disposition,
 4997                                &language.name(),
 4998                                cx,
 4999                            );
 5000                            if let Some(state) = local.language_servers.get(&server_id)
 5001                                && let Ok(uri) = uri
 5002                            {
 5003                                state.add_workspace_folder(uri);
 5004                            };
 5005                            server_id
 5006                        });
 5007
 5008                        if let Some(language_server_id) = server_id {
 5009                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5010                                language_server_id,
 5011                                name: node.name(),
 5012                                message:
 5013                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5014                                        proto::RegisteredForBuffer {
 5015                                            buffer_abs_path: abs_path
 5016                                                .to_string_lossy()
 5017                                                .into_owned(),
 5018                                            buffer_id: buffer_id.to_proto(),
 5019                                        },
 5020                                    ),
 5021                            });
 5022                        }
 5023                    }
 5024                } else {
 5025                    continue;
 5026                }
 5027            }
 5028            rebase.finish()
 5029        };
 5030        for message in messages_to_report {
 5031            cx.emit(message);
 5032        }
 5033        local.lsp_tree = new_tree;
 5034        for (id, _) in to_stop {
 5035            self.stop_local_language_server(id, cx).detach();
 5036        }
 5037    }
 5038
 5039    pub fn apply_code_action(
 5040        &self,
 5041        buffer_handle: Entity<Buffer>,
 5042        mut action: CodeAction,
 5043        push_to_history: bool,
 5044        cx: &mut Context<Self>,
 5045    ) -> Task<Result<ProjectTransaction>> {
 5046        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5047            let request = proto::ApplyCodeAction {
 5048                project_id,
 5049                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5050                action: Some(Self::serialize_code_action(&action)),
 5051            };
 5052            let buffer_store = self.buffer_store();
 5053            cx.spawn(async move |_, cx| {
 5054                let response = upstream_client
 5055                    .request(request)
 5056                    .await?
 5057                    .transaction
 5058                    .context("missing transaction")?;
 5059
 5060                buffer_store
 5061                    .update(cx, |buffer_store, cx| {
 5062                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5063                    })
 5064                    .await
 5065            })
 5066        } else if self.mode.is_local() {
 5067            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 5068                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5069                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 5070            }) else {
 5071                return Task::ready(Ok(ProjectTransaction::default()));
 5072            };
 5073            cx.spawn(async move |this,  cx| {
 5074                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 5075                    .await
 5076                    .context("resolving a code action")?;
 5077                if let Some(edit) = action.lsp_action.edit()
 5078                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5079                        return LocalLspStore::deserialize_workspace_edit(
 5080                            this.upgrade().context("no app present")?,
 5081                            edit.clone(),
 5082                            push_to_history,
 5083
 5084                            lang_server.clone(),
 5085                            cx,
 5086                        )
 5087                        .await;
 5088                    }
 5089
 5090                if let Some(command) = action.lsp_action.command() {
 5091                    let server_capabilities = lang_server.capabilities();
 5092                    let available_commands = server_capabilities
 5093                        .execute_command_provider
 5094                        .as_ref()
 5095                        .map(|options| options.commands.as_slice())
 5096                        .unwrap_or_default();
 5097                    if available_commands.contains(&command.command) {
 5098                        this.update(cx, |this, _| {
 5099                            this.as_local_mut()
 5100                                .unwrap()
 5101                                .last_workspace_edits_by_language_server
 5102                                .remove(&lang_server.server_id());
 5103                        })?;
 5104
 5105                        let _result = lang_server
 5106                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5107                                command: command.command.clone(),
 5108                                arguments: command.arguments.clone().unwrap_or_default(),
 5109                                ..lsp::ExecuteCommandParams::default()
 5110                            })
 5111                            .await.into_response()
 5112                            .context("execute command")?;
 5113
 5114                        return this.update(cx, |this, _| {
 5115                            this.as_local_mut()
 5116                                .unwrap()
 5117                                .last_workspace_edits_by_language_server
 5118                                .remove(&lang_server.server_id())
 5119                                .unwrap_or_default()
 5120                        });
 5121                    } else {
 5122                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5123                    }
 5124                }
 5125
 5126                Ok(ProjectTransaction::default())
 5127            })
 5128        } else {
 5129            Task::ready(Err(anyhow!("no upstream client and not local")))
 5130        }
 5131    }
 5132
 5133    pub fn apply_code_action_kind(
 5134        &mut self,
 5135        buffers: HashSet<Entity<Buffer>>,
 5136        kind: CodeActionKind,
 5137        push_to_history: bool,
 5138        cx: &mut Context<Self>,
 5139    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5140        if self.as_local().is_some() {
 5141            cx.spawn(async move |lsp_store, cx| {
 5142                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5143                let result = LocalLspStore::execute_code_action_kind_locally(
 5144                    lsp_store.clone(),
 5145                    buffers,
 5146                    kind,
 5147                    push_to_history,
 5148                    cx,
 5149                )
 5150                .await;
 5151                lsp_store.update(cx, |lsp_store, _| {
 5152                    lsp_store.update_last_formatting_failure(&result);
 5153                })?;
 5154                result
 5155            })
 5156        } else if let Some((client, project_id)) = self.upstream_client() {
 5157            let buffer_store = self.buffer_store();
 5158            cx.spawn(async move |lsp_store, cx| {
 5159                let result = client
 5160                    .request(proto::ApplyCodeActionKind {
 5161                        project_id,
 5162                        kind: kind.as_str().to_owned(),
 5163                        buffer_ids: buffers
 5164                            .iter()
 5165                            .map(|buffer| {
 5166                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5167                            })
 5168                            .collect(),
 5169                    })
 5170                    .await
 5171                    .and_then(|result| result.transaction.context("missing transaction"));
 5172                lsp_store.update(cx, |lsp_store, _| {
 5173                    lsp_store.update_last_formatting_failure(&result);
 5174                })?;
 5175
 5176                let transaction_response = result?;
 5177                buffer_store
 5178                    .update(cx, |buffer_store, cx| {
 5179                        buffer_store.deserialize_project_transaction(
 5180                            transaction_response,
 5181                            push_to_history,
 5182                            cx,
 5183                        )
 5184                    })
 5185                    .await
 5186            })
 5187        } else {
 5188            Task::ready(Ok(ProjectTransaction::default()))
 5189        }
 5190    }
 5191
 5192    pub fn resolved_hint(
 5193        &mut self,
 5194        buffer_id: BufferId,
 5195        id: InlayId,
 5196        cx: &mut Context<Self>,
 5197    ) -> Option<ResolvedHint> {
 5198        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5199
 5200        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5201        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5202        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5203        let (server_id, resolve_data) = match &hint.resolve_state {
 5204            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5205            ResolveState::Resolving => {
 5206                return Some(ResolvedHint::Resolving(
 5207                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5208                ));
 5209            }
 5210            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5211        };
 5212
 5213        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5214        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5215        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5216            id,
 5217            cx.spawn(async move |lsp_store, cx| {
 5218                let resolved_hint = resolve_task.await;
 5219                lsp_store
 5220                    .update(cx, |lsp_store, _| {
 5221                        if let Some(old_inlay_hint) = lsp_store
 5222                            .lsp_data
 5223                            .get_mut(&buffer_id)
 5224                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5225                        {
 5226                            match resolved_hint {
 5227                                Ok(resolved_hint) => {
 5228                                    *old_inlay_hint = resolved_hint;
 5229                                }
 5230                                Err(e) => {
 5231                                    old_inlay_hint.resolve_state =
 5232                                        ResolveState::CanResolve(server_id, resolve_data);
 5233                                    log::error!("Inlay hint resolve failed: {e:#}");
 5234                                }
 5235                            }
 5236                        }
 5237                    })
 5238                    .ok();
 5239            })
 5240            .shared(),
 5241        );
 5242        debug_assert!(
 5243            previous_task.is_none(),
 5244            "Did not change hint's resolve state after spawning its resolve"
 5245        );
 5246        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5247        None
 5248    }
 5249
 5250    fn resolve_inlay_hint(
 5251        &self,
 5252        mut hint: InlayHint,
 5253        buffer: Entity<Buffer>,
 5254        server_id: LanguageServerId,
 5255        cx: &mut Context<Self>,
 5256    ) -> Task<anyhow::Result<InlayHint>> {
 5257        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5258            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5259            {
 5260                hint.resolve_state = ResolveState::Resolved;
 5261                return Task::ready(Ok(hint));
 5262            }
 5263            let request = proto::ResolveInlayHint {
 5264                project_id,
 5265                buffer_id: buffer.read(cx).remote_id().into(),
 5266                language_server_id: server_id.0 as u64,
 5267                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5268            };
 5269            cx.background_spawn(async move {
 5270                let response = upstream_client
 5271                    .request(request)
 5272                    .await
 5273                    .context("inlay hints proto request")?;
 5274                match response.hint {
 5275                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5276                        .context("inlay hints proto resolve response conversion"),
 5277                    None => Ok(hint),
 5278                }
 5279            })
 5280        } else {
 5281            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5282                self.language_server_for_local_buffer(buffer, server_id, cx)
 5283                    .map(|(_, server)| server.clone())
 5284            }) else {
 5285                return Task::ready(Ok(hint));
 5286            };
 5287            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5288                return Task::ready(Ok(hint));
 5289            }
 5290            let buffer_snapshot = buffer.read(cx).snapshot();
 5291            cx.spawn(async move |_, cx| {
 5292                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5293                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5294                );
 5295                let resolved_hint = resolve_task
 5296                    .await
 5297                    .into_response()
 5298                    .context("inlay hint resolve LSP request")?;
 5299                let resolved_hint = InlayHints::lsp_to_project_hint(
 5300                    resolved_hint,
 5301                    &buffer,
 5302                    server_id,
 5303                    ResolveState::Resolved,
 5304                    false,
 5305                    cx,
 5306                )
 5307                .await?;
 5308                Ok(resolved_hint)
 5309            })
 5310        }
 5311    }
 5312
 5313    pub fn resolve_color_presentation(
 5314        &mut self,
 5315        mut color: DocumentColor,
 5316        buffer: Entity<Buffer>,
 5317        server_id: LanguageServerId,
 5318        cx: &mut Context<Self>,
 5319    ) -> Task<Result<DocumentColor>> {
 5320        if color.resolved {
 5321            return Task::ready(Ok(color));
 5322        }
 5323
 5324        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5325            let start = color.lsp_range.start;
 5326            let end = color.lsp_range.end;
 5327            let request = proto::GetColorPresentation {
 5328                project_id,
 5329                server_id: server_id.to_proto(),
 5330                buffer_id: buffer.read(cx).remote_id().into(),
 5331                color: Some(proto::ColorInformation {
 5332                    red: color.color.red,
 5333                    green: color.color.green,
 5334                    blue: color.color.blue,
 5335                    alpha: color.color.alpha,
 5336                    lsp_range_start: Some(proto::PointUtf16 {
 5337                        row: start.line,
 5338                        column: start.character,
 5339                    }),
 5340                    lsp_range_end: Some(proto::PointUtf16 {
 5341                        row: end.line,
 5342                        column: end.character,
 5343                    }),
 5344                }),
 5345            };
 5346            cx.background_spawn(async move {
 5347                let response = upstream_client
 5348                    .request(request)
 5349                    .await
 5350                    .context("color presentation proto request")?;
 5351                color.resolved = true;
 5352                color.color_presentations = response
 5353                    .presentations
 5354                    .into_iter()
 5355                    .map(|presentation| ColorPresentation {
 5356                        label: SharedString::from(presentation.label),
 5357                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5358                        additional_text_edits: presentation
 5359                            .additional_text_edits
 5360                            .into_iter()
 5361                            .filter_map(deserialize_lsp_edit)
 5362                            .collect(),
 5363                    })
 5364                    .collect();
 5365                Ok(color)
 5366            })
 5367        } else {
 5368            let path = match buffer
 5369                .update(cx, |buffer, cx| {
 5370                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5371                })
 5372                .context("buffer with the missing path")
 5373            {
 5374                Ok(path) => path,
 5375                Err(e) => return Task::ready(Err(e)),
 5376            };
 5377            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5378                self.language_server_for_local_buffer(buffer, server_id, cx)
 5379                    .map(|(_, server)| server.clone())
 5380            }) else {
 5381                return Task::ready(Ok(color));
 5382            };
 5383            cx.background_spawn(async move {
 5384                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5385                    lsp::ColorPresentationParams {
 5386                        text_document: make_text_document_identifier(&path)?,
 5387                        color: color.color,
 5388                        range: color.lsp_range,
 5389                        work_done_progress_params: Default::default(),
 5390                        partial_result_params: Default::default(),
 5391                    },
 5392                );
 5393                color.color_presentations = resolve_task
 5394                    .await
 5395                    .into_response()
 5396                    .context("color presentation resolve LSP request")?
 5397                    .into_iter()
 5398                    .map(|presentation| ColorPresentation {
 5399                        label: SharedString::from(presentation.label),
 5400                        text_edit: presentation.text_edit,
 5401                        additional_text_edits: presentation
 5402                            .additional_text_edits
 5403                            .unwrap_or_default(),
 5404                    })
 5405                    .collect();
 5406                color.resolved = true;
 5407                Ok(color)
 5408            })
 5409        }
 5410    }
 5411
 5412    pub(crate) fn linked_edits(
 5413        &mut self,
 5414        buffer: &Entity<Buffer>,
 5415        position: Anchor,
 5416        cx: &mut Context<Self>,
 5417    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5418        let snapshot = buffer.read(cx).snapshot();
 5419        let scope = snapshot.language_scope_at(position);
 5420        let Some(server_id) = self
 5421            .as_local()
 5422            .and_then(|local| {
 5423                buffer.update(cx, |buffer, cx| {
 5424                    local
 5425                        .language_servers_for_buffer(buffer, cx)
 5426                        .filter(|(_, server)| {
 5427                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5428                        })
 5429                        .filter(|(adapter, _)| {
 5430                            scope
 5431                                .as_ref()
 5432                                .map(|scope| scope.language_allowed(&adapter.name))
 5433                                .unwrap_or(true)
 5434                        })
 5435                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5436                        .next()
 5437                })
 5438            })
 5439            .or_else(|| {
 5440                self.upstream_client()
 5441                    .is_some()
 5442                    .then_some(LanguageServerToQuery::FirstCapable)
 5443            })
 5444            .filter(|_| {
 5445                maybe!({
 5446                    let language = buffer.read(cx).language_at(position)?;
 5447                    Some(
 5448                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5449                            .linked_edits,
 5450                    )
 5451                }) == Some(true)
 5452            })
 5453        else {
 5454            return Task::ready(Ok(Vec::new()));
 5455        };
 5456
 5457        self.request_lsp(
 5458            buffer.clone(),
 5459            server_id,
 5460            LinkedEditingRange { position },
 5461            cx,
 5462        )
 5463    }
 5464
 5465    fn apply_on_type_formatting(
 5466        &mut self,
 5467        buffer: Entity<Buffer>,
 5468        position: Anchor,
 5469        trigger: String,
 5470        cx: &mut Context<Self>,
 5471    ) -> Task<Result<Option<Transaction>>> {
 5472        if let Some((client, project_id)) = self.upstream_client() {
 5473            if !self.check_if_capable_for_proto_request(
 5474                &buffer,
 5475                |capabilities| {
 5476                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5477                },
 5478                cx,
 5479            ) {
 5480                return Task::ready(Ok(None));
 5481            }
 5482            let request = proto::OnTypeFormatting {
 5483                project_id,
 5484                buffer_id: buffer.read(cx).remote_id().into(),
 5485                position: Some(serialize_anchor(&position)),
 5486                trigger,
 5487                version: serialize_version(&buffer.read(cx).version()),
 5488            };
 5489            cx.background_spawn(async move {
 5490                client
 5491                    .request(request)
 5492                    .await?
 5493                    .transaction
 5494                    .map(language::proto::deserialize_transaction)
 5495                    .transpose()
 5496            })
 5497        } else if let Some(local) = self.as_local_mut() {
 5498            let buffer_id = buffer.read(cx).remote_id();
 5499            local.buffers_being_formatted.insert(buffer_id);
 5500            cx.spawn(async move |this, cx| {
 5501                let _cleanup = defer({
 5502                    let this = this.clone();
 5503                    let mut cx = cx.clone();
 5504                    move || {
 5505                        this.update(&mut cx, |this, _| {
 5506                            if let Some(local) = this.as_local_mut() {
 5507                                local.buffers_being_formatted.remove(&buffer_id);
 5508                            }
 5509                        })
 5510                        .ok();
 5511                    }
 5512                });
 5513
 5514                buffer
 5515                    .update(cx, |buffer, _| {
 5516                        buffer.wait_for_edits(Some(position.timestamp))
 5517                    })
 5518                    .await?;
 5519                this.update(cx, |this, cx| {
 5520                    let position = position.to_point_utf16(buffer.read(cx));
 5521                    this.on_type_format(buffer, position, trigger, false, cx)
 5522                })?
 5523                .await
 5524            })
 5525        } else {
 5526            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5527        }
 5528    }
 5529
 5530    pub fn on_type_format<T: ToPointUtf16>(
 5531        &mut self,
 5532        buffer: Entity<Buffer>,
 5533        position: T,
 5534        trigger: String,
 5535        push_to_history: bool,
 5536        cx: &mut Context<Self>,
 5537    ) -> Task<Result<Option<Transaction>>> {
 5538        let position = position.to_point_utf16(buffer.read(cx));
 5539        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5540    }
 5541
 5542    fn on_type_format_impl(
 5543        &mut self,
 5544        buffer: Entity<Buffer>,
 5545        position: PointUtf16,
 5546        trigger: String,
 5547        push_to_history: bool,
 5548        cx: &mut Context<Self>,
 5549    ) -> Task<Result<Option<Transaction>>> {
 5550        let options = buffer.update(cx, |buffer, cx| {
 5551            lsp_command::lsp_formatting_options(
 5552                language_settings(
 5553                    buffer.language_at(position).map(|l| l.name()),
 5554                    buffer.file(),
 5555                    cx,
 5556                )
 5557                .as_ref(),
 5558            )
 5559        });
 5560
 5561        cx.spawn(async move |this, cx| {
 5562            if let Some(waiter) =
 5563                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5564            {
 5565                waiter.await?;
 5566            }
 5567            cx.update(|cx| {
 5568                this.update(cx, |this, cx| {
 5569                    this.request_lsp(
 5570                        buffer.clone(),
 5571                        LanguageServerToQuery::FirstCapable,
 5572                        OnTypeFormatting {
 5573                            position,
 5574                            trigger,
 5575                            options,
 5576                            push_to_history,
 5577                        },
 5578                        cx,
 5579                    )
 5580                })
 5581            })?
 5582            .await
 5583        })
 5584    }
 5585
 5586    pub fn definitions(
 5587        &mut self,
 5588        buffer: &Entity<Buffer>,
 5589        position: PointUtf16,
 5590        cx: &mut Context<Self>,
 5591    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5592        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5593            let request = GetDefinitions { position };
 5594            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5595                return Task::ready(Ok(None));
 5596            }
 5597            let request_task = upstream_client.request_lsp(
 5598                project_id,
 5599                None,
 5600                LSP_REQUEST_TIMEOUT,
 5601                cx.background_executor().clone(),
 5602                request.to_proto(project_id, buffer.read(cx)),
 5603            );
 5604            let buffer = buffer.clone();
 5605            cx.spawn(async move |weak_lsp_store, cx| {
 5606                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5607                    return Ok(None);
 5608                };
 5609                let Some(responses) = request_task.await? else {
 5610                    return Ok(None);
 5611                };
 5612                let actions = join_all(responses.payload.into_iter().map(|response| {
 5613                    GetDefinitions { position }.response_from_proto(
 5614                        response.response,
 5615                        lsp_store.clone(),
 5616                        buffer.clone(),
 5617                        cx.clone(),
 5618                    )
 5619                }))
 5620                .await;
 5621
 5622                Ok(Some(
 5623                    actions
 5624                        .into_iter()
 5625                        .collect::<Result<Vec<Vec<_>>>>()?
 5626                        .into_iter()
 5627                        .flatten()
 5628                        .dedup()
 5629                        .collect(),
 5630                ))
 5631            })
 5632        } else {
 5633            let definitions_task = self.request_multiple_lsp_locally(
 5634                buffer,
 5635                Some(position),
 5636                GetDefinitions { position },
 5637                cx,
 5638            );
 5639            cx.background_spawn(async move {
 5640                Ok(Some(
 5641                    definitions_task
 5642                        .await
 5643                        .into_iter()
 5644                        .flat_map(|(_, definitions)| definitions)
 5645                        .dedup()
 5646                        .collect(),
 5647                ))
 5648            })
 5649        }
 5650    }
 5651
 5652    pub fn declarations(
 5653        &mut self,
 5654        buffer: &Entity<Buffer>,
 5655        position: PointUtf16,
 5656        cx: &mut Context<Self>,
 5657    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5658        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5659            let request = GetDeclarations { position };
 5660            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5661                return Task::ready(Ok(None));
 5662            }
 5663            let request_task = upstream_client.request_lsp(
 5664                project_id,
 5665                None,
 5666                LSP_REQUEST_TIMEOUT,
 5667                cx.background_executor().clone(),
 5668                request.to_proto(project_id, buffer.read(cx)),
 5669            );
 5670            let buffer = buffer.clone();
 5671            cx.spawn(async move |weak_lsp_store, cx| {
 5672                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5673                    return Ok(None);
 5674                };
 5675                let Some(responses) = request_task.await? else {
 5676                    return Ok(None);
 5677                };
 5678                let actions = join_all(responses.payload.into_iter().map(|response| {
 5679                    GetDeclarations { position }.response_from_proto(
 5680                        response.response,
 5681                        lsp_store.clone(),
 5682                        buffer.clone(),
 5683                        cx.clone(),
 5684                    )
 5685                }))
 5686                .await;
 5687
 5688                Ok(Some(
 5689                    actions
 5690                        .into_iter()
 5691                        .collect::<Result<Vec<Vec<_>>>>()?
 5692                        .into_iter()
 5693                        .flatten()
 5694                        .dedup()
 5695                        .collect(),
 5696                ))
 5697            })
 5698        } else {
 5699            let declarations_task = self.request_multiple_lsp_locally(
 5700                buffer,
 5701                Some(position),
 5702                GetDeclarations { position },
 5703                cx,
 5704            );
 5705            cx.background_spawn(async move {
 5706                Ok(Some(
 5707                    declarations_task
 5708                        .await
 5709                        .into_iter()
 5710                        .flat_map(|(_, declarations)| declarations)
 5711                        .dedup()
 5712                        .collect(),
 5713                ))
 5714            })
 5715        }
 5716    }
 5717
 5718    pub fn type_definitions(
 5719        &mut self,
 5720        buffer: &Entity<Buffer>,
 5721        position: PointUtf16,
 5722        cx: &mut Context<Self>,
 5723    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5724        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5725            let request = GetTypeDefinitions { position };
 5726            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5727                return Task::ready(Ok(None));
 5728            }
 5729            let request_task = upstream_client.request_lsp(
 5730                project_id,
 5731                None,
 5732                LSP_REQUEST_TIMEOUT,
 5733                cx.background_executor().clone(),
 5734                request.to_proto(project_id, buffer.read(cx)),
 5735            );
 5736            let buffer = buffer.clone();
 5737            cx.spawn(async move |weak_lsp_store, cx| {
 5738                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5739                    return Ok(None);
 5740                };
 5741                let Some(responses) = request_task.await? else {
 5742                    return Ok(None);
 5743                };
 5744                let actions = join_all(responses.payload.into_iter().map(|response| {
 5745                    GetTypeDefinitions { position }.response_from_proto(
 5746                        response.response,
 5747                        lsp_store.clone(),
 5748                        buffer.clone(),
 5749                        cx.clone(),
 5750                    )
 5751                }))
 5752                .await;
 5753
 5754                Ok(Some(
 5755                    actions
 5756                        .into_iter()
 5757                        .collect::<Result<Vec<Vec<_>>>>()?
 5758                        .into_iter()
 5759                        .flatten()
 5760                        .dedup()
 5761                        .collect(),
 5762                ))
 5763            })
 5764        } else {
 5765            let type_definitions_task = self.request_multiple_lsp_locally(
 5766                buffer,
 5767                Some(position),
 5768                GetTypeDefinitions { position },
 5769                cx,
 5770            );
 5771            cx.background_spawn(async move {
 5772                Ok(Some(
 5773                    type_definitions_task
 5774                        .await
 5775                        .into_iter()
 5776                        .flat_map(|(_, type_definitions)| type_definitions)
 5777                        .dedup()
 5778                        .collect(),
 5779                ))
 5780            })
 5781        }
 5782    }
 5783
 5784    pub fn implementations(
 5785        &mut self,
 5786        buffer: &Entity<Buffer>,
 5787        position: PointUtf16,
 5788        cx: &mut Context<Self>,
 5789    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5790        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5791            let request = GetImplementations { position };
 5792            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5793                return Task::ready(Ok(None));
 5794            }
 5795            let request_task = upstream_client.request_lsp(
 5796                project_id,
 5797                None,
 5798                LSP_REQUEST_TIMEOUT,
 5799                cx.background_executor().clone(),
 5800                request.to_proto(project_id, buffer.read(cx)),
 5801            );
 5802            let buffer = buffer.clone();
 5803            cx.spawn(async move |weak_lsp_store, cx| {
 5804                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5805                    return Ok(None);
 5806                };
 5807                let Some(responses) = request_task.await? else {
 5808                    return Ok(None);
 5809                };
 5810                let actions = join_all(responses.payload.into_iter().map(|response| {
 5811                    GetImplementations { position }.response_from_proto(
 5812                        response.response,
 5813                        lsp_store.clone(),
 5814                        buffer.clone(),
 5815                        cx.clone(),
 5816                    )
 5817                }))
 5818                .await;
 5819
 5820                Ok(Some(
 5821                    actions
 5822                        .into_iter()
 5823                        .collect::<Result<Vec<Vec<_>>>>()?
 5824                        .into_iter()
 5825                        .flatten()
 5826                        .dedup()
 5827                        .collect(),
 5828                ))
 5829            })
 5830        } else {
 5831            let implementations_task = self.request_multiple_lsp_locally(
 5832                buffer,
 5833                Some(position),
 5834                GetImplementations { position },
 5835                cx,
 5836            );
 5837            cx.background_spawn(async move {
 5838                Ok(Some(
 5839                    implementations_task
 5840                        .await
 5841                        .into_iter()
 5842                        .flat_map(|(_, implementations)| implementations)
 5843                        .dedup()
 5844                        .collect(),
 5845                ))
 5846            })
 5847        }
 5848    }
 5849
 5850    pub fn references(
 5851        &mut self,
 5852        buffer: &Entity<Buffer>,
 5853        position: PointUtf16,
 5854        cx: &mut Context<Self>,
 5855    ) -> Task<Result<Option<Vec<Location>>>> {
 5856        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5857            let request = GetReferences { position };
 5858            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5859                return Task::ready(Ok(None));
 5860            }
 5861
 5862            let request_task = upstream_client.request_lsp(
 5863                project_id,
 5864                None,
 5865                LSP_REQUEST_TIMEOUT,
 5866                cx.background_executor().clone(),
 5867                request.to_proto(project_id, buffer.read(cx)),
 5868            );
 5869            let buffer = buffer.clone();
 5870            cx.spawn(async move |weak_lsp_store, cx| {
 5871                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5872                    return Ok(None);
 5873                };
 5874                let Some(responses) = request_task.await? else {
 5875                    return Ok(None);
 5876                };
 5877
 5878                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5879                    GetReferences { position }.response_from_proto(
 5880                        lsp_response.response,
 5881                        lsp_store.clone(),
 5882                        buffer.clone(),
 5883                        cx.clone(),
 5884                    )
 5885                }))
 5886                .await
 5887                .into_iter()
 5888                .collect::<Result<Vec<Vec<_>>>>()?
 5889                .into_iter()
 5890                .flatten()
 5891                .dedup()
 5892                .collect();
 5893                Ok(Some(locations))
 5894            })
 5895        } else {
 5896            let references_task = self.request_multiple_lsp_locally(
 5897                buffer,
 5898                Some(position),
 5899                GetReferences { position },
 5900                cx,
 5901            );
 5902            cx.background_spawn(async move {
 5903                Ok(Some(
 5904                    references_task
 5905                        .await
 5906                        .into_iter()
 5907                        .flat_map(|(_, references)| references)
 5908                        .dedup()
 5909                        .collect(),
 5910                ))
 5911            })
 5912        }
 5913    }
 5914
 5915    pub fn code_actions(
 5916        &mut self,
 5917        buffer: &Entity<Buffer>,
 5918        range: Range<Anchor>,
 5919        kinds: Option<Vec<CodeActionKind>>,
 5920        cx: &mut Context<Self>,
 5921    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5922        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5923            let request = GetCodeActions {
 5924                range: range.clone(),
 5925                kinds: kinds.clone(),
 5926            };
 5927            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5928                return Task::ready(Ok(None));
 5929            }
 5930            let request_task = upstream_client.request_lsp(
 5931                project_id,
 5932                None,
 5933                LSP_REQUEST_TIMEOUT,
 5934                cx.background_executor().clone(),
 5935                request.to_proto(project_id, buffer.read(cx)),
 5936            );
 5937            let buffer = buffer.clone();
 5938            cx.spawn(async move |weak_lsp_store, cx| {
 5939                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5940                    return Ok(None);
 5941                };
 5942                let Some(responses) = request_task.await? else {
 5943                    return Ok(None);
 5944                };
 5945                let actions = join_all(responses.payload.into_iter().map(|response| {
 5946                    GetCodeActions {
 5947                        range: range.clone(),
 5948                        kinds: kinds.clone(),
 5949                    }
 5950                    .response_from_proto(
 5951                        response.response,
 5952                        lsp_store.clone(),
 5953                        buffer.clone(),
 5954                        cx.clone(),
 5955                    )
 5956                }))
 5957                .await;
 5958
 5959                Ok(Some(
 5960                    actions
 5961                        .into_iter()
 5962                        .collect::<Result<Vec<Vec<_>>>>()?
 5963                        .into_iter()
 5964                        .flatten()
 5965                        .collect(),
 5966                ))
 5967            })
 5968        } else {
 5969            let all_actions_task = self.request_multiple_lsp_locally(
 5970                buffer,
 5971                Some(range.start),
 5972                GetCodeActions { range, kinds },
 5973                cx,
 5974            );
 5975            cx.background_spawn(async move {
 5976                Ok(Some(
 5977                    all_actions_task
 5978                        .await
 5979                        .into_iter()
 5980                        .flat_map(|(_, actions)| actions)
 5981                        .collect(),
 5982                ))
 5983            })
 5984        }
 5985    }
 5986
 5987    pub fn code_lens_actions(
 5988        &mut self,
 5989        buffer: &Entity<Buffer>,
 5990        cx: &mut Context<Self>,
 5991    ) -> CodeLensTask {
 5992        let version_queried_for = buffer.read(cx).version();
 5993        let buffer_id = buffer.read(cx).remote_id();
 5994        let existing_servers = self.as_local().map(|local| {
 5995            local
 5996                .buffers_opened_in_servers
 5997                .get(&buffer_id)
 5998                .cloned()
 5999                .unwrap_or_default()
 6000        });
 6001
 6002        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 6003            if let Some(cached_lens) = &lsp_data.code_lens {
 6004                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 6005                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 6006                        existing_servers != cached_lens.lens.keys().copied().collect()
 6007                    });
 6008                    if !has_different_servers {
 6009                        return Task::ready(Ok(Some(
 6010                            cached_lens.lens.values().flatten().cloned().collect(),
 6011                        )))
 6012                        .shared();
 6013                    }
 6014                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 6015                    if !version_queried_for.changed_since(updating_for) {
 6016                        return running_update.clone();
 6017                    }
 6018                }
 6019            }
 6020        }
 6021
 6022        let lens_lsp_data = self
 6023            .latest_lsp_data(buffer, cx)
 6024            .code_lens
 6025            .get_or_insert_default();
 6026        let buffer = buffer.clone();
 6027        let query_version_queried_for = version_queried_for.clone();
 6028        let new_task = cx
 6029            .spawn(async move |lsp_store, cx| {
 6030                cx.background_executor()
 6031                    .timer(Duration::from_millis(30))
 6032                    .await;
 6033                let fetched_lens = lsp_store
 6034                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 6035                    .map_err(Arc::new)?
 6036                    .await
 6037                    .context("fetching code lens")
 6038                    .map_err(Arc::new);
 6039                let fetched_lens = match fetched_lens {
 6040                    Ok(fetched_lens) => fetched_lens,
 6041                    Err(e) => {
 6042                        lsp_store
 6043                            .update(cx, |lsp_store, _| {
 6044                                if let Some(lens_lsp_data) = lsp_store
 6045                                    .lsp_data
 6046                                    .get_mut(&buffer_id)
 6047                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 6048                                {
 6049                                    lens_lsp_data.update = None;
 6050                                }
 6051                            })
 6052                            .ok();
 6053                        return Err(e);
 6054                    }
 6055                };
 6056
 6057                lsp_store
 6058                    .update(cx, |lsp_store, _| {
 6059                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 6060                        let code_lens = lsp_data.code_lens.as_mut()?;
 6061                        if let Some(fetched_lens) = fetched_lens {
 6062                            if lsp_data.buffer_version == query_version_queried_for {
 6063                                code_lens.lens.extend(fetched_lens);
 6064                            } else if !lsp_data
 6065                                .buffer_version
 6066                                .changed_since(&query_version_queried_for)
 6067                            {
 6068                                lsp_data.buffer_version = query_version_queried_for;
 6069                                code_lens.lens = fetched_lens;
 6070                            }
 6071                        }
 6072                        code_lens.update = None;
 6073                        Some(code_lens.lens.values().flatten().cloned().collect())
 6074                    })
 6075                    .map_err(Arc::new)
 6076            })
 6077            .shared();
 6078        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 6079        new_task
 6080    }
 6081
 6082    fn fetch_code_lens(
 6083        &mut self,
 6084        buffer: &Entity<Buffer>,
 6085        cx: &mut Context<Self>,
 6086    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 6087        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6088            let request = GetCodeLens;
 6089            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6090                return Task::ready(Ok(None));
 6091            }
 6092            let request_task = upstream_client.request_lsp(
 6093                project_id,
 6094                None,
 6095                LSP_REQUEST_TIMEOUT,
 6096                cx.background_executor().clone(),
 6097                request.to_proto(project_id, buffer.read(cx)),
 6098            );
 6099            let buffer = buffer.clone();
 6100            cx.spawn(async move |weak_lsp_store, cx| {
 6101                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6102                    return Ok(None);
 6103                };
 6104                let Some(responses) = request_task.await? else {
 6105                    return Ok(None);
 6106                };
 6107
 6108                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 6109                    let lsp_store = lsp_store.clone();
 6110                    let buffer = buffer.clone();
 6111                    let cx = cx.clone();
 6112                    async move {
 6113                        (
 6114                            LanguageServerId::from_proto(response.server_id),
 6115                            GetCodeLens
 6116                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6117                                .await,
 6118                        )
 6119                    }
 6120                }))
 6121                .await;
 6122
 6123                let mut has_errors = false;
 6124                let code_lens_actions = code_lens_actions
 6125                    .into_iter()
 6126                    .filter_map(|(server_id, code_lens)| match code_lens {
 6127                        Ok(code_lens) => Some((server_id, code_lens)),
 6128                        Err(e) => {
 6129                            has_errors = true;
 6130                            log::error!("{e:#}");
 6131                            None
 6132                        }
 6133                    })
 6134                    .collect::<HashMap<_, _>>();
 6135                anyhow::ensure!(
 6136                    !has_errors || !code_lens_actions.is_empty(),
 6137                    "Failed to fetch code lens"
 6138                );
 6139                Ok(Some(code_lens_actions))
 6140            })
 6141        } else {
 6142            let code_lens_actions_task =
 6143                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 6144            cx.background_spawn(async move {
 6145                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 6146            })
 6147        }
 6148    }
 6149
 6150    #[inline(never)]
 6151    pub fn completions(
 6152        &self,
 6153        buffer: &Entity<Buffer>,
 6154        position: PointUtf16,
 6155        context: CompletionContext,
 6156        cx: &mut Context<Self>,
 6157    ) -> Task<Result<Vec<CompletionResponse>>> {
 6158        let language_registry = self.languages.clone();
 6159
 6160        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6161            let snapshot = buffer.read(cx).snapshot();
 6162            let offset = position.to_offset(&snapshot);
 6163            let scope = snapshot.language_scope_at(offset);
 6164            let capable_lsps = self.all_capable_for_proto_request(
 6165                buffer,
 6166                |server_name, capabilities| {
 6167                    capabilities.completion_provider.is_some()
 6168                        && scope
 6169                            .as_ref()
 6170                            .map(|scope| scope.language_allowed(server_name))
 6171                            .unwrap_or(true)
 6172                },
 6173                cx,
 6174            );
 6175            if capable_lsps.is_empty() {
 6176                return Task::ready(Ok(Vec::new()));
 6177            }
 6178
 6179            let language = buffer.read(cx).language().cloned();
 6180
 6181            // In the future, we should provide project guests with the names of LSP adapters,
 6182            // so that they can use the correct LSP adapter when computing labels. For now,
 6183            // guests just use the first LSP adapter associated with the buffer's language.
 6184            let lsp_adapter = language.as_ref().and_then(|language| {
 6185                language_registry
 6186                    .lsp_adapters(&language.name())
 6187                    .first()
 6188                    .cloned()
 6189            });
 6190
 6191            let buffer = buffer.clone();
 6192
 6193            cx.spawn(async move |this, cx| {
 6194                let requests = join_all(
 6195                    capable_lsps
 6196                        .into_iter()
 6197                        .map(|id| {
 6198                            let request = GetCompletions {
 6199                                position,
 6200                                context: context.clone(),
 6201                                server_id: Some(id),
 6202                            };
 6203                            let buffer = buffer.clone();
 6204                            let language = language.clone();
 6205                            let lsp_adapter = lsp_adapter.clone();
 6206                            let upstream_client = upstream_client.clone();
 6207                            let response = this
 6208                                .update(cx, |this, cx| {
 6209                                    this.send_lsp_proto_request(
 6210                                        buffer,
 6211                                        upstream_client,
 6212                                        project_id,
 6213                                        request,
 6214                                        cx,
 6215                                    )
 6216                                })
 6217                                .log_err();
 6218                            async move {
 6219                                let response = response?.await.log_err()?;
 6220
 6221                                let completions = populate_labels_for_completions(
 6222                                    response.completions,
 6223                                    language,
 6224                                    lsp_adapter,
 6225                                )
 6226                                .await;
 6227
 6228                                Some(CompletionResponse {
 6229                                    completions,
 6230                                    display_options: CompletionDisplayOptions::default(),
 6231                                    is_incomplete: response.is_incomplete,
 6232                                })
 6233                            }
 6234                        })
 6235                        .collect::<Vec<_>>(),
 6236                );
 6237                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6238            })
 6239        } else if let Some(local) = self.as_local() {
 6240            let snapshot = buffer.read(cx).snapshot();
 6241            let offset = position.to_offset(&snapshot);
 6242            let scope = snapshot.language_scope_at(offset);
 6243            let language = snapshot.language().cloned();
 6244            let completion_settings = language_settings(
 6245                language.as_ref().map(|language| language.name()),
 6246                buffer.read(cx).file(),
 6247                cx,
 6248            )
 6249            .completions
 6250            .clone();
 6251            if !completion_settings.lsp {
 6252                return Task::ready(Ok(Vec::new()));
 6253            }
 6254
 6255            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6256                local
 6257                    .language_servers_for_buffer(buffer, cx)
 6258                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6259                    .filter(|(adapter, _)| {
 6260                        scope
 6261                            .as_ref()
 6262                            .map(|scope| scope.language_allowed(&adapter.name))
 6263                            .unwrap_or(true)
 6264                    })
 6265                    .map(|(_, server)| server.server_id())
 6266                    .collect()
 6267            });
 6268
 6269            let buffer = buffer.clone();
 6270            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6271            let lsp_timeout = if lsp_timeout > 0 {
 6272                Some(Duration::from_millis(lsp_timeout))
 6273            } else {
 6274                None
 6275            };
 6276            cx.spawn(async move |this,  cx| {
 6277                let mut tasks = Vec::with_capacity(server_ids.len());
 6278                this.update(cx, |lsp_store, cx| {
 6279                    for server_id in server_ids {
 6280                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6281                        let lsp_timeout = lsp_timeout
 6282                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6283                        let mut timeout = cx.background_spawn(async move {
 6284                            match lsp_timeout {
 6285                                Some(lsp_timeout) => {
 6286                                    lsp_timeout.await;
 6287                                    true
 6288                                },
 6289                                None => false,
 6290                            }
 6291                        }).fuse();
 6292                        let mut lsp_request = lsp_store.request_lsp(
 6293                            buffer.clone(),
 6294                            LanguageServerToQuery::Other(server_id),
 6295                            GetCompletions {
 6296                                position,
 6297                                context: context.clone(),
 6298                                server_id: Some(server_id),
 6299                            },
 6300                            cx,
 6301                        ).fuse();
 6302                        let new_task = cx.background_spawn(async move {
 6303                            select_biased! {
 6304                                response = lsp_request => anyhow::Ok(Some(response?)),
 6305                                timeout_happened = timeout => {
 6306                                    if timeout_happened {
 6307                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6308                                        Ok(None)
 6309                                    } else {
 6310                                        let completions = lsp_request.await?;
 6311                                        Ok(Some(completions))
 6312                                    }
 6313                                },
 6314                            }
 6315                        });
 6316                        tasks.push((lsp_adapter, new_task));
 6317                    }
 6318                })?;
 6319
 6320                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6321                    let completion_response = task.await.ok()??;
 6322                    let completions = populate_labels_for_completions(
 6323                            completion_response.completions,
 6324                            language.clone(),
 6325                            lsp_adapter,
 6326                        )
 6327                        .await;
 6328                    Some(CompletionResponse {
 6329                        completions,
 6330                        display_options: CompletionDisplayOptions::default(),
 6331                        is_incomplete: completion_response.is_incomplete,
 6332                    })
 6333                });
 6334
 6335                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6336
 6337                Ok(responses.into_iter().flatten().collect())
 6338            })
 6339        } else {
 6340            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6341        }
 6342    }
 6343
 6344    pub fn resolve_completions(
 6345        &self,
 6346        buffer: Entity<Buffer>,
 6347        completion_indices: Vec<usize>,
 6348        completions: Rc<RefCell<Box<[Completion]>>>,
 6349        cx: &mut Context<Self>,
 6350    ) -> Task<Result<bool>> {
 6351        let client = self.upstream_client();
 6352        let buffer_id = buffer.read(cx).remote_id();
 6353        let buffer_snapshot = buffer.read(cx).snapshot();
 6354
 6355        if !self.check_if_capable_for_proto_request(
 6356            &buffer,
 6357            GetCompletions::can_resolve_completions,
 6358            cx,
 6359        ) {
 6360            return Task::ready(Ok(false));
 6361        }
 6362        cx.spawn(async move |lsp_store, cx| {
 6363            let mut did_resolve = false;
 6364            if let Some((client, project_id)) = client {
 6365                for completion_index in completion_indices {
 6366                    let server_id = {
 6367                        let completion = &completions.borrow()[completion_index];
 6368                        completion.source.server_id()
 6369                    };
 6370                    if let Some(server_id) = server_id {
 6371                        if Self::resolve_completion_remote(
 6372                            project_id,
 6373                            server_id,
 6374                            buffer_id,
 6375                            completions.clone(),
 6376                            completion_index,
 6377                            client.clone(),
 6378                        )
 6379                        .await
 6380                        .log_err()
 6381                        .is_some()
 6382                        {
 6383                            did_resolve = true;
 6384                        }
 6385                    } else {
 6386                        resolve_word_completion(
 6387                            &buffer_snapshot,
 6388                            &mut completions.borrow_mut()[completion_index],
 6389                        );
 6390                    }
 6391                }
 6392            } else {
 6393                for completion_index in completion_indices {
 6394                    let server_id = {
 6395                        let completion = &completions.borrow()[completion_index];
 6396                        completion.source.server_id()
 6397                    };
 6398                    if let Some(server_id) = server_id {
 6399                        let server_and_adapter = lsp_store
 6400                            .read_with(cx, |lsp_store, _| {
 6401                                let server = lsp_store.language_server_for_id(server_id)?;
 6402                                let adapter =
 6403                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6404                                Some((server, adapter))
 6405                            })
 6406                            .ok()
 6407                            .flatten();
 6408                        let Some((server, adapter)) = server_and_adapter else {
 6409                            continue;
 6410                        };
 6411
 6412                        let resolved = Self::resolve_completion_local(
 6413                            server,
 6414                            completions.clone(),
 6415                            completion_index,
 6416                        )
 6417                        .await
 6418                        .log_err()
 6419                        .is_some();
 6420                        if resolved {
 6421                            Self::regenerate_completion_labels(
 6422                                adapter,
 6423                                &buffer_snapshot,
 6424                                completions.clone(),
 6425                                completion_index,
 6426                            )
 6427                            .await
 6428                            .log_err();
 6429                            did_resolve = true;
 6430                        }
 6431                    } else {
 6432                        resolve_word_completion(
 6433                            &buffer_snapshot,
 6434                            &mut completions.borrow_mut()[completion_index],
 6435                        );
 6436                    }
 6437                }
 6438            }
 6439
 6440            Ok(did_resolve)
 6441        })
 6442    }
 6443
 6444    async fn resolve_completion_local(
 6445        server: Arc<lsp::LanguageServer>,
 6446        completions: Rc<RefCell<Box<[Completion]>>>,
 6447        completion_index: usize,
 6448    ) -> Result<()> {
 6449        let server_id = server.server_id();
 6450        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6451            return Ok(());
 6452        }
 6453
 6454        let request = {
 6455            let completion = &completions.borrow()[completion_index];
 6456            match &completion.source {
 6457                CompletionSource::Lsp {
 6458                    lsp_completion,
 6459                    resolved,
 6460                    server_id: completion_server_id,
 6461                    ..
 6462                } => {
 6463                    if *resolved {
 6464                        return Ok(());
 6465                    }
 6466                    anyhow::ensure!(
 6467                        server_id == *completion_server_id,
 6468                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6469                    );
 6470                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6471                }
 6472                CompletionSource::BufferWord { .. }
 6473                | CompletionSource::Dap { .. }
 6474                | CompletionSource::Custom => {
 6475                    return Ok(());
 6476                }
 6477            }
 6478        };
 6479        let resolved_completion = request
 6480            .await
 6481            .into_response()
 6482            .context("resolve completion")?;
 6483
 6484        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6485        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6486
 6487        let mut completions = completions.borrow_mut();
 6488        let completion = &mut completions[completion_index];
 6489        if let CompletionSource::Lsp {
 6490            lsp_completion,
 6491            resolved,
 6492            server_id: completion_server_id,
 6493            ..
 6494        } = &mut completion.source
 6495        {
 6496            if *resolved {
 6497                return Ok(());
 6498            }
 6499            anyhow::ensure!(
 6500                server_id == *completion_server_id,
 6501                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6502            );
 6503            **lsp_completion = resolved_completion;
 6504            *resolved = true;
 6505        }
 6506        Ok(())
 6507    }
 6508
 6509    async fn regenerate_completion_labels(
 6510        adapter: Arc<CachedLspAdapter>,
 6511        snapshot: &BufferSnapshot,
 6512        completions: Rc<RefCell<Box<[Completion]>>>,
 6513        completion_index: usize,
 6514    ) -> Result<()> {
 6515        let completion_item = completions.borrow()[completion_index]
 6516            .source
 6517            .lsp_completion(true)
 6518            .map(Cow::into_owned);
 6519        if let Some(lsp_documentation) = completion_item
 6520            .as_ref()
 6521            .and_then(|completion_item| completion_item.documentation.clone())
 6522        {
 6523            let mut completions = completions.borrow_mut();
 6524            let completion = &mut completions[completion_index];
 6525            completion.documentation = Some(lsp_documentation.into());
 6526        } else {
 6527            let mut completions = completions.borrow_mut();
 6528            let completion = &mut completions[completion_index];
 6529            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6530        }
 6531
 6532        let mut new_label = match completion_item {
 6533            Some(completion_item) => {
 6534                // Some language servers always return `detail` lazily via resolve, regardless of
 6535                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6536                // See: https://github.com/yioneko/vtsls/issues/213
 6537                let language = snapshot.language();
 6538                match language {
 6539                    Some(language) => {
 6540                        adapter
 6541                            .labels_for_completions(
 6542                                std::slice::from_ref(&completion_item),
 6543                                language,
 6544                            )
 6545                            .await?
 6546                    }
 6547                    None => Vec::new(),
 6548                }
 6549                .pop()
 6550                .flatten()
 6551                .unwrap_or_else(|| {
 6552                    CodeLabel::fallback_for_completion(
 6553                        &completion_item,
 6554                        language.map(|language| language.as_ref()),
 6555                    )
 6556                })
 6557            }
 6558            None => CodeLabel::plain(
 6559                completions.borrow()[completion_index].new_text.clone(),
 6560                None,
 6561            ),
 6562        };
 6563        ensure_uniform_list_compatible_label(&mut new_label);
 6564
 6565        let mut completions = completions.borrow_mut();
 6566        let completion = &mut completions[completion_index];
 6567        if completion.label.filter_text() == new_label.filter_text() {
 6568            completion.label = new_label;
 6569        } else {
 6570            log::error!(
 6571                "Resolved completion changed display label from {} to {}. \
 6572                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6573                completion.label.text(),
 6574                new_label.text(),
 6575                completion.label.filter_text(),
 6576                new_label.filter_text()
 6577            );
 6578        }
 6579
 6580        Ok(())
 6581    }
 6582
 6583    async fn resolve_completion_remote(
 6584        project_id: u64,
 6585        server_id: LanguageServerId,
 6586        buffer_id: BufferId,
 6587        completions: Rc<RefCell<Box<[Completion]>>>,
 6588        completion_index: usize,
 6589        client: AnyProtoClient,
 6590    ) -> Result<()> {
 6591        let lsp_completion = {
 6592            let completion = &completions.borrow()[completion_index];
 6593            match &completion.source {
 6594                CompletionSource::Lsp {
 6595                    lsp_completion,
 6596                    resolved,
 6597                    server_id: completion_server_id,
 6598                    ..
 6599                } => {
 6600                    anyhow::ensure!(
 6601                        server_id == *completion_server_id,
 6602                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6603                    );
 6604                    if *resolved {
 6605                        return Ok(());
 6606                    }
 6607                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6608                }
 6609                CompletionSource::Custom
 6610                | CompletionSource::Dap { .. }
 6611                | CompletionSource::BufferWord { .. } => {
 6612                    return Ok(());
 6613                }
 6614            }
 6615        };
 6616        let request = proto::ResolveCompletionDocumentation {
 6617            project_id,
 6618            language_server_id: server_id.0 as u64,
 6619            lsp_completion,
 6620            buffer_id: buffer_id.into(),
 6621        };
 6622
 6623        let response = client
 6624            .request(request)
 6625            .await
 6626            .context("completion documentation resolve proto request")?;
 6627        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6628
 6629        let documentation = if response.documentation.is_empty() {
 6630            CompletionDocumentation::Undocumented
 6631        } else if response.documentation_is_markdown {
 6632            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6633        } else if response.documentation.lines().count() <= 1 {
 6634            CompletionDocumentation::SingleLine(response.documentation.into())
 6635        } else {
 6636            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6637        };
 6638
 6639        let mut completions = completions.borrow_mut();
 6640        let completion = &mut completions[completion_index];
 6641        completion.documentation = Some(documentation);
 6642        if let CompletionSource::Lsp {
 6643            insert_range,
 6644            lsp_completion,
 6645            resolved,
 6646            server_id: completion_server_id,
 6647            lsp_defaults: _,
 6648        } = &mut completion.source
 6649        {
 6650            let completion_insert_range = response
 6651                .old_insert_start
 6652                .and_then(deserialize_anchor)
 6653                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6654            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6655
 6656            if *resolved {
 6657                return Ok(());
 6658            }
 6659            anyhow::ensure!(
 6660                server_id == *completion_server_id,
 6661                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6662            );
 6663            **lsp_completion = resolved_lsp_completion;
 6664            *resolved = true;
 6665        }
 6666
 6667        let replace_range = response
 6668            .old_replace_start
 6669            .and_then(deserialize_anchor)
 6670            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6671        if let Some((old_replace_start, old_replace_end)) = replace_range
 6672            && !response.new_text.is_empty()
 6673        {
 6674            completion.new_text = response.new_text;
 6675            completion.replace_range = old_replace_start..old_replace_end;
 6676        }
 6677
 6678        Ok(())
 6679    }
 6680
 6681    pub fn apply_additional_edits_for_completion(
 6682        &self,
 6683        buffer_handle: Entity<Buffer>,
 6684        completions: Rc<RefCell<Box<[Completion]>>>,
 6685        completion_index: usize,
 6686        push_to_history: bool,
 6687        cx: &mut Context<Self>,
 6688    ) -> Task<Result<Option<Transaction>>> {
 6689        if let Some((client, project_id)) = self.upstream_client() {
 6690            let buffer = buffer_handle.read(cx);
 6691            let buffer_id = buffer.remote_id();
 6692            cx.spawn(async move |_, cx| {
 6693                let request = {
 6694                    let completion = completions.borrow()[completion_index].clone();
 6695                    proto::ApplyCompletionAdditionalEdits {
 6696                        project_id,
 6697                        buffer_id: buffer_id.into(),
 6698                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6699                            replace_range: completion.replace_range,
 6700                            new_text: completion.new_text,
 6701                            source: completion.source,
 6702                        })),
 6703                    }
 6704                };
 6705
 6706                if let Some(transaction) = client.request(request).await?.transaction {
 6707                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6708                    buffer_handle
 6709                        .update(cx, |buffer, _| {
 6710                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6711                        })
 6712                        .await?;
 6713                    if push_to_history {
 6714                        buffer_handle.update(cx, |buffer, _| {
 6715                            buffer.push_transaction(transaction.clone(), Instant::now());
 6716                            buffer.finalize_last_transaction();
 6717                        });
 6718                    }
 6719                    Ok(Some(transaction))
 6720                } else {
 6721                    Ok(None)
 6722                }
 6723            })
 6724        } else {
 6725            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6726                let completion = &completions.borrow()[completion_index];
 6727                let server_id = completion.source.server_id()?;
 6728                Some(
 6729                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6730                        .1
 6731                        .clone(),
 6732                )
 6733            }) else {
 6734                return Task::ready(Ok(None));
 6735            };
 6736
 6737            cx.spawn(async move |this, cx| {
 6738                Self::resolve_completion_local(
 6739                    server.clone(),
 6740                    completions.clone(),
 6741                    completion_index,
 6742                )
 6743                .await
 6744                .context("resolving completion")?;
 6745                let completion = completions.borrow()[completion_index].clone();
 6746                let additional_text_edits = completion
 6747                    .source
 6748                    .lsp_completion(true)
 6749                    .as_ref()
 6750                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6751                if let Some(edits) = additional_text_edits {
 6752                    let edits = this
 6753                        .update(cx, |this, cx| {
 6754                            this.as_local_mut().unwrap().edits_from_lsp(
 6755                                &buffer_handle,
 6756                                edits,
 6757                                server.server_id(),
 6758                                None,
 6759                                cx,
 6760                            )
 6761                        })?
 6762                        .await?;
 6763
 6764                    buffer_handle.update(cx, |buffer, cx| {
 6765                        buffer.finalize_last_transaction();
 6766                        buffer.start_transaction();
 6767
 6768                        for (range, text) in edits {
 6769                            let primary = &completion.replace_range;
 6770
 6771                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6772                            // and the primary completion is just an insertion (empty range), then this is likely
 6773                            // an auto-import scenario and should not be considered overlapping
 6774                            // https://github.com/zed-industries/zed/issues/26136
 6775                            let is_file_start_auto_import = {
 6776                                let snapshot = buffer.snapshot();
 6777                                let primary_start_point = primary.start.to_point(&snapshot);
 6778                                let range_start_point = range.start.to_point(&snapshot);
 6779
 6780                                let result = primary_start_point.row == 0
 6781                                    && primary_start_point.column == 0
 6782                                    && range_start_point.row == 0
 6783                                    && range_start_point.column == 0;
 6784
 6785                                result
 6786                            };
 6787
 6788                            let has_overlap = if is_file_start_auto_import {
 6789                                false
 6790                            } else {
 6791                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6792                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6793                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6794                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6795                                let result = start_within || end_within;
 6796                                result
 6797                            };
 6798
 6799                            //Skip additional edits which overlap with the primary completion edit
 6800                            //https://github.com/zed-industries/zed/pull/1871
 6801                            if !has_overlap {
 6802                                buffer.edit([(range, text)], None, cx);
 6803                            }
 6804                        }
 6805
 6806                        let transaction = if buffer.end_transaction(cx).is_some() {
 6807                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6808                            if !push_to_history {
 6809                                buffer.forget_transaction(transaction.id);
 6810                            }
 6811                            Some(transaction)
 6812                        } else {
 6813                            None
 6814                        };
 6815                        Ok(transaction)
 6816                    })
 6817                } else {
 6818                    Ok(None)
 6819                }
 6820            })
 6821        }
 6822    }
 6823
 6824    pub fn pull_diagnostics(
 6825        &mut self,
 6826        buffer: Entity<Buffer>,
 6827        cx: &mut Context<Self>,
 6828    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6829        let buffer_id = buffer.read(cx).remote_id();
 6830
 6831        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6832            let mut suitable_capabilities = None;
 6833            // Are we capable for proto request?
 6834            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6835                &buffer,
 6836                |capabilities| {
 6837                    if let Some(caps) = &capabilities.diagnostic_provider {
 6838                        suitable_capabilities = Some(caps.clone());
 6839                        true
 6840                    } else {
 6841                        false
 6842                    }
 6843                },
 6844                cx,
 6845            );
 6846            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6847            let Some(dynamic_caps) = suitable_capabilities else {
 6848                return Task::ready(Ok(None));
 6849            };
 6850            assert!(any_server_has_diagnostics_provider);
 6851
 6852            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6853            let request = GetDocumentDiagnostics {
 6854                previous_result_id: None,
 6855                identifier,
 6856                registration_id: None,
 6857            };
 6858            let request_task = client.request_lsp(
 6859                upstream_project_id,
 6860                None,
 6861                LSP_REQUEST_TIMEOUT,
 6862                cx.background_executor().clone(),
 6863                request.to_proto(upstream_project_id, buffer.read(cx)),
 6864            );
 6865            cx.background_spawn(async move {
 6866                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6867                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6868                // Do not attempt to further process the dummy responses here.
 6869                let _response = request_task.await?;
 6870                Ok(None)
 6871            })
 6872        } else {
 6873            let servers = buffer.update(cx, |buffer, cx| {
 6874                self.running_language_servers_for_local_buffer(buffer, cx)
 6875                    .map(|(_, server)| server.clone())
 6876                    .collect::<Vec<_>>()
 6877            });
 6878
 6879            let pull_diagnostics = servers
 6880                .into_iter()
 6881                .flat_map(|server| {
 6882                    let result = maybe!({
 6883                        let local = self.as_local()?;
 6884                        let server_id = server.server_id();
 6885                        let providers_with_identifiers = local
 6886                            .language_server_dynamic_registrations
 6887                            .get(&server_id)
 6888                            .into_iter()
 6889                            .flat_map(|registrations| registrations.diagnostics.clone())
 6890                            .collect::<Vec<_>>();
 6891                        Some(
 6892                            providers_with_identifiers
 6893                                .into_iter()
 6894                                .map(|(registration_id, dynamic_caps)| {
 6895                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6896                                    let registration_id = registration_id.map(SharedString::from);
 6897                                    let result_id = self.result_id_for_buffer_pull(
 6898                                        server_id,
 6899                                        buffer_id,
 6900                                        &registration_id,
 6901                                        cx,
 6902                                    );
 6903                                    self.request_lsp(
 6904                                        buffer.clone(),
 6905                                        LanguageServerToQuery::Other(server_id),
 6906                                        GetDocumentDiagnostics {
 6907                                            previous_result_id: result_id,
 6908                                            registration_id,
 6909                                            identifier,
 6910                                        },
 6911                                        cx,
 6912                                    )
 6913                                })
 6914                                .collect::<Vec<_>>(),
 6915                        )
 6916                    });
 6917
 6918                    result.unwrap_or_default()
 6919                })
 6920                .collect::<Vec<_>>();
 6921
 6922            cx.background_spawn(async move {
 6923                let mut responses = Vec::new();
 6924                for diagnostics in join_all(pull_diagnostics).await {
 6925                    responses.extend(diagnostics?);
 6926                }
 6927                Ok(Some(responses))
 6928            })
 6929        }
 6930    }
 6931
 6932    pub fn applicable_inlay_chunks(
 6933        &mut self,
 6934        buffer: &Entity<Buffer>,
 6935        ranges: &[Range<text::Anchor>],
 6936        cx: &mut Context<Self>,
 6937    ) -> Vec<Range<BufferRow>> {
 6938        let buffer_snapshot = buffer.read(cx).snapshot();
 6939        let ranges = ranges
 6940            .iter()
 6941            .map(|range| range.to_point(&buffer_snapshot))
 6942            .collect::<Vec<_>>();
 6943
 6944        self.latest_lsp_data(buffer, cx)
 6945            .inlay_hints
 6946            .applicable_chunks(ranges.as_slice())
 6947            .map(|chunk| chunk.row_range())
 6948            .collect()
 6949    }
 6950
 6951    pub fn invalidate_inlay_hints<'a>(
 6952        &'a mut self,
 6953        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6954    ) {
 6955        for buffer_id in for_buffers {
 6956            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6957                lsp_data.inlay_hints.clear();
 6958            }
 6959        }
 6960    }
 6961
 6962    pub fn inlay_hints(
 6963        &mut self,
 6964        invalidate: InvalidationStrategy,
 6965        buffer: Entity<Buffer>,
 6966        ranges: Vec<Range<text::Anchor>>,
 6967        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6968        cx: &mut Context<Self>,
 6969    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6970        let next_hint_id = self.next_hint_id.clone();
 6971        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6972        let query_version = lsp_data.buffer_version.clone();
 6973        let mut lsp_refresh_requested = false;
 6974        let for_server = if let InvalidationStrategy::RefreshRequested {
 6975            server_id,
 6976            request_id,
 6977        } = invalidate
 6978        {
 6979            let invalidated = lsp_data
 6980                .inlay_hints
 6981                .invalidate_for_server_refresh(server_id, request_id);
 6982            lsp_refresh_requested = invalidated;
 6983            Some(server_id)
 6984        } else {
 6985            None
 6986        };
 6987        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6988        let known_chunks = known_chunks
 6989            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6990            .map(|(_, known_chunks)| known_chunks)
 6991            .unwrap_or_default();
 6992
 6993        let buffer_snapshot = buffer.read(cx).snapshot();
 6994        let ranges = ranges
 6995            .iter()
 6996            .map(|range| range.to_point(&buffer_snapshot))
 6997            .collect::<Vec<_>>();
 6998
 6999        let mut hint_fetch_tasks = Vec::new();
 7000        let mut cached_inlay_hints = None;
 7001        let mut ranges_to_query = None;
 7002        let applicable_chunks = existing_inlay_hints
 7003            .applicable_chunks(ranges.as_slice())
 7004            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7005            .collect::<Vec<_>>();
 7006        if applicable_chunks.is_empty() {
 7007            return HashMap::default();
 7008        }
 7009
 7010        for row_chunk in applicable_chunks {
 7011            match (
 7012                existing_inlay_hints
 7013                    .cached_hints(&row_chunk)
 7014                    .filter(|_| !lsp_refresh_requested)
 7015                    .cloned(),
 7016                existing_inlay_hints
 7017                    .fetched_hints(&row_chunk)
 7018                    .as_ref()
 7019                    .filter(|_| !lsp_refresh_requested)
 7020                    .cloned(),
 7021            ) {
 7022                (None, None) => {
 7023                    let chunk_range = row_chunk.anchor_range();
 7024                    ranges_to_query
 7025                        .get_or_insert_with(Vec::new)
 7026                        .push((row_chunk, chunk_range));
 7027                }
 7028                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7029                (Some(cached_hints), None) => {
 7030                    for (server_id, cached_hints) in cached_hints {
 7031                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7032                            cached_inlay_hints
 7033                                .get_or_insert_with(HashMap::default)
 7034                                .entry(row_chunk.row_range())
 7035                                .or_insert_with(HashMap::default)
 7036                                .entry(server_id)
 7037                                .or_insert_with(Vec::new)
 7038                                .extend(cached_hints);
 7039                        }
 7040                    }
 7041                }
 7042                (Some(cached_hints), Some(fetched_hints)) => {
 7043                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7044                    for (server_id, cached_hints) in cached_hints {
 7045                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7046                            cached_inlay_hints
 7047                                .get_or_insert_with(HashMap::default)
 7048                                .entry(row_chunk.row_range())
 7049                                .or_insert_with(HashMap::default)
 7050                                .entry(server_id)
 7051                                .or_insert_with(Vec::new)
 7052                                .extend(cached_hints);
 7053                        }
 7054                    }
 7055                }
 7056            }
 7057        }
 7058
 7059        if hint_fetch_tasks.is_empty()
 7060            && ranges_to_query
 7061                .as_ref()
 7062                .is_none_or(|ranges| ranges.is_empty())
 7063            && let Some(cached_inlay_hints) = cached_inlay_hints
 7064        {
 7065            cached_inlay_hints
 7066                .into_iter()
 7067                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7068                .collect()
 7069        } else {
 7070            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7071                let next_hint_id = next_hint_id.clone();
 7072                let buffer = buffer.clone();
 7073                let query_version = query_version.clone();
 7074                let new_inlay_hints = cx
 7075                    .spawn(async move |lsp_store, cx| {
 7076                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7077                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7078                        })?;
 7079                        new_fetch_task
 7080                            .await
 7081                            .and_then(|new_hints_by_server| {
 7082                                lsp_store.update(cx, |lsp_store, cx| {
 7083                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7084                                    let update_cache = lsp_data.buffer_version == query_version;
 7085                                    if new_hints_by_server.is_empty() {
 7086                                        if update_cache {
 7087                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7088                                        }
 7089                                        HashMap::default()
 7090                                    } else {
 7091                                        new_hints_by_server
 7092                                            .into_iter()
 7093                                            .map(|(server_id, new_hints)| {
 7094                                                let new_hints = new_hints
 7095                                                    .into_iter()
 7096                                                    .map(|new_hint| {
 7097                                                        (
 7098                                                            InlayId::Hint(next_hint_id.fetch_add(
 7099                                                                1,
 7100                                                                atomic::Ordering::AcqRel,
 7101                                                            )),
 7102                                                            new_hint,
 7103                                                        )
 7104                                                    })
 7105                                                    .collect::<Vec<_>>();
 7106                                                if update_cache {
 7107                                                    lsp_data.inlay_hints.insert_new_hints(
 7108                                                        chunk,
 7109                                                        server_id,
 7110                                                        new_hints.clone(),
 7111                                                    );
 7112                                                }
 7113                                                (server_id, new_hints)
 7114                                            })
 7115                                            .collect()
 7116                                    }
 7117                                })
 7118                            })
 7119                            .map_err(Arc::new)
 7120                    })
 7121                    .shared();
 7122
 7123                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7124                *fetch_task = Some(new_inlay_hints.clone());
 7125                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7126            }
 7127
 7128            cached_inlay_hints
 7129                .unwrap_or_default()
 7130                .into_iter()
 7131                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7132                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7133                    (
 7134                        chunk.row_range(),
 7135                        cx.spawn(async move |_, _| {
 7136                            hints_fetch.await.map_err(|e| {
 7137                                if e.error_code() != ErrorCode::Internal {
 7138                                    anyhow!(e.error_code())
 7139                                } else {
 7140                                    anyhow!("{e:#}")
 7141                                }
 7142                            })
 7143                        }),
 7144                    )
 7145                }))
 7146                .collect()
 7147        }
 7148    }
 7149
 7150    fn fetch_inlay_hints(
 7151        &mut self,
 7152        for_server: Option<LanguageServerId>,
 7153        buffer: &Entity<Buffer>,
 7154        range: Range<Anchor>,
 7155        cx: &mut Context<Self>,
 7156    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7157        let request = InlayHints {
 7158            range: range.clone(),
 7159        };
 7160        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7161            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7162                return Task::ready(Ok(HashMap::default()));
 7163            }
 7164            let request_task = upstream_client.request_lsp(
 7165                project_id,
 7166                for_server.map(|id| id.to_proto()),
 7167                LSP_REQUEST_TIMEOUT,
 7168                cx.background_executor().clone(),
 7169                request.to_proto(project_id, buffer.read(cx)),
 7170            );
 7171            let buffer = buffer.clone();
 7172            cx.spawn(async move |weak_lsp_store, cx| {
 7173                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7174                    return Ok(HashMap::default());
 7175                };
 7176                let Some(responses) = request_task.await? else {
 7177                    return Ok(HashMap::default());
 7178                };
 7179
 7180                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7181                    let lsp_store = lsp_store.clone();
 7182                    let buffer = buffer.clone();
 7183                    let cx = cx.clone();
 7184                    let request = request.clone();
 7185                    async move {
 7186                        (
 7187                            LanguageServerId::from_proto(response.server_id),
 7188                            request
 7189                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7190                                .await,
 7191                        )
 7192                    }
 7193                }))
 7194                .await;
 7195
 7196                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7197                let mut has_errors = false;
 7198                let inlay_hints = inlay_hints
 7199                    .into_iter()
 7200                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7201                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7202                        Err(e) => {
 7203                            has_errors = true;
 7204                            log::error!("{e:#}");
 7205                            None
 7206                        }
 7207                    })
 7208                    .map(|(server_id, mut new_hints)| {
 7209                        new_hints.retain(|hint| {
 7210                            hint.position.is_valid(&buffer_snapshot)
 7211                                && range.start.is_valid(&buffer_snapshot)
 7212                                && range.end.is_valid(&buffer_snapshot)
 7213                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7214                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7215                        });
 7216                        (server_id, new_hints)
 7217                    })
 7218                    .collect::<HashMap<_, _>>();
 7219                anyhow::ensure!(
 7220                    !has_errors || !inlay_hints.is_empty(),
 7221                    "Failed to fetch inlay hints"
 7222                );
 7223                Ok(inlay_hints)
 7224            })
 7225        } else {
 7226            let inlay_hints_task = match for_server {
 7227                Some(server_id) => {
 7228                    let server_task = self.request_lsp(
 7229                        buffer.clone(),
 7230                        LanguageServerToQuery::Other(server_id),
 7231                        request,
 7232                        cx,
 7233                    );
 7234                    cx.background_spawn(async move {
 7235                        let mut responses = Vec::new();
 7236                        match server_task.await {
 7237                            Ok(response) => responses.push((server_id, response)),
 7238                            // rust-analyzer likes to error with this when its still loading up
 7239                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7240                            Err(e) => log::error!(
 7241                                "Error handling response for inlay hints request: {e:#}"
 7242                            ),
 7243                        }
 7244                        responses
 7245                    })
 7246                }
 7247                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7248            };
 7249            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7250            cx.background_spawn(async move {
 7251                Ok(inlay_hints_task
 7252                    .await
 7253                    .into_iter()
 7254                    .map(|(server_id, mut new_hints)| {
 7255                        new_hints.retain(|hint| {
 7256                            hint.position.is_valid(&buffer_snapshot)
 7257                                && range.start.is_valid(&buffer_snapshot)
 7258                                && range.end.is_valid(&buffer_snapshot)
 7259                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7260                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7261                        });
 7262                        (server_id, new_hints)
 7263                    })
 7264                    .collect())
 7265            })
 7266        }
 7267    }
 7268
 7269    fn diagnostic_registration_exists(
 7270        &self,
 7271        server_id: LanguageServerId,
 7272        registration_id: &Option<SharedString>,
 7273    ) -> bool {
 7274        let Some(local) = self.as_local() else {
 7275            return false;
 7276        };
 7277        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7278        else {
 7279            return false;
 7280        };
 7281        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7282        registrations.diagnostics.contains_key(&registration_key)
 7283    }
 7284
 7285    pub fn pull_diagnostics_for_buffer(
 7286        &mut self,
 7287        buffer: Entity<Buffer>,
 7288        cx: &mut Context<Self>,
 7289    ) -> Task<anyhow::Result<()>> {
 7290        let diagnostics = self.pull_diagnostics(buffer, cx);
 7291        cx.spawn(async move |lsp_store, cx| {
 7292            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7293                return Ok(());
 7294            };
 7295            lsp_store.update(cx, |lsp_store, cx| {
 7296                if lsp_store.as_local().is_none() {
 7297                    return;
 7298                }
 7299
 7300                let mut unchanged_buffers = HashMap::default();
 7301                let server_diagnostics_updates = diagnostics
 7302                    .into_iter()
 7303                    .filter_map(|diagnostics_set| match diagnostics_set {
 7304                        LspPullDiagnostics::Response {
 7305                            server_id,
 7306                            uri,
 7307                            diagnostics,
 7308                            registration_id,
 7309                        } => Some((server_id, uri, diagnostics, registration_id)),
 7310                        LspPullDiagnostics::Default => None,
 7311                    })
 7312                    .filter(|(server_id, _, _, registration_id)| {
 7313                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7314                    })
 7315                    .fold(
 7316                        HashMap::default(),
 7317                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7318                            let (result_id, diagnostics) = match diagnostics {
 7319                                PulledDiagnostics::Unchanged { result_id } => {
 7320                                    unchanged_buffers
 7321                                        .entry(new_registration_id.clone())
 7322                                        .or_insert_with(HashSet::default)
 7323                                        .insert(uri.clone());
 7324                                    (Some(result_id), Vec::new())
 7325                                }
 7326                                PulledDiagnostics::Changed {
 7327                                    result_id,
 7328                                    diagnostics,
 7329                                } => (result_id, diagnostics),
 7330                            };
 7331                            let disk_based_sources = Cow::Owned(
 7332                                lsp_store
 7333                                    .language_server_adapter_for_id(server_id)
 7334                                    .as_ref()
 7335                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7336                                    .unwrap_or(&[])
 7337                                    .to_vec(),
 7338                            );
 7339                            acc.entry(server_id)
 7340                                .or_insert_with(HashMap::default)
 7341                                .entry(new_registration_id.clone())
 7342                                .or_insert_with(Vec::new)
 7343                                .push(DocumentDiagnosticsUpdate {
 7344                                    server_id,
 7345                                    diagnostics: lsp::PublishDiagnosticsParams {
 7346                                        uri,
 7347                                        diagnostics,
 7348                                        version: None,
 7349                                    },
 7350                                    result_id,
 7351                                    disk_based_sources,
 7352                                    registration_id: new_registration_id,
 7353                                });
 7354                            acc
 7355                        },
 7356                    );
 7357
 7358                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7359                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7360                        lsp_store
 7361                            .merge_lsp_diagnostics(
 7362                                DiagnosticSourceKind::Pulled,
 7363                                diagnostic_updates,
 7364                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7365                                    DiagnosticSourceKind::Pulled => {
 7366                                        old_diagnostic.registration_id != registration_id
 7367                                            || unchanged_buffers
 7368                                                .get(&old_diagnostic.registration_id)
 7369                                                .is_some_and(|unchanged_buffers| {
 7370                                                    unchanged_buffers.contains(&document_uri)
 7371                                                })
 7372                                    }
 7373                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7374                                        true
 7375                                    }
 7376                                },
 7377                                cx,
 7378                            )
 7379                            .log_err();
 7380                    }
 7381                }
 7382            })
 7383        })
 7384    }
 7385
 7386    pub fn document_colors(
 7387        &mut self,
 7388        known_cache_version: Option<usize>,
 7389        buffer: Entity<Buffer>,
 7390        cx: &mut Context<Self>,
 7391    ) -> Option<DocumentColorTask> {
 7392        let version_queried_for = buffer.read(cx).version();
 7393        let buffer_id = buffer.read(cx).remote_id();
 7394
 7395        let current_language_servers = self.as_local().map(|local| {
 7396            local
 7397                .buffers_opened_in_servers
 7398                .get(&buffer_id)
 7399                .cloned()
 7400                .unwrap_or_default()
 7401        });
 7402
 7403        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7404            if let Some(cached_colors) = &lsp_data.document_colors {
 7405                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7406                    let has_different_servers =
 7407                        current_language_servers.is_some_and(|current_language_servers| {
 7408                            current_language_servers
 7409                                != cached_colors.colors.keys().copied().collect()
 7410                        });
 7411                    if !has_different_servers {
 7412                        let cache_version = cached_colors.cache_version;
 7413                        if Some(cache_version) == known_cache_version {
 7414                            return None;
 7415                        } else {
 7416                            return Some(
 7417                                Task::ready(Ok(DocumentColors {
 7418                                    colors: cached_colors
 7419                                        .colors
 7420                                        .values()
 7421                                        .flatten()
 7422                                        .cloned()
 7423                                        .collect(),
 7424                                    cache_version: Some(cache_version),
 7425                                }))
 7426                                .shared(),
 7427                            );
 7428                        }
 7429                    }
 7430                }
 7431            }
 7432        }
 7433
 7434        let color_lsp_data = self
 7435            .latest_lsp_data(&buffer, cx)
 7436            .document_colors
 7437            .get_or_insert_default();
 7438        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7439            && !version_queried_for.changed_since(updating_for)
 7440        {
 7441            return Some(running_update.clone());
 7442        }
 7443        let buffer_version_queried_for = version_queried_for.clone();
 7444        let new_task = cx
 7445            .spawn(async move |lsp_store, cx| {
 7446                cx.background_executor()
 7447                    .timer(Duration::from_millis(30))
 7448                    .await;
 7449                let fetched_colors = lsp_store
 7450                    .update(cx, |lsp_store, cx| {
 7451                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7452                    })?
 7453                    .await
 7454                    .context("fetching document colors")
 7455                    .map_err(Arc::new);
 7456                let fetched_colors = match fetched_colors {
 7457                    Ok(fetched_colors) => {
 7458                        if buffer.update(cx, |buffer, _| {
 7459                            buffer.version() != buffer_version_queried_for
 7460                        }) {
 7461                            return Ok(DocumentColors::default());
 7462                        }
 7463                        fetched_colors
 7464                    }
 7465                    Err(e) => {
 7466                        lsp_store
 7467                            .update(cx, |lsp_store, _| {
 7468                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7469                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7470                                        document_colors.colors_update = None;
 7471                                    }
 7472                                }
 7473                            })
 7474                            .ok();
 7475                        return Err(e);
 7476                    }
 7477                };
 7478
 7479                lsp_store
 7480                    .update(cx, |lsp_store, cx| {
 7481                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7482                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7483
 7484                        if let Some(fetched_colors) = fetched_colors {
 7485                            if lsp_data.buffer_version == buffer_version_queried_for {
 7486                                lsp_colors.colors.extend(fetched_colors);
 7487                                lsp_colors.cache_version += 1;
 7488                            } else if !lsp_data
 7489                                .buffer_version
 7490                                .changed_since(&buffer_version_queried_for)
 7491                            {
 7492                                lsp_data.buffer_version = buffer_version_queried_for;
 7493                                lsp_colors.colors = fetched_colors;
 7494                                lsp_colors.cache_version += 1;
 7495                            }
 7496                        }
 7497                        lsp_colors.colors_update = None;
 7498                        let colors = lsp_colors
 7499                            .colors
 7500                            .values()
 7501                            .flatten()
 7502                            .cloned()
 7503                            .collect::<HashSet<_>>();
 7504                        DocumentColors {
 7505                            colors,
 7506                            cache_version: Some(lsp_colors.cache_version),
 7507                        }
 7508                    })
 7509                    .map_err(Arc::new)
 7510            })
 7511            .shared();
 7512        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7513        Some(new_task)
 7514    }
 7515
 7516    fn fetch_document_colors_for_buffer(
 7517        &mut self,
 7518        buffer: &Entity<Buffer>,
 7519        cx: &mut Context<Self>,
 7520    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7521        if let Some((client, project_id)) = self.upstream_client() {
 7522            let request = GetDocumentColor {};
 7523            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7524                return Task::ready(Ok(None));
 7525            }
 7526
 7527            let request_task = client.request_lsp(
 7528                project_id,
 7529                None,
 7530                LSP_REQUEST_TIMEOUT,
 7531                cx.background_executor().clone(),
 7532                request.to_proto(project_id, buffer.read(cx)),
 7533            );
 7534            let buffer = buffer.clone();
 7535            cx.spawn(async move |lsp_store, cx| {
 7536                let Some(lsp_store) = lsp_store.upgrade() else {
 7537                    return Ok(None);
 7538                };
 7539                let colors = join_all(
 7540                    request_task
 7541                        .await
 7542                        .log_err()
 7543                        .flatten()
 7544                        .map(|response| response.payload)
 7545                        .unwrap_or_default()
 7546                        .into_iter()
 7547                        .map(|color_response| {
 7548                            let response = request.response_from_proto(
 7549                                color_response.response,
 7550                                lsp_store.clone(),
 7551                                buffer.clone(),
 7552                                cx.clone(),
 7553                            );
 7554                            async move {
 7555                                (
 7556                                    LanguageServerId::from_proto(color_response.server_id),
 7557                                    response.await.log_err().unwrap_or_default(),
 7558                                )
 7559                            }
 7560                        }),
 7561                )
 7562                .await
 7563                .into_iter()
 7564                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7565                    acc.entry(server_id)
 7566                        .or_insert_with(HashSet::default)
 7567                        .extend(colors);
 7568                    acc
 7569                });
 7570                Ok(Some(colors))
 7571            })
 7572        } else {
 7573            let document_colors_task =
 7574                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7575            cx.background_spawn(async move {
 7576                Ok(Some(
 7577                    document_colors_task
 7578                        .await
 7579                        .into_iter()
 7580                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7581                            acc.entry(server_id)
 7582                                .or_insert_with(HashSet::default)
 7583                                .extend(colors);
 7584                            acc
 7585                        })
 7586                        .into_iter()
 7587                        .collect(),
 7588                ))
 7589            })
 7590        }
 7591    }
 7592
 7593    pub fn signature_help<T: ToPointUtf16>(
 7594        &mut self,
 7595        buffer: &Entity<Buffer>,
 7596        position: T,
 7597        cx: &mut Context<Self>,
 7598    ) -> Task<Option<Vec<SignatureHelp>>> {
 7599        let position = position.to_point_utf16(buffer.read(cx));
 7600
 7601        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7602            let request = GetSignatureHelp { position };
 7603            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7604                return Task::ready(None);
 7605            }
 7606            let request_task = client.request_lsp(
 7607                upstream_project_id,
 7608                None,
 7609                LSP_REQUEST_TIMEOUT,
 7610                cx.background_executor().clone(),
 7611                request.to_proto(upstream_project_id, buffer.read(cx)),
 7612            );
 7613            let buffer = buffer.clone();
 7614            cx.spawn(async move |weak_lsp_store, cx| {
 7615                let lsp_store = weak_lsp_store.upgrade()?;
 7616                let signatures = join_all(
 7617                    request_task
 7618                        .await
 7619                        .log_err()
 7620                        .flatten()
 7621                        .map(|response| response.payload)
 7622                        .unwrap_or_default()
 7623                        .into_iter()
 7624                        .map(|response| {
 7625                            let response = GetSignatureHelp { position }.response_from_proto(
 7626                                response.response,
 7627                                lsp_store.clone(),
 7628                                buffer.clone(),
 7629                                cx.clone(),
 7630                            );
 7631                            async move { response.await.log_err().flatten() }
 7632                        }),
 7633                )
 7634                .await
 7635                .into_iter()
 7636                .flatten()
 7637                .collect();
 7638                Some(signatures)
 7639            })
 7640        } else {
 7641            let all_actions_task = self.request_multiple_lsp_locally(
 7642                buffer,
 7643                Some(position),
 7644                GetSignatureHelp { position },
 7645                cx,
 7646            );
 7647            cx.background_spawn(async move {
 7648                Some(
 7649                    all_actions_task
 7650                        .await
 7651                        .into_iter()
 7652                        .flat_map(|(_, actions)| actions)
 7653                        .collect::<Vec<_>>(),
 7654                )
 7655            })
 7656        }
 7657    }
 7658
 7659    pub fn hover(
 7660        &mut self,
 7661        buffer: &Entity<Buffer>,
 7662        position: PointUtf16,
 7663        cx: &mut Context<Self>,
 7664    ) -> Task<Option<Vec<Hover>>> {
 7665        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7666            let request = GetHover { position };
 7667            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7668                return Task::ready(None);
 7669            }
 7670            let request_task = client.request_lsp(
 7671                upstream_project_id,
 7672                None,
 7673                LSP_REQUEST_TIMEOUT,
 7674                cx.background_executor().clone(),
 7675                request.to_proto(upstream_project_id, buffer.read(cx)),
 7676            );
 7677            let buffer = buffer.clone();
 7678            cx.spawn(async move |weak_lsp_store, cx| {
 7679                let lsp_store = weak_lsp_store.upgrade()?;
 7680                let hovers = join_all(
 7681                    request_task
 7682                        .await
 7683                        .log_err()
 7684                        .flatten()
 7685                        .map(|response| response.payload)
 7686                        .unwrap_or_default()
 7687                        .into_iter()
 7688                        .map(|response| {
 7689                            let response = GetHover { position }.response_from_proto(
 7690                                response.response,
 7691                                lsp_store.clone(),
 7692                                buffer.clone(),
 7693                                cx.clone(),
 7694                            );
 7695                            async move {
 7696                                response
 7697                                    .await
 7698                                    .log_err()
 7699                                    .flatten()
 7700                                    .and_then(remove_empty_hover_blocks)
 7701                            }
 7702                        }),
 7703                )
 7704                .await
 7705                .into_iter()
 7706                .flatten()
 7707                .collect();
 7708                Some(hovers)
 7709            })
 7710        } else {
 7711            let all_actions_task = self.request_multiple_lsp_locally(
 7712                buffer,
 7713                Some(position),
 7714                GetHover { position },
 7715                cx,
 7716            );
 7717            cx.background_spawn(async move {
 7718                Some(
 7719                    all_actions_task
 7720                        .await
 7721                        .into_iter()
 7722                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7723                        .collect::<Vec<Hover>>(),
 7724                )
 7725            })
 7726        }
 7727    }
 7728
 7729    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7730        let language_registry = self.languages.clone();
 7731
 7732        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7733            let request = upstream_client.request(proto::GetProjectSymbols {
 7734                project_id: *project_id,
 7735                query: query.to_string(),
 7736            });
 7737            cx.foreground_executor().spawn(async move {
 7738                let response = request.await?;
 7739                let mut symbols = Vec::new();
 7740                let core_symbols = response
 7741                    .symbols
 7742                    .into_iter()
 7743                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7744                    .collect::<Vec<_>>();
 7745                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7746                    .await;
 7747                Ok(symbols)
 7748            })
 7749        } else if let Some(local) = self.as_local() {
 7750            struct WorkspaceSymbolsResult {
 7751                server_id: LanguageServerId,
 7752                lsp_adapter: Arc<CachedLspAdapter>,
 7753                worktree: WeakEntity<Worktree>,
 7754                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7755            }
 7756
 7757            let mut requests = Vec::new();
 7758            let mut requested_servers = BTreeSet::new();
 7759            for (seed, state) in local.language_server_ids.iter() {
 7760                let Some(worktree_handle) = self
 7761                    .worktree_store
 7762                    .read(cx)
 7763                    .worktree_for_id(seed.worktree_id, cx)
 7764                else {
 7765                    continue;
 7766                };
 7767                let worktree = worktree_handle.read(cx);
 7768                if !worktree.is_visible() {
 7769                    continue;
 7770                }
 7771
 7772                if !requested_servers.insert(state.id) {
 7773                    continue;
 7774                }
 7775
 7776                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7777                    Some(LanguageServerState::Running {
 7778                        adapter, server, ..
 7779                    }) => (adapter.clone(), server),
 7780
 7781                    _ => continue,
 7782                };
 7783                let supports_workspace_symbol_request =
 7784                    match server.capabilities().workspace_symbol_provider {
 7785                        Some(OneOf::Left(supported)) => supported,
 7786                        Some(OneOf::Right(_)) => true,
 7787                        None => false,
 7788                    };
 7789                if !supports_workspace_symbol_request {
 7790                    continue;
 7791                }
 7792                let worktree_handle = worktree_handle.clone();
 7793                let server_id = server.server_id();
 7794                requests.push(
 7795                        server
 7796                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7797                                lsp::WorkspaceSymbolParams {
 7798                                    query: query.to_string(),
 7799                                    ..Default::default()
 7800                                },
 7801                            )
 7802                            .map(move |response| {
 7803                                let lsp_symbols = response.into_response()
 7804                                    .context("workspace symbols request")
 7805                                    .log_err()
 7806                                    .flatten()
 7807                                    .map(|symbol_response| match symbol_response {
 7808                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7809                                            flat_responses.into_iter().map(|lsp_symbol| {
 7810                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7811                                            }).collect::<Vec<_>>()
 7812                                        }
 7813                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7814                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7815                                                let location = match lsp_symbol.location {
 7816                                                    OneOf::Left(location) => location,
 7817                                                    OneOf::Right(_) => {
 7818                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7819                                                        return None
 7820                                                    }
 7821                                                };
 7822                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7823                                            }).collect::<Vec<_>>()
 7824                                        }
 7825                                    }).unwrap_or_default();
 7826
 7827                                WorkspaceSymbolsResult {
 7828                                    server_id,
 7829                                    lsp_adapter,
 7830                                    worktree: worktree_handle.downgrade(),
 7831                                    lsp_symbols,
 7832                                }
 7833                            }),
 7834                    );
 7835            }
 7836
 7837            cx.spawn(async move |this, cx| {
 7838                let responses = futures::future::join_all(requests).await;
 7839                let this = match this.upgrade() {
 7840                    Some(this) => this,
 7841                    None => return Ok(Vec::new()),
 7842                };
 7843
 7844                let mut symbols = Vec::new();
 7845                for result in responses {
 7846                    let core_symbols = this.update(cx, |this, cx| {
 7847                        result
 7848                            .lsp_symbols
 7849                            .into_iter()
 7850                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7851                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7852                                let source_worktree = result.worktree.upgrade()?;
 7853                                let source_worktree_id = source_worktree.read(cx).id();
 7854
 7855                                let path = if let Some((tree, rel_path)) =
 7856                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7857                                {
 7858                                    let worktree_id = tree.read(cx).id();
 7859                                    SymbolLocation::InProject(ProjectPath {
 7860                                        worktree_id,
 7861                                        path: rel_path,
 7862                                    })
 7863                                } else {
 7864                                    SymbolLocation::OutsideProject {
 7865                                        signature: this.symbol_signature(&abs_path),
 7866                                        abs_path: abs_path.into(),
 7867                                    }
 7868                                };
 7869
 7870                                Some(CoreSymbol {
 7871                                    source_language_server_id: result.server_id,
 7872                                    language_server_name: result.lsp_adapter.name.clone(),
 7873                                    source_worktree_id,
 7874                                    path,
 7875                                    kind: symbol_kind,
 7876                                    name: symbol_name,
 7877                                    range: range_from_lsp(symbol_location.range),
 7878                                })
 7879                            })
 7880                            .collect::<Vec<_>>()
 7881                    });
 7882
 7883                    populate_labels_for_symbols(
 7884                        core_symbols,
 7885                        &language_registry,
 7886                        Some(result.lsp_adapter),
 7887                        &mut symbols,
 7888                    )
 7889                    .await;
 7890                }
 7891
 7892                Ok(symbols)
 7893            })
 7894        } else {
 7895            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7896        }
 7897    }
 7898
 7899    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7900        let mut summary = DiagnosticSummary::default();
 7901        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7902            summary.error_count += path_summary.error_count;
 7903            summary.warning_count += path_summary.warning_count;
 7904        }
 7905        summary
 7906    }
 7907
 7908    /// Returns the diagnostic summary for a specific project path.
 7909    pub fn diagnostic_summary_for_path(
 7910        &self,
 7911        project_path: &ProjectPath,
 7912        _: &App,
 7913    ) -> DiagnosticSummary {
 7914        if let Some(summaries) = self
 7915            .diagnostic_summaries
 7916            .get(&project_path.worktree_id)
 7917            .and_then(|map| map.get(&project_path.path))
 7918        {
 7919            let (error_count, warning_count) = summaries.iter().fold(
 7920                (0, 0),
 7921                |(error_count, warning_count), (_language_server_id, summary)| {
 7922                    (
 7923                        error_count + summary.error_count,
 7924                        warning_count + summary.warning_count,
 7925                    )
 7926                },
 7927            );
 7928
 7929            DiagnosticSummary {
 7930                error_count,
 7931                warning_count,
 7932            }
 7933        } else {
 7934            DiagnosticSummary::default()
 7935        }
 7936    }
 7937
 7938    pub fn diagnostic_summaries<'a>(
 7939        &'a self,
 7940        include_ignored: bool,
 7941        cx: &'a App,
 7942    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7943        self.worktree_store
 7944            .read(cx)
 7945            .visible_worktrees(cx)
 7946            .filter_map(|worktree| {
 7947                let worktree = worktree.read(cx);
 7948                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7949            })
 7950            .flat_map(move |(worktree, summaries)| {
 7951                let worktree_id = worktree.id();
 7952                summaries
 7953                    .iter()
 7954                    .filter(move |(path, _)| {
 7955                        include_ignored
 7956                            || worktree
 7957                                .entry_for_path(path.as_ref())
 7958                                .is_some_and(|entry| !entry.is_ignored)
 7959                    })
 7960                    .flat_map(move |(path, summaries)| {
 7961                        summaries.iter().map(move |(server_id, summary)| {
 7962                            (
 7963                                ProjectPath {
 7964                                    worktree_id,
 7965                                    path: path.clone(),
 7966                                },
 7967                                *server_id,
 7968                                *summary,
 7969                            )
 7970                        })
 7971                    })
 7972            })
 7973    }
 7974
 7975    pub fn on_buffer_edited(
 7976        &mut self,
 7977        buffer: Entity<Buffer>,
 7978        cx: &mut Context<Self>,
 7979    ) -> Option<()> {
 7980        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7981            Some(
 7982                self.as_local()?
 7983                    .language_servers_for_buffer(buffer, cx)
 7984                    .map(|i| i.1.clone())
 7985                    .collect(),
 7986            )
 7987        })?;
 7988
 7989        let buffer = buffer.read(cx);
 7990        let file = File::from_dyn(buffer.file())?;
 7991        let abs_path = file.as_local()?.abs_path(cx);
 7992        let uri = lsp::Uri::from_file_path(&abs_path)
 7993            .ok()
 7994            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7995            .log_err()?;
 7996        let next_snapshot = buffer.text_snapshot();
 7997        for language_server in language_servers {
 7998            let language_server = language_server.clone();
 7999
 8000            let buffer_snapshots = self
 8001                .as_local_mut()?
 8002                .buffer_snapshots
 8003                .get_mut(&buffer.remote_id())
 8004                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 8005            let previous_snapshot = buffer_snapshots.last()?;
 8006
 8007            let build_incremental_change = || {
 8008                buffer
 8009                    .edits_since::<Dimensions<PointUtf16, usize>>(
 8010                        previous_snapshot.snapshot.version(),
 8011                    )
 8012                    .map(|edit| {
 8013                        let edit_start = edit.new.start.0;
 8014                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 8015                        let new_text = next_snapshot
 8016                            .text_for_range(edit.new.start.1..edit.new.end.1)
 8017                            .collect();
 8018                        lsp::TextDocumentContentChangeEvent {
 8019                            range: Some(lsp::Range::new(
 8020                                point_to_lsp(edit_start),
 8021                                point_to_lsp(edit_end),
 8022                            )),
 8023                            range_length: None,
 8024                            text: new_text,
 8025                        }
 8026                    })
 8027                    .collect()
 8028            };
 8029
 8030            let document_sync_kind = language_server
 8031                .capabilities()
 8032                .text_document_sync
 8033                .as_ref()
 8034                .and_then(|sync| match sync {
 8035                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 8036                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 8037                });
 8038
 8039            let content_changes: Vec<_> = match document_sync_kind {
 8040                Some(lsp::TextDocumentSyncKind::FULL) => {
 8041                    vec![lsp::TextDocumentContentChangeEvent {
 8042                        range: None,
 8043                        range_length: None,
 8044                        text: next_snapshot.text(),
 8045                    }]
 8046                }
 8047                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8048                _ => {
 8049                    #[cfg(any(test, feature = "test-support"))]
 8050                    {
 8051                        build_incremental_change()
 8052                    }
 8053
 8054                    #[cfg(not(any(test, feature = "test-support")))]
 8055                    {
 8056                        continue;
 8057                    }
 8058                }
 8059            };
 8060
 8061            let next_version = previous_snapshot.version + 1;
 8062            buffer_snapshots.push(LspBufferSnapshot {
 8063                version: next_version,
 8064                snapshot: next_snapshot.clone(),
 8065            });
 8066
 8067            language_server
 8068                .notify::<lsp::notification::DidChangeTextDocument>(
 8069                    lsp::DidChangeTextDocumentParams {
 8070                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8071                            uri.clone(),
 8072                            next_version,
 8073                        ),
 8074                        content_changes,
 8075                    },
 8076                )
 8077                .ok();
 8078            self.pull_workspace_diagnostics(language_server.server_id());
 8079        }
 8080
 8081        None
 8082    }
 8083
 8084    pub fn on_buffer_saved(
 8085        &mut self,
 8086        buffer: Entity<Buffer>,
 8087        cx: &mut Context<Self>,
 8088    ) -> Option<()> {
 8089        let file = File::from_dyn(buffer.read(cx).file())?;
 8090        let worktree_id = file.worktree_id(cx);
 8091        let abs_path = file.as_local()?.abs_path(cx);
 8092        let text_document = lsp::TextDocumentIdentifier {
 8093            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8094        };
 8095        let local = self.as_local()?;
 8096
 8097        for server in local.language_servers_for_worktree(worktree_id) {
 8098            if let Some(include_text) = include_text(server.as_ref()) {
 8099                let text = if include_text {
 8100                    Some(buffer.read(cx).text())
 8101                } else {
 8102                    None
 8103                };
 8104                server
 8105                    .notify::<lsp::notification::DidSaveTextDocument>(
 8106                        lsp::DidSaveTextDocumentParams {
 8107                            text_document: text_document.clone(),
 8108                            text,
 8109                        },
 8110                    )
 8111                    .ok();
 8112            }
 8113        }
 8114
 8115        let language_servers = buffer.update(cx, |buffer, cx| {
 8116            local.language_server_ids_for_buffer(buffer, cx)
 8117        });
 8118        for language_server_id in language_servers {
 8119            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8120        }
 8121
 8122        None
 8123    }
 8124
 8125    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8126        maybe!(async move {
 8127            let mut refreshed_servers = HashSet::default();
 8128            let servers = lsp_store
 8129                .update(cx, |lsp_store, cx| {
 8130                    let local = lsp_store.as_local()?;
 8131
 8132                    let servers = local
 8133                        .language_server_ids
 8134                        .iter()
 8135                        .filter_map(|(seed, state)| {
 8136                            let worktree = lsp_store
 8137                                .worktree_store
 8138                                .read(cx)
 8139                                .worktree_for_id(seed.worktree_id, cx);
 8140                            let delegate: Arc<dyn LspAdapterDelegate> =
 8141                                worktree.map(|worktree| {
 8142                                    LocalLspAdapterDelegate::new(
 8143                                        local.languages.clone(),
 8144                                        &local.environment,
 8145                                        cx.weak_entity(),
 8146                                        &worktree,
 8147                                        local.http_client.clone(),
 8148                                        local.fs.clone(),
 8149                                        cx,
 8150                                    )
 8151                                })?;
 8152                            let server_id = state.id;
 8153
 8154                            let states = local.language_servers.get(&server_id)?;
 8155
 8156                            match states {
 8157                                LanguageServerState::Starting { .. } => None,
 8158                                LanguageServerState::Running {
 8159                                    adapter, server, ..
 8160                                } => {
 8161                                    let adapter = adapter.clone();
 8162                                    let server = server.clone();
 8163                                    refreshed_servers.insert(server.name());
 8164                                    let toolchain = seed.toolchain.clone();
 8165                                    Some(cx.spawn(async move |_, cx| {
 8166                                        let settings =
 8167                                            LocalLspStore::workspace_configuration_for_adapter(
 8168                                                adapter.adapter.clone(),
 8169                                                &delegate,
 8170                                                toolchain,
 8171                                                None,
 8172                                                cx,
 8173                                            )
 8174                                            .await
 8175                                            .ok()?;
 8176                                        server
 8177                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8178                                                lsp::DidChangeConfigurationParams { settings },
 8179                                            )
 8180                                            .ok()?;
 8181                                        Some(())
 8182                                    }))
 8183                                }
 8184                            }
 8185                        })
 8186                        .collect::<Vec<_>>();
 8187
 8188                    Some(servers)
 8189                })
 8190                .ok()
 8191                .flatten()?;
 8192
 8193            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8194            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8195            // to stop and unregister its language server wrapper.
 8196            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8197            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8198            let _: Vec<Option<()>> = join_all(servers).await;
 8199
 8200            Some(())
 8201        })
 8202        .await;
 8203    }
 8204
 8205    fn maintain_workspace_config(
 8206        external_refresh_requests: watch::Receiver<()>,
 8207        cx: &mut Context<Self>,
 8208    ) -> Task<Result<()>> {
 8209        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8210        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8211
 8212        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8213            *settings_changed_tx.borrow_mut() = ();
 8214        });
 8215
 8216        let mut joint_future =
 8217            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8218        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8219        // - 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).
 8220        // - 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.
 8221        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8222        // - 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,
 8223        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8224        cx.spawn(async move |this, cx| {
 8225            while let Some(()) = joint_future.next().await {
 8226                this.update(cx, |this, cx| {
 8227                    this.refresh_server_tree(cx);
 8228                })
 8229                .ok();
 8230
 8231                Self::refresh_workspace_configurations(&this, cx).await;
 8232            }
 8233
 8234            drop(settings_observation);
 8235            anyhow::Ok(())
 8236        })
 8237    }
 8238
 8239    pub fn running_language_servers_for_local_buffer<'a>(
 8240        &'a self,
 8241        buffer: &Buffer,
 8242        cx: &mut App,
 8243    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8244        let local = self.as_local();
 8245        let language_server_ids = local
 8246            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8247            .unwrap_or_default();
 8248
 8249        language_server_ids
 8250            .into_iter()
 8251            .filter_map(
 8252                move |server_id| match local?.language_servers.get(&server_id)? {
 8253                    LanguageServerState::Running {
 8254                        adapter, server, ..
 8255                    } => Some((adapter, server)),
 8256                    _ => None,
 8257                },
 8258            )
 8259    }
 8260
 8261    pub fn language_servers_for_local_buffer(
 8262        &self,
 8263        buffer: &Buffer,
 8264        cx: &mut App,
 8265    ) -> Vec<LanguageServerId> {
 8266        let local = self.as_local();
 8267        local
 8268            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8269            .unwrap_or_default()
 8270    }
 8271
 8272    pub fn language_server_for_local_buffer<'a>(
 8273        &'a self,
 8274        buffer: &'a Buffer,
 8275        server_id: LanguageServerId,
 8276        cx: &'a mut App,
 8277    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8278        self.as_local()?
 8279            .language_servers_for_buffer(buffer, cx)
 8280            .find(|(_, s)| s.server_id() == server_id)
 8281    }
 8282
 8283    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8284        self.diagnostic_summaries.remove(&id_to_remove);
 8285        if let Some(local) = self.as_local_mut() {
 8286            let to_remove = local.remove_worktree(id_to_remove, cx);
 8287            for server in to_remove {
 8288                self.language_server_statuses.remove(&server);
 8289            }
 8290        }
 8291    }
 8292
 8293    pub fn shared(
 8294        &mut self,
 8295        project_id: u64,
 8296        downstream_client: AnyProtoClient,
 8297        _: &mut Context<Self>,
 8298    ) {
 8299        self.downstream_client = Some((downstream_client.clone(), project_id));
 8300
 8301        for (server_id, status) in &self.language_server_statuses {
 8302            if let Some(server) = self.language_server_for_id(*server_id) {
 8303                downstream_client
 8304                    .send(proto::StartLanguageServer {
 8305                        project_id,
 8306                        server: Some(proto::LanguageServer {
 8307                            id: server_id.to_proto(),
 8308                            name: status.name.to_string(),
 8309                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8310                        }),
 8311                        capabilities: serde_json::to_string(&server.capabilities())
 8312                            .expect("serializing server LSP capabilities"),
 8313                    })
 8314                    .log_err();
 8315            }
 8316        }
 8317    }
 8318
 8319    pub fn disconnected_from_host(&mut self) {
 8320        self.downstream_client.take();
 8321    }
 8322
 8323    pub fn disconnected_from_ssh_remote(&mut self) {
 8324        if let LspStoreMode::Remote(RemoteLspStore {
 8325            upstream_client, ..
 8326        }) = &mut self.mode
 8327        {
 8328            upstream_client.take();
 8329        }
 8330    }
 8331
 8332    pub(crate) fn set_language_server_statuses_from_proto(
 8333        &mut self,
 8334        project: WeakEntity<Project>,
 8335        language_servers: Vec<proto::LanguageServer>,
 8336        server_capabilities: Vec<String>,
 8337        cx: &mut Context<Self>,
 8338    ) {
 8339        let lsp_logs = cx
 8340            .try_global::<GlobalLogStore>()
 8341            .map(|lsp_store| lsp_store.0.clone());
 8342
 8343        self.language_server_statuses = language_servers
 8344            .into_iter()
 8345            .zip(server_capabilities)
 8346            .map(|(server, server_capabilities)| {
 8347                let server_id = LanguageServerId(server.id as usize);
 8348                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8349                    self.lsp_server_capabilities
 8350                        .insert(server_id, server_capabilities);
 8351                }
 8352
 8353                let name = LanguageServerName::from_proto(server.name);
 8354                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8355
 8356                if let Some(lsp_logs) = &lsp_logs {
 8357                    lsp_logs.update(cx, |lsp_logs, cx| {
 8358                        lsp_logs.add_language_server(
 8359                            // Only remote clients get their language servers set from proto
 8360                            LanguageServerKind::Remote {
 8361                                project: project.clone(),
 8362                            },
 8363                            server_id,
 8364                            Some(name.clone()),
 8365                            worktree,
 8366                            None,
 8367                            cx,
 8368                        );
 8369                    });
 8370                }
 8371
 8372                (
 8373                    server_id,
 8374                    LanguageServerStatus {
 8375                        name,
 8376                        server_version: None,
 8377                        pending_work: Default::default(),
 8378                        has_pending_diagnostic_updates: false,
 8379                        progress_tokens: Default::default(),
 8380                        worktree,
 8381                        binary: None,
 8382                        configuration: None,
 8383                        workspace_folders: BTreeSet::new(),
 8384                    },
 8385                )
 8386            })
 8387            .collect();
 8388    }
 8389
 8390    #[cfg(test)]
 8391    pub fn update_diagnostic_entries(
 8392        &mut self,
 8393        server_id: LanguageServerId,
 8394        abs_path: PathBuf,
 8395        result_id: Option<SharedString>,
 8396        version: Option<i32>,
 8397        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8398        cx: &mut Context<Self>,
 8399    ) -> anyhow::Result<()> {
 8400        self.merge_diagnostic_entries(
 8401            vec![DocumentDiagnosticsUpdate {
 8402                diagnostics: DocumentDiagnostics {
 8403                    diagnostics,
 8404                    document_abs_path: abs_path,
 8405                    version,
 8406                },
 8407                result_id,
 8408                server_id,
 8409                disk_based_sources: Cow::Borrowed(&[]),
 8410                registration_id: None,
 8411            }],
 8412            |_, _, _| false,
 8413            cx,
 8414        )?;
 8415        Ok(())
 8416    }
 8417
 8418    pub fn merge_diagnostic_entries<'a>(
 8419        &mut self,
 8420        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8421        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8422        cx: &mut Context<Self>,
 8423    ) -> anyhow::Result<()> {
 8424        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8425        let mut updated_diagnostics_paths = HashMap::default();
 8426        for mut update in diagnostic_updates {
 8427            let abs_path = &update.diagnostics.document_abs_path;
 8428            let server_id = update.server_id;
 8429            let Some((worktree, relative_path)) =
 8430                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8431            else {
 8432                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8433                return Ok(());
 8434            };
 8435
 8436            let worktree_id = worktree.read(cx).id();
 8437            let project_path = ProjectPath {
 8438                worktree_id,
 8439                path: relative_path,
 8440            };
 8441
 8442            let document_uri = lsp::Uri::from_file_path(abs_path)
 8443                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8444            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8445                let snapshot = buffer_handle.read(cx).snapshot();
 8446                let buffer = buffer_handle.read(cx);
 8447                let reused_diagnostics = buffer
 8448                    .buffer_diagnostics(Some(server_id))
 8449                    .iter()
 8450                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8451                    .map(|v| {
 8452                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8453                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8454                        DiagnosticEntry {
 8455                            range: start..end,
 8456                            diagnostic: v.diagnostic.clone(),
 8457                        }
 8458                    })
 8459                    .collect::<Vec<_>>();
 8460
 8461                self.as_local_mut()
 8462                    .context("cannot merge diagnostics on a remote LspStore")?
 8463                    .update_buffer_diagnostics(
 8464                        &buffer_handle,
 8465                        server_id,
 8466                        Some(update.registration_id),
 8467                        update.result_id,
 8468                        update.diagnostics.version,
 8469                        update.diagnostics.diagnostics.clone(),
 8470                        reused_diagnostics.clone(),
 8471                        cx,
 8472                    )?;
 8473
 8474                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8475            } else if let Some(local) = self.as_local() {
 8476                let reused_diagnostics = local
 8477                    .diagnostics
 8478                    .get(&worktree_id)
 8479                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8480                    .and_then(|diagnostics_by_server_id| {
 8481                        diagnostics_by_server_id
 8482                            .binary_search_by_key(&server_id, |e| e.0)
 8483                            .ok()
 8484                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8485                    })
 8486                    .into_iter()
 8487                    .flatten()
 8488                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8489
 8490                update
 8491                    .diagnostics
 8492                    .diagnostics
 8493                    .extend(reused_diagnostics.cloned());
 8494            }
 8495
 8496            let updated = worktree.update(cx, |worktree, cx| {
 8497                self.update_worktree_diagnostics(
 8498                    worktree.id(),
 8499                    server_id,
 8500                    project_path.path.clone(),
 8501                    update.diagnostics.diagnostics,
 8502                    cx,
 8503                )
 8504            })?;
 8505            match updated {
 8506                ControlFlow::Continue(new_summary) => {
 8507                    if let Some((project_id, new_summary)) = new_summary {
 8508                        match &mut diagnostics_summary {
 8509                            Some(diagnostics_summary) => {
 8510                                diagnostics_summary
 8511                                    .more_summaries
 8512                                    .push(proto::DiagnosticSummary {
 8513                                        path: project_path.path.as_ref().to_proto(),
 8514                                        language_server_id: server_id.0 as u64,
 8515                                        error_count: new_summary.error_count,
 8516                                        warning_count: new_summary.warning_count,
 8517                                    })
 8518                            }
 8519                            None => {
 8520                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8521                                    project_id,
 8522                                    worktree_id: worktree_id.to_proto(),
 8523                                    summary: Some(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                                    more_summaries: Vec::new(),
 8530                                })
 8531                            }
 8532                        }
 8533                    }
 8534                    updated_diagnostics_paths
 8535                        .entry(server_id)
 8536                        .or_insert_with(Vec::new)
 8537                        .push(project_path);
 8538                }
 8539                ControlFlow::Break(()) => {}
 8540            }
 8541        }
 8542
 8543        if let Some((diagnostics_summary, (downstream_client, _))) =
 8544            diagnostics_summary.zip(self.downstream_client.as_ref())
 8545        {
 8546            downstream_client.send(diagnostics_summary).log_err();
 8547        }
 8548        for (server_id, paths) in updated_diagnostics_paths {
 8549            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8550        }
 8551        Ok(())
 8552    }
 8553
 8554    fn update_worktree_diagnostics(
 8555        &mut self,
 8556        worktree_id: WorktreeId,
 8557        server_id: LanguageServerId,
 8558        path_in_worktree: Arc<RelPath>,
 8559        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8560        _: &mut Context<Worktree>,
 8561    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8562        let local = match &mut self.mode {
 8563            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8564            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8565        };
 8566
 8567        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8568        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8569        let summaries_by_server_id = summaries_for_tree
 8570            .entry(path_in_worktree.clone())
 8571            .or_default();
 8572
 8573        let old_summary = summaries_by_server_id
 8574            .remove(&server_id)
 8575            .unwrap_or_default();
 8576
 8577        let new_summary = DiagnosticSummary::new(&diagnostics);
 8578        if diagnostics.is_empty() {
 8579            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8580            {
 8581                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8582                    diagnostics_by_server_id.remove(ix);
 8583                }
 8584                if diagnostics_by_server_id.is_empty() {
 8585                    diagnostics_for_tree.remove(&path_in_worktree);
 8586                }
 8587            }
 8588        } else {
 8589            summaries_by_server_id.insert(server_id, new_summary);
 8590            let diagnostics_by_server_id = diagnostics_for_tree
 8591                .entry(path_in_worktree.clone())
 8592                .or_default();
 8593            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8594                Ok(ix) => {
 8595                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8596                }
 8597                Err(ix) => {
 8598                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8599                }
 8600            }
 8601        }
 8602
 8603        if !old_summary.is_empty() || !new_summary.is_empty() {
 8604            if let Some((_, project_id)) = &self.downstream_client {
 8605                Ok(ControlFlow::Continue(Some((
 8606                    *project_id,
 8607                    proto::DiagnosticSummary {
 8608                        path: path_in_worktree.to_proto(),
 8609                        language_server_id: server_id.0 as u64,
 8610                        error_count: new_summary.error_count as u32,
 8611                        warning_count: new_summary.warning_count as u32,
 8612                    },
 8613                ))))
 8614            } else {
 8615                Ok(ControlFlow::Continue(None))
 8616            }
 8617        } else {
 8618            Ok(ControlFlow::Break(()))
 8619        }
 8620    }
 8621
 8622    pub fn open_buffer_for_symbol(
 8623        &mut self,
 8624        symbol: &Symbol,
 8625        cx: &mut Context<Self>,
 8626    ) -> Task<Result<Entity<Buffer>>> {
 8627        if let Some((client, project_id)) = self.upstream_client() {
 8628            let request = client.request(proto::OpenBufferForSymbol {
 8629                project_id,
 8630                symbol: Some(Self::serialize_symbol(symbol)),
 8631            });
 8632            cx.spawn(async move |this, cx| {
 8633                let response = request.await?;
 8634                let buffer_id = BufferId::new(response.buffer_id)?;
 8635                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8636                    .await
 8637            })
 8638        } else if let Some(local) = self.as_local() {
 8639            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8640                seed.worktree_id == symbol.source_worktree_id
 8641                    && state.id == symbol.source_language_server_id
 8642                    && symbol.language_server_name == seed.name
 8643            });
 8644            if !is_valid {
 8645                return Task::ready(Err(anyhow!(
 8646                    "language server for worktree and language not found"
 8647                )));
 8648            };
 8649
 8650            let symbol_abs_path = match &symbol.path {
 8651                SymbolLocation::InProject(project_path) => self
 8652                    .worktree_store
 8653                    .read(cx)
 8654                    .absolutize(&project_path, cx)
 8655                    .context("no such worktree"),
 8656                SymbolLocation::OutsideProject {
 8657                    abs_path,
 8658                    signature: _,
 8659                } => Ok(abs_path.to_path_buf()),
 8660            };
 8661            let symbol_abs_path = match symbol_abs_path {
 8662                Ok(abs_path) => abs_path,
 8663                Err(err) => return Task::ready(Err(err)),
 8664            };
 8665            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8666                uri
 8667            } else {
 8668                return Task::ready(Err(anyhow!("invalid symbol path")));
 8669            };
 8670
 8671            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8672        } else {
 8673            Task::ready(Err(anyhow!("no upstream client or local store")))
 8674        }
 8675    }
 8676
 8677    pub(crate) fn open_local_buffer_via_lsp(
 8678        &mut self,
 8679        abs_path: lsp::Uri,
 8680        language_server_id: LanguageServerId,
 8681        cx: &mut Context<Self>,
 8682    ) -> Task<Result<Entity<Buffer>>> {
 8683        cx.spawn(async move |lsp_store, cx| {
 8684            // Escape percent-encoded string.
 8685            let current_scheme = abs_path.scheme().to_owned();
 8686            // Uri is immutable, so we can't modify the scheme
 8687
 8688            let abs_path = abs_path
 8689                .to_file_path()
 8690                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8691            let p = abs_path.clone();
 8692            let yarn_worktree = lsp_store
 8693                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8694                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8695                        cx.spawn(async move |this, cx| {
 8696                            let t = this
 8697                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8698                                .ok()?;
 8699                            t.await
 8700                        })
 8701                    }),
 8702                    None => Task::ready(None),
 8703                })?
 8704                .await;
 8705            let (worktree_root_target, known_relative_path) =
 8706                if let Some((zip_root, relative_path)) = yarn_worktree {
 8707                    (zip_root, Some(relative_path))
 8708                } else {
 8709                    (Arc::<Path>::from(abs_path.as_path()), None)
 8710                };
 8711            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8712                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8713                    worktree_store.find_worktree(&worktree_root_target, cx)
 8714                })
 8715            })?;
 8716            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8717                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8718                (result.0, relative_path, None)
 8719            } else {
 8720                let worktree = lsp_store
 8721                    .update(cx, |lsp_store, cx| {
 8722                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8723                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8724                        })
 8725                    })?
 8726                    .await?;
 8727                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8728                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8729                    lsp_store
 8730                        .update(cx, |lsp_store, cx| {
 8731                            if let Some(local) = lsp_store.as_local_mut() {
 8732                                local.register_language_server_for_invisible_worktree(
 8733                                    &worktree,
 8734                                    language_server_id,
 8735                                    cx,
 8736                                )
 8737                            }
 8738                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8739                                Some(status) => status.worktree,
 8740                                None => None,
 8741                            }
 8742                        })
 8743                        .ok()
 8744                        .flatten()
 8745                        .zip(Some(worktree_root.clone()))
 8746                } else {
 8747                    None
 8748                };
 8749                let relative_path = if let Some(known_path) = known_relative_path {
 8750                    known_path
 8751                } else {
 8752                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8753                        .into_arc()
 8754                };
 8755                (worktree, relative_path, source_ws)
 8756            };
 8757            let project_path = ProjectPath {
 8758                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8759                path: relative_path,
 8760            };
 8761            let buffer = lsp_store
 8762                .update(cx, |lsp_store, cx| {
 8763                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8764                        buffer_store.open_buffer(project_path, cx)
 8765                    })
 8766                })?
 8767                .await?;
 8768            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8769            if let Some((source_ws, worktree_root)) = source_ws {
 8770                buffer.update(cx, |buffer, cx| {
 8771                    let settings = WorktreeSettings::get(
 8772                        Some(
 8773                            (&ProjectPath {
 8774                                worktree_id: source_ws,
 8775                                path: Arc::from(RelPath::empty()),
 8776                            })
 8777                                .into(),
 8778                        ),
 8779                        cx,
 8780                    );
 8781                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8782                    if is_read_only {
 8783                        buffer.set_capability(Capability::ReadOnly, cx);
 8784                    }
 8785                });
 8786            }
 8787            Ok(buffer)
 8788        })
 8789    }
 8790
 8791    fn request_multiple_lsp_locally<P, R>(
 8792        &mut self,
 8793        buffer: &Entity<Buffer>,
 8794        position: Option<P>,
 8795        request: R,
 8796        cx: &mut Context<Self>,
 8797    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8798    where
 8799        P: ToOffset,
 8800        R: LspCommand + Clone,
 8801        <R::LspRequest as lsp::request::Request>::Result: Send,
 8802        <R::LspRequest as lsp::request::Request>::Params: Send,
 8803    {
 8804        let Some(local) = self.as_local() else {
 8805            return Task::ready(Vec::new());
 8806        };
 8807
 8808        let snapshot = buffer.read(cx).snapshot();
 8809        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8810
 8811        let server_ids = buffer.update(cx, |buffer, cx| {
 8812            local
 8813                .language_servers_for_buffer(buffer, cx)
 8814                .filter(|(adapter, _)| {
 8815                    scope
 8816                        .as_ref()
 8817                        .map(|scope| scope.language_allowed(&adapter.name))
 8818                        .unwrap_or(true)
 8819                })
 8820                .map(|(_, server)| server.server_id())
 8821                .filter(|server_id| {
 8822                    self.as_local().is_none_or(|local| {
 8823                        local
 8824                            .buffers_opened_in_servers
 8825                            .get(&snapshot.remote_id())
 8826                            .is_some_and(|servers| servers.contains(server_id))
 8827                    })
 8828                })
 8829                .collect::<Vec<_>>()
 8830        });
 8831
 8832        let mut response_results = server_ids
 8833            .into_iter()
 8834            .map(|server_id| {
 8835                let task = self.request_lsp(
 8836                    buffer.clone(),
 8837                    LanguageServerToQuery::Other(server_id),
 8838                    request.clone(),
 8839                    cx,
 8840                );
 8841                async move { (server_id, task.await) }
 8842            })
 8843            .collect::<FuturesUnordered<_>>();
 8844
 8845        cx.background_spawn(async move {
 8846            let mut responses = Vec::with_capacity(response_results.len());
 8847            while let Some((server_id, response_result)) = response_results.next().await {
 8848                match response_result {
 8849                    Ok(response) => responses.push((server_id, response)),
 8850                    // rust-analyzer likes to error with this when its still loading up
 8851                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8852                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8853                }
 8854            }
 8855            responses
 8856        })
 8857    }
 8858
 8859    async fn handle_lsp_get_completions(
 8860        this: Entity<Self>,
 8861        envelope: TypedEnvelope<proto::GetCompletions>,
 8862        mut cx: AsyncApp,
 8863    ) -> Result<proto::GetCompletionsResponse> {
 8864        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8865
 8866        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8867        let buffer_handle = this.update(&mut cx, |this, cx| {
 8868            this.buffer_store.read(cx).get_existing(buffer_id)
 8869        })?;
 8870        let request = GetCompletions::from_proto(
 8871            envelope.payload,
 8872            this.clone(),
 8873            buffer_handle.clone(),
 8874            cx.clone(),
 8875        )
 8876        .await?;
 8877
 8878        let server_to_query = match request.server_id {
 8879            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8880            None => LanguageServerToQuery::FirstCapable,
 8881        };
 8882
 8883        let response = this
 8884            .update(&mut cx, |this, cx| {
 8885                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8886            })
 8887            .await?;
 8888        this.update(&mut cx, |this, cx| {
 8889            Ok(GetCompletions::response_to_proto(
 8890                response,
 8891                this,
 8892                sender_id,
 8893                &buffer_handle.read(cx).version(),
 8894                cx,
 8895            ))
 8896        })
 8897    }
 8898
 8899    async fn handle_lsp_command<T: LspCommand>(
 8900        this: Entity<Self>,
 8901        envelope: TypedEnvelope<T::ProtoRequest>,
 8902        mut cx: AsyncApp,
 8903    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8904    where
 8905        <T::LspRequest as lsp::request::Request>::Params: Send,
 8906        <T::LspRequest as lsp::request::Request>::Result: Send,
 8907    {
 8908        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8909        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8910        let buffer_handle = this.update(&mut cx, |this, cx| {
 8911            this.buffer_store.read(cx).get_existing(buffer_id)
 8912        })?;
 8913        let request = T::from_proto(
 8914            envelope.payload,
 8915            this.clone(),
 8916            buffer_handle.clone(),
 8917            cx.clone(),
 8918        )
 8919        .await?;
 8920        let response = this
 8921            .update(&mut cx, |this, cx| {
 8922                this.request_lsp(
 8923                    buffer_handle.clone(),
 8924                    LanguageServerToQuery::FirstCapable,
 8925                    request,
 8926                    cx,
 8927                )
 8928            })
 8929            .await?;
 8930        this.update(&mut cx, |this, cx| {
 8931            Ok(T::response_to_proto(
 8932                response,
 8933                this,
 8934                sender_id,
 8935                &buffer_handle.read(cx).version(),
 8936                cx,
 8937            ))
 8938        })
 8939    }
 8940
 8941    async fn handle_lsp_query(
 8942        lsp_store: Entity<Self>,
 8943        envelope: TypedEnvelope<proto::LspQuery>,
 8944        mut cx: AsyncApp,
 8945    ) -> Result<proto::Ack> {
 8946        use proto::lsp_query::Request;
 8947        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8948        let lsp_query = envelope.payload;
 8949        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8950        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8951        match lsp_query.request.context("invalid LSP query request")? {
 8952            Request::GetReferences(get_references) => {
 8953                let position = get_references.position.clone().and_then(deserialize_anchor);
 8954                Self::query_lsp_locally::<GetReferences>(
 8955                    lsp_store,
 8956                    server_id,
 8957                    sender_id,
 8958                    lsp_request_id,
 8959                    get_references,
 8960                    position,
 8961                    &mut cx,
 8962                )
 8963                .await?;
 8964            }
 8965            Request::GetDocumentColor(get_document_color) => {
 8966                Self::query_lsp_locally::<GetDocumentColor>(
 8967                    lsp_store,
 8968                    server_id,
 8969                    sender_id,
 8970                    lsp_request_id,
 8971                    get_document_color,
 8972                    None,
 8973                    &mut cx,
 8974                )
 8975                .await?;
 8976            }
 8977            Request::GetHover(get_hover) => {
 8978                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8979                Self::query_lsp_locally::<GetHover>(
 8980                    lsp_store,
 8981                    server_id,
 8982                    sender_id,
 8983                    lsp_request_id,
 8984                    get_hover,
 8985                    position,
 8986                    &mut cx,
 8987                )
 8988                .await?;
 8989            }
 8990            Request::GetCodeActions(get_code_actions) => {
 8991                Self::query_lsp_locally::<GetCodeActions>(
 8992                    lsp_store,
 8993                    server_id,
 8994                    sender_id,
 8995                    lsp_request_id,
 8996                    get_code_actions,
 8997                    None,
 8998                    &mut cx,
 8999                )
 9000                .await?;
 9001            }
 9002            Request::GetSignatureHelp(get_signature_help) => {
 9003                let position = get_signature_help
 9004                    .position
 9005                    .clone()
 9006                    .and_then(deserialize_anchor);
 9007                Self::query_lsp_locally::<GetSignatureHelp>(
 9008                    lsp_store,
 9009                    server_id,
 9010                    sender_id,
 9011                    lsp_request_id,
 9012                    get_signature_help,
 9013                    position,
 9014                    &mut cx,
 9015                )
 9016                .await?;
 9017            }
 9018            Request::GetCodeLens(get_code_lens) => {
 9019                Self::query_lsp_locally::<GetCodeLens>(
 9020                    lsp_store,
 9021                    server_id,
 9022                    sender_id,
 9023                    lsp_request_id,
 9024                    get_code_lens,
 9025                    None,
 9026                    &mut cx,
 9027                )
 9028                .await?;
 9029            }
 9030            Request::GetDefinition(get_definition) => {
 9031                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9032                Self::query_lsp_locally::<GetDefinitions>(
 9033                    lsp_store,
 9034                    server_id,
 9035                    sender_id,
 9036                    lsp_request_id,
 9037                    get_definition,
 9038                    position,
 9039                    &mut cx,
 9040                )
 9041                .await?;
 9042            }
 9043            Request::GetDeclaration(get_declaration) => {
 9044                let position = get_declaration
 9045                    .position
 9046                    .clone()
 9047                    .and_then(deserialize_anchor);
 9048                Self::query_lsp_locally::<GetDeclarations>(
 9049                    lsp_store,
 9050                    server_id,
 9051                    sender_id,
 9052                    lsp_request_id,
 9053                    get_declaration,
 9054                    position,
 9055                    &mut cx,
 9056                )
 9057                .await?;
 9058            }
 9059            Request::GetTypeDefinition(get_type_definition) => {
 9060                let position = get_type_definition
 9061                    .position
 9062                    .clone()
 9063                    .and_then(deserialize_anchor);
 9064                Self::query_lsp_locally::<GetTypeDefinitions>(
 9065                    lsp_store,
 9066                    server_id,
 9067                    sender_id,
 9068                    lsp_request_id,
 9069                    get_type_definition,
 9070                    position,
 9071                    &mut cx,
 9072                )
 9073                .await?;
 9074            }
 9075            Request::GetImplementation(get_implementation) => {
 9076                let position = get_implementation
 9077                    .position
 9078                    .clone()
 9079                    .and_then(deserialize_anchor);
 9080                Self::query_lsp_locally::<GetImplementations>(
 9081                    lsp_store,
 9082                    server_id,
 9083                    sender_id,
 9084                    lsp_request_id,
 9085                    get_implementation,
 9086                    position,
 9087                    &mut cx,
 9088                )
 9089                .await?;
 9090            }
 9091            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9092                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 9093                let version = deserialize_version(get_document_diagnostics.buffer_version());
 9094                let buffer = lsp_store.update(&mut cx, |this, cx| {
 9095                    this.buffer_store.read(cx).get_existing(buffer_id)
 9096                })?;
 9097                buffer
 9098                    .update(&mut cx, |buffer, _| {
 9099                        buffer.wait_for_version(version.clone())
 9100                    })
 9101                    .await?;
 9102                lsp_store.update(&mut cx, |lsp_store, cx| {
 9103                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9104                    let key = LspKey {
 9105                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9106                        server_queried: server_id,
 9107                    };
 9108                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9109                    ) {
 9110                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9111                            lsp_requests.clear();
 9112                        };
 9113                    }
 9114
 9115                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 9116                    existing_queries.insert(
 9117                        lsp_request_id,
 9118                        cx.spawn(async move |lsp_store, cx| {
 9119                            let diagnostics_pull = lsp_store.update(cx, |lsp_store, cx| {
 9120                                lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9121                            });
 9122                            if let Ok(diagnostics_pull) = diagnostics_pull {
 9123                                match diagnostics_pull.await {
 9124                                    Ok(()) => {}
 9125                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9126                                };
 9127                            }
 9128                        }),
 9129                    );
 9130                });
 9131            }
 9132            Request::InlayHints(inlay_hints) => {
 9133                let query_start = inlay_hints
 9134                    .start
 9135                    .clone()
 9136                    .and_then(deserialize_anchor)
 9137                    .context("invalid inlay hints range start")?;
 9138                let query_end = inlay_hints
 9139                    .end
 9140                    .clone()
 9141                    .and_then(deserialize_anchor)
 9142                    .context("invalid inlay hints range end")?;
 9143                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9144                    &lsp_store,
 9145                    server_id,
 9146                    lsp_request_id,
 9147                    &inlay_hints,
 9148                    query_start..query_end,
 9149                    &mut cx,
 9150                )
 9151                .await
 9152                .context("preparing inlay hints request")?;
 9153                Self::query_lsp_locally::<InlayHints>(
 9154                    lsp_store,
 9155                    server_id,
 9156                    sender_id,
 9157                    lsp_request_id,
 9158                    inlay_hints,
 9159                    None,
 9160                    &mut cx,
 9161                )
 9162                .await
 9163                .context("querying for inlay hints")?
 9164            }
 9165        }
 9166        Ok(proto::Ack {})
 9167    }
 9168
 9169    async fn handle_lsp_query_response(
 9170        lsp_store: Entity<Self>,
 9171        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9172        cx: AsyncApp,
 9173    ) -> Result<()> {
 9174        lsp_store.read_with(&cx, |lsp_store, _| {
 9175            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9176                upstream_client.handle_lsp_response(envelope.clone());
 9177            }
 9178        });
 9179        Ok(())
 9180    }
 9181
 9182    async fn handle_apply_code_action(
 9183        this: Entity<Self>,
 9184        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9185        mut cx: AsyncApp,
 9186    ) -> Result<proto::ApplyCodeActionResponse> {
 9187        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9188        let action =
 9189            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9190        let apply_code_action = this.update(&mut cx, |this, cx| {
 9191            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9192            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9193            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9194        })?;
 9195
 9196        let project_transaction = apply_code_action.await?;
 9197        let project_transaction = this.update(&mut cx, |this, cx| {
 9198            this.buffer_store.update(cx, |buffer_store, cx| {
 9199                buffer_store.serialize_project_transaction_for_peer(
 9200                    project_transaction,
 9201                    sender_id,
 9202                    cx,
 9203                )
 9204            })
 9205        });
 9206        Ok(proto::ApplyCodeActionResponse {
 9207            transaction: Some(project_transaction),
 9208        })
 9209    }
 9210
 9211    async fn handle_register_buffer_with_language_servers(
 9212        this: Entity<Self>,
 9213        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9214        mut cx: AsyncApp,
 9215    ) -> Result<proto::Ack> {
 9216        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9217        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9218        this.update(&mut cx, |this, cx| {
 9219            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9220                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9221                    project_id: upstream_project_id,
 9222                    buffer_id: buffer_id.to_proto(),
 9223                    only_servers: envelope.payload.only_servers,
 9224                });
 9225            }
 9226
 9227            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9228                anyhow::bail!("buffer is not open");
 9229            };
 9230
 9231            let handle = this.register_buffer_with_language_servers(
 9232                &buffer,
 9233                envelope
 9234                    .payload
 9235                    .only_servers
 9236                    .into_iter()
 9237                    .filter_map(|selector| {
 9238                        Some(match selector.selector? {
 9239                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9240                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9241                            }
 9242                            proto::language_server_selector::Selector::Name(name) => {
 9243                                LanguageServerSelector::Name(LanguageServerName(
 9244                                    SharedString::from(name),
 9245                                ))
 9246                            }
 9247                        })
 9248                    })
 9249                    .collect(),
 9250                false,
 9251                cx,
 9252            );
 9253            this.buffer_store().update(cx, |buffer_store, _| {
 9254                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9255            });
 9256
 9257            Ok(())
 9258        })?;
 9259        Ok(proto::Ack {})
 9260    }
 9261
 9262    async fn handle_rename_project_entry(
 9263        this: Entity<Self>,
 9264        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9265        mut cx: AsyncApp,
 9266    ) -> Result<proto::ProjectEntryResponse> {
 9267        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9268        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9269        let new_path =
 9270            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9271
 9272        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9273            .update(&mut cx, |this, cx| {
 9274                let (worktree, entry) = this
 9275                    .worktree_store
 9276                    .read(cx)
 9277                    .worktree_and_entry_for_id(entry_id, cx)?;
 9278                let new_worktree = this
 9279                    .worktree_store
 9280                    .read(cx)
 9281                    .worktree_for_id(new_worktree_id, cx)?;
 9282                Some((
 9283                    this.worktree_store.clone(),
 9284                    worktree,
 9285                    new_worktree,
 9286                    entry.clone(),
 9287                ))
 9288            })
 9289            .context("worktree not found")?;
 9290        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9291            (worktree.absolutize(&old_entry.path), worktree.id())
 9292        });
 9293        let new_abs_path =
 9294            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9295
 9296        let _transaction = Self::will_rename_entry(
 9297            this.downgrade(),
 9298            old_worktree_id,
 9299            &old_abs_path,
 9300            &new_abs_path,
 9301            old_entry.is_dir(),
 9302            cx.clone(),
 9303        )
 9304        .await;
 9305        let response = WorktreeStore::handle_rename_project_entry(
 9306            worktree_store,
 9307            envelope.payload,
 9308            cx.clone(),
 9309        )
 9310        .await;
 9311        this.read_with(&cx, |this, _| {
 9312            this.did_rename_entry(
 9313                old_worktree_id,
 9314                &old_abs_path,
 9315                &new_abs_path,
 9316                old_entry.is_dir(),
 9317            );
 9318        });
 9319        response
 9320    }
 9321
 9322    async fn handle_update_diagnostic_summary(
 9323        this: Entity<Self>,
 9324        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9325        mut cx: AsyncApp,
 9326    ) -> Result<()> {
 9327        this.update(&mut cx, |lsp_store, cx| {
 9328            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9329            let mut updated_diagnostics_paths = HashMap::default();
 9330            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9331            for message_summary in envelope
 9332                .payload
 9333                .summary
 9334                .into_iter()
 9335                .chain(envelope.payload.more_summaries)
 9336            {
 9337                let project_path = ProjectPath {
 9338                    worktree_id,
 9339                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9340                };
 9341                let path = project_path.path.clone();
 9342                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9343                let summary = DiagnosticSummary {
 9344                    error_count: message_summary.error_count as usize,
 9345                    warning_count: message_summary.warning_count as usize,
 9346                };
 9347
 9348                if summary.is_empty() {
 9349                    if let Some(worktree_summaries) =
 9350                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9351                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9352                    {
 9353                        summaries.remove(&server_id);
 9354                        if summaries.is_empty() {
 9355                            worktree_summaries.remove(&path);
 9356                        }
 9357                    }
 9358                } else {
 9359                    lsp_store
 9360                        .diagnostic_summaries
 9361                        .entry(worktree_id)
 9362                        .or_default()
 9363                        .entry(path)
 9364                        .or_default()
 9365                        .insert(server_id, summary);
 9366                }
 9367
 9368                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9369                    match &mut diagnostics_summary {
 9370                        Some(diagnostics_summary) => {
 9371                            diagnostics_summary
 9372                                .more_summaries
 9373                                .push(proto::DiagnosticSummary {
 9374                                    path: project_path.path.as_ref().to_proto(),
 9375                                    language_server_id: server_id.0 as u64,
 9376                                    error_count: summary.error_count as u32,
 9377                                    warning_count: summary.warning_count as u32,
 9378                                })
 9379                        }
 9380                        None => {
 9381                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9382                                project_id: *project_id,
 9383                                worktree_id: worktree_id.to_proto(),
 9384                                summary: Some(proto::DiagnosticSummary {
 9385                                    path: project_path.path.as_ref().to_proto(),
 9386                                    language_server_id: server_id.0 as u64,
 9387                                    error_count: summary.error_count as u32,
 9388                                    warning_count: summary.warning_count as u32,
 9389                                }),
 9390                                more_summaries: Vec::new(),
 9391                            })
 9392                        }
 9393                    }
 9394                }
 9395                updated_diagnostics_paths
 9396                    .entry(server_id)
 9397                    .or_insert_with(Vec::new)
 9398                    .push(project_path);
 9399            }
 9400
 9401            if let Some((diagnostics_summary, (downstream_client, _))) =
 9402                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9403            {
 9404                downstream_client.send(diagnostics_summary).log_err();
 9405            }
 9406            for (server_id, paths) in updated_diagnostics_paths {
 9407                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9408            }
 9409            Ok(())
 9410        })
 9411    }
 9412
 9413    async fn handle_start_language_server(
 9414        lsp_store: Entity<Self>,
 9415        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9416        mut cx: AsyncApp,
 9417    ) -> Result<()> {
 9418        let server = envelope.payload.server.context("invalid server")?;
 9419        let server_capabilities =
 9420            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9421                .with_context(|| {
 9422                    format!(
 9423                        "incorrect server capabilities {}",
 9424                        envelope.payload.capabilities
 9425                    )
 9426                })?;
 9427        lsp_store.update(&mut cx, |lsp_store, cx| {
 9428            let server_id = LanguageServerId(server.id as usize);
 9429            let server_name = LanguageServerName::from_proto(server.name.clone());
 9430            lsp_store
 9431                .lsp_server_capabilities
 9432                .insert(server_id, server_capabilities);
 9433            lsp_store.language_server_statuses.insert(
 9434                server_id,
 9435                LanguageServerStatus {
 9436                    name: server_name.clone(),
 9437                    server_version: None,
 9438                    pending_work: Default::default(),
 9439                    has_pending_diagnostic_updates: false,
 9440                    progress_tokens: Default::default(),
 9441                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9442                    binary: None,
 9443                    configuration: None,
 9444                    workspace_folders: BTreeSet::new(),
 9445                },
 9446            );
 9447            cx.emit(LspStoreEvent::LanguageServerAdded(
 9448                server_id,
 9449                server_name,
 9450                server.worktree_id.map(WorktreeId::from_proto),
 9451            ));
 9452            cx.notify();
 9453        });
 9454        Ok(())
 9455    }
 9456
 9457    async fn handle_update_language_server(
 9458        lsp_store: Entity<Self>,
 9459        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9460        mut cx: AsyncApp,
 9461    ) -> Result<()> {
 9462        lsp_store.update(&mut cx, |lsp_store, cx| {
 9463            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9464
 9465            match envelope.payload.variant.context("invalid variant")? {
 9466                proto::update_language_server::Variant::WorkStart(payload) => {
 9467                    lsp_store.on_lsp_work_start(
 9468                        language_server_id,
 9469                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9470                            .context("invalid progress token value")?,
 9471                        LanguageServerProgress {
 9472                            title: payload.title,
 9473                            is_disk_based_diagnostics_progress: false,
 9474                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9475                            message: payload.message,
 9476                            percentage: payload.percentage.map(|p| p as usize),
 9477                            last_update_at: cx.background_executor().now(),
 9478                        },
 9479                        cx,
 9480                    );
 9481                }
 9482                proto::update_language_server::Variant::WorkProgress(payload) => {
 9483                    lsp_store.on_lsp_work_progress(
 9484                        language_server_id,
 9485                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9486                            .context("invalid progress token value")?,
 9487                        LanguageServerProgress {
 9488                            title: None,
 9489                            is_disk_based_diagnostics_progress: false,
 9490                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9491                            message: payload.message,
 9492                            percentage: payload.percentage.map(|p| p as usize),
 9493                            last_update_at: cx.background_executor().now(),
 9494                        },
 9495                        cx,
 9496                    );
 9497                }
 9498
 9499                proto::update_language_server::Variant::WorkEnd(payload) => {
 9500                    lsp_store.on_lsp_work_end(
 9501                        language_server_id,
 9502                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9503                            .context("invalid progress token value")?,
 9504                        cx,
 9505                    );
 9506                }
 9507
 9508                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9509                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9510                }
 9511
 9512                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9513                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9514                }
 9515
 9516                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9517                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9518                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9519                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9520                        language_server_id,
 9521                        name: envelope
 9522                            .payload
 9523                            .server_name
 9524                            .map(SharedString::new)
 9525                            .map(LanguageServerName),
 9526                        message: non_lsp,
 9527                    });
 9528                }
 9529            }
 9530
 9531            Ok(())
 9532        })
 9533    }
 9534
 9535    async fn handle_language_server_log(
 9536        this: Entity<Self>,
 9537        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9538        mut cx: AsyncApp,
 9539    ) -> Result<()> {
 9540        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9541        let log_type = envelope
 9542            .payload
 9543            .log_type
 9544            .map(LanguageServerLogType::from_proto)
 9545            .context("invalid language server log type")?;
 9546
 9547        let message = envelope.payload.message;
 9548
 9549        this.update(&mut cx, |_, cx| {
 9550            cx.emit(LspStoreEvent::LanguageServerLog(
 9551                language_server_id,
 9552                log_type,
 9553                message,
 9554            ));
 9555        });
 9556        Ok(())
 9557    }
 9558
 9559    async fn handle_lsp_ext_cancel_flycheck(
 9560        lsp_store: Entity<Self>,
 9561        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9562        cx: AsyncApp,
 9563    ) -> Result<proto::Ack> {
 9564        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9565        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9566            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9567                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9568            } else {
 9569                None
 9570            }
 9571        });
 9572        if let Some(task) = task {
 9573            task.context("handling lsp ext cancel flycheck")?;
 9574        }
 9575
 9576        Ok(proto::Ack {})
 9577    }
 9578
 9579    async fn handle_lsp_ext_run_flycheck(
 9580        lsp_store: Entity<Self>,
 9581        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9582        mut cx: AsyncApp,
 9583    ) -> Result<proto::Ack> {
 9584        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9585        lsp_store.update(&mut cx, |lsp_store, cx| {
 9586            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9587                let text_document = if envelope.payload.current_file_only {
 9588                    let buffer_id = envelope
 9589                        .payload
 9590                        .buffer_id
 9591                        .map(|id| BufferId::new(id))
 9592                        .transpose()?;
 9593                    buffer_id
 9594                        .and_then(|buffer_id| {
 9595                            lsp_store
 9596                                .buffer_store()
 9597                                .read(cx)
 9598                                .get(buffer_id)
 9599                                .and_then(|buffer| {
 9600                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9601                                })
 9602                                .map(|path| make_text_document_identifier(&path))
 9603                        })
 9604                        .transpose()?
 9605                } else {
 9606                    None
 9607                };
 9608                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9609                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9610                )?;
 9611            }
 9612            anyhow::Ok(())
 9613        })?;
 9614
 9615        Ok(proto::Ack {})
 9616    }
 9617
 9618    async fn handle_lsp_ext_clear_flycheck(
 9619        lsp_store: Entity<Self>,
 9620        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9621        cx: AsyncApp,
 9622    ) -> Result<proto::Ack> {
 9623        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9624        lsp_store.read_with(&cx, |lsp_store, _| {
 9625            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9626                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9627            } else {
 9628                None
 9629            }
 9630        });
 9631
 9632        Ok(proto::Ack {})
 9633    }
 9634
 9635    pub fn disk_based_diagnostics_started(
 9636        &mut self,
 9637        language_server_id: LanguageServerId,
 9638        cx: &mut Context<Self>,
 9639    ) {
 9640        if let Some(language_server_status) =
 9641            self.language_server_statuses.get_mut(&language_server_id)
 9642        {
 9643            language_server_status.has_pending_diagnostic_updates = true;
 9644        }
 9645
 9646        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9647        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9648            language_server_id,
 9649            name: self
 9650                .language_server_adapter_for_id(language_server_id)
 9651                .map(|adapter| adapter.name()),
 9652            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9653                Default::default(),
 9654            ),
 9655        })
 9656    }
 9657
 9658    pub fn disk_based_diagnostics_finished(
 9659        &mut self,
 9660        language_server_id: LanguageServerId,
 9661        cx: &mut Context<Self>,
 9662    ) {
 9663        if let Some(language_server_status) =
 9664            self.language_server_statuses.get_mut(&language_server_id)
 9665        {
 9666            language_server_status.has_pending_diagnostic_updates = false;
 9667        }
 9668
 9669        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9670        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9671            language_server_id,
 9672            name: self
 9673                .language_server_adapter_for_id(language_server_id)
 9674                .map(|adapter| adapter.name()),
 9675            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9676                Default::default(),
 9677            ),
 9678        })
 9679    }
 9680
 9681    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9682    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9683    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9684    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9685    // the language server might take some time to publish diagnostics.
 9686    fn simulate_disk_based_diagnostics_events_if_needed(
 9687        &mut self,
 9688        language_server_id: LanguageServerId,
 9689        cx: &mut Context<Self>,
 9690    ) {
 9691        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9692
 9693        let Some(LanguageServerState::Running {
 9694            simulate_disk_based_diagnostics_completion,
 9695            adapter,
 9696            ..
 9697        }) = self
 9698            .as_local_mut()
 9699            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9700        else {
 9701            return;
 9702        };
 9703
 9704        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9705            return;
 9706        }
 9707
 9708        let prev_task =
 9709            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9710                cx.background_executor()
 9711                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9712                    .await;
 9713
 9714                this.update(cx, |this, cx| {
 9715                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9716
 9717                    if let Some(LanguageServerState::Running {
 9718                        simulate_disk_based_diagnostics_completion,
 9719                        ..
 9720                    }) = this.as_local_mut().and_then(|local_store| {
 9721                        local_store.language_servers.get_mut(&language_server_id)
 9722                    }) {
 9723                        *simulate_disk_based_diagnostics_completion = None;
 9724                    }
 9725                })
 9726                .ok();
 9727            }));
 9728
 9729        if prev_task.is_none() {
 9730            self.disk_based_diagnostics_started(language_server_id, cx);
 9731        }
 9732    }
 9733
 9734    pub fn language_server_statuses(
 9735        &self,
 9736    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9737        self.language_server_statuses
 9738            .iter()
 9739            .map(|(key, value)| (*key, value))
 9740    }
 9741
 9742    pub(super) fn did_rename_entry(
 9743        &self,
 9744        worktree_id: WorktreeId,
 9745        old_path: &Path,
 9746        new_path: &Path,
 9747        is_dir: bool,
 9748    ) {
 9749        maybe!({
 9750            let local_store = self.as_local()?;
 9751
 9752            let old_uri = lsp::Uri::from_file_path(old_path)
 9753                .ok()
 9754                .map(|uri| uri.to_string())?;
 9755            let new_uri = lsp::Uri::from_file_path(new_path)
 9756                .ok()
 9757                .map(|uri| uri.to_string())?;
 9758
 9759            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9760                let Some(filter) = local_store
 9761                    .language_server_paths_watched_for_rename
 9762                    .get(&language_server.server_id())
 9763                else {
 9764                    continue;
 9765                };
 9766
 9767                if filter.should_send_did_rename(&old_uri, is_dir) {
 9768                    language_server
 9769                        .notify::<DidRenameFiles>(RenameFilesParams {
 9770                            files: vec![FileRename {
 9771                                old_uri: old_uri.clone(),
 9772                                new_uri: new_uri.clone(),
 9773                            }],
 9774                        })
 9775                        .ok();
 9776                }
 9777            }
 9778            Some(())
 9779        });
 9780    }
 9781
 9782    pub(super) fn will_rename_entry(
 9783        this: WeakEntity<Self>,
 9784        worktree_id: WorktreeId,
 9785        old_path: &Path,
 9786        new_path: &Path,
 9787        is_dir: bool,
 9788        cx: AsyncApp,
 9789    ) -> Task<ProjectTransaction> {
 9790        let old_uri = lsp::Uri::from_file_path(old_path)
 9791            .ok()
 9792            .map(|uri| uri.to_string());
 9793        let new_uri = lsp::Uri::from_file_path(new_path)
 9794            .ok()
 9795            .map(|uri| uri.to_string());
 9796        cx.spawn(async move |cx| {
 9797            let mut tasks = vec![];
 9798            this.update(cx, |this, cx| {
 9799                let local_store = this.as_local()?;
 9800                let old_uri = old_uri?;
 9801                let new_uri = new_uri?;
 9802                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9803                    let Some(filter) = local_store
 9804                        .language_server_paths_watched_for_rename
 9805                        .get(&language_server.server_id())
 9806                    else {
 9807                        continue;
 9808                    };
 9809
 9810                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9811                        let apply_edit = cx.spawn({
 9812                            let old_uri = old_uri.clone();
 9813                            let new_uri = new_uri.clone();
 9814                            let language_server = language_server.clone();
 9815                            async move |this, cx| {
 9816                                let edit = language_server
 9817                                    .request::<WillRenameFiles>(RenameFilesParams {
 9818                                        files: vec![FileRename { old_uri, new_uri }],
 9819                                    })
 9820                                    .await
 9821                                    .into_response()
 9822                                    .context("will rename files")
 9823                                    .log_err()
 9824                                    .flatten()?;
 9825
 9826                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9827                                    this.upgrade()?,
 9828                                    edit,
 9829                                    false,
 9830                                    language_server.clone(),
 9831                                    cx,
 9832                                )
 9833                                .await
 9834                                .ok()?;
 9835                                Some(transaction)
 9836                            }
 9837                        });
 9838                        tasks.push(apply_edit);
 9839                    }
 9840                }
 9841                Some(())
 9842            })
 9843            .ok()
 9844            .flatten();
 9845            let mut merged_transaction = ProjectTransaction::default();
 9846            for task in tasks {
 9847                // Await on tasks sequentially so that the order of application of edits is deterministic
 9848                // (at least with regards to the order of registration of language servers)
 9849                if let Some(transaction) = task.await {
 9850                    for (buffer, buffer_transaction) in transaction.0 {
 9851                        merged_transaction.0.insert(buffer, buffer_transaction);
 9852                    }
 9853                }
 9854            }
 9855            merged_transaction
 9856        })
 9857    }
 9858
 9859    fn lsp_notify_abs_paths_changed(
 9860        &mut self,
 9861        server_id: LanguageServerId,
 9862        changes: Vec<PathEvent>,
 9863    ) {
 9864        maybe!({
 9865            let server = self.language_server_for_id(server_id)?;
 9866            let changes = changes
 9867                .into_iter()
 9868                .filter_map(|event| {
 9869                    let typ = match event.kind? {
 9870                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9871                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9872                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9873                    };
 9874                    Some(lsp::FileEvent {
 9875                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9876                        typ,
 9877                    })
 9878                })
 9879                .collect::<Vec<_>>();
 9880            if !changes.is_empty() {
 9881                server
 9882                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9883                        lsp::DidChangeWatchedFilesParams { changes },
 9884                    )
 9885                    .ok();
 9886            }
 9887            Some(())
 9888        });
 9889    }
 9890
 9891    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9892        self.as_local()?.language_server_for_id(id)
 9893    }
 9894
 9895    fn on_lsp_progress(
 9896        &mut self,
 9897        progress_params: lsp::ProgressParams,
 9898        language_server_id: LanguageServerId,
 9899        disk_based_diagnostics_progress_token: Option<String>,
 9900        cx: &mut Context<Self>,
 9901    ) {
 9902        match progress_params.value {
 9903            lsp::ProgressParamsValue::WorkDone(progress) => {
 9904                self.handle_work_done_progress(
 9905                    progress,
 9906                    language_server_id,
 9907                    disk_based_diagnostics_progress_token,
 9908                    ProgressToken::from_lsp(progress_params.token),
 9909                    cx,
 9910                );
 9911            }
 9912            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9913                let registration_id = match progress_params.token {
 9914                    lsp::NumberOrString::Number(_) => None,
 9915                    lsp::NumberOrString::String(token) => token
 9916                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9917                        .map(|(_, id)| id.to_owned()),
 9918                };
 9919                if let Some(LanguageServerState::Running {
 9920                    workspace_diagnostics_refresh_tasks,
 9921                    ..
 9922                }) = self
 9923                    .as_local_mut()
 9924                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9925                    && let Some(workspace_diagnostics) =
 9926                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9927                {
 9928                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9929                    self.apply_workspace_diagnostic_report(
 9930                        language_server_id,
 9931                        report,
 9932                        registration_id.map(SharedString::from),
 9933                        cx,
 9934                    )
 9935                }
 9936            }
 9937        }
 9938    }
 9939
 9940    fn handle_work_done_progress(
 9941        &mut self,
 9942        progress: lsp::WorkDoneProgress,
 9943        language_server_id: LanguageServerId,
 9944        disk_based_diagnostics_progress_token: Option<String>,
 9945        token: ProgressToken,
 9946        cx: &mut Context<Self>,
 9947    ) {
 9948        let language_server_status =
 9949            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9950                status
 9951            } else {
 9952                return;
 9953            };
 9954
 9955        if !language_server_status.progress_tokens.contains(&token) {
 9956            return;
 9957        }
 9958
 9959        let is_disk_based_diagnostics_progress =
 9960            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9961                (&disk_based_diagnostics_progress_token, &token)
 9962            {
 9963                token.starts_with(disk_based_token)
 9964            } else {
 9965                false
 9966            };
 9967
 9968        match progress {
 9969            lsp::WorkDoneProgress::Begin(report) => {
 9970                if is_disk_based_diagnostics_progress {
 9971                    self.disk_based_diagnostics_started(language_server_id, cx);
 9972                }
 9973                self.on_lsp_work_start(
 9974                    language_server_id,
 9975                    token.clone(),
 9976                    LanguageServerProgress {
 9977                        title: Some(report.title),
 9978                        is_disk_based_diagnostics_progress,
 9979                        is_cancellable: report.cancellable.unwrap_or(false),
 9980                        message: report.message.clone(),
 9981                        percentage: report.percentage.map(|p| p as usize),
 9982                        last_update_at: cx.background_executor().now(),
 9983                    },
 9984                    cx,
 9985                );
 9986            }
 9987            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9988                language_server_id,
 9989                token,
 9990                LanguageServerProgress {
 9991                    title: None,
 9992                    is_disk_based_diagnostics_progress,
 9993                    is_cancellable: report.cancellable.unwrap_or(false),
 9994                    message: report.message,
 9995                    percentage: report.percentage.map(|p| p as usize),
 9996                    last_update_at: cx.background_executor().now(),
 9997                },
 9998                cx,
 9999            ),
10000            lsp::WorkDoneProgress::End(_) => {
10001                language_server_status.progress_tokens.remove(&token);
10002                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10003                if is_disk_based_diagnostics_progress {
10004                    self.disk_based_diagnostics_finished(language_server_id, cx);
10005                }
10006            }
10007        }
10008    }
10009
10010    fn on_lsp_work_start(
10011        &mut self,
10012        language_server_id: LanguageServerId,
10013        token: ProgressToken,
10014        progress: LanguageServerProgress,
10015        cx: &mut Context<Self>,
10016    ) {
10017        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10018            status.pending_work.insert(token.clone(), progress.clone());
10019            cx.notify();
10020        }
10021        cx.emit(LspStoreEvent::LanguageServerUpdate {
10022            language_server_id,
10023            name: self
10024                .language_server_adapter_for_id(language_server_id)
10025                .map(|adapter| adapter.name()),
10026            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10027                token: Some(token.to_proto()),
10028                title: progress.title,
10029                message: progress.message,
10030                percentage: progress.percentage.map(|p| p as u32),
10031                is_cancellable: Some(progress.is_cancellable),
10032            }),
10033        })
10034    }
10035
10036    fn on_lsp_work_progress(
10037        &mut self,
10038        language_server_id: LanguageServerId,
10039        token: ProgressToken,
10040        progress: LanguageServerProgress,
10041        cx: &mut Context<Self>,
10042    ) {
10043        let mut did_update = false;
10044        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10045            match status.pending_work.entry(token.clone()) {
10046                btree_map::Entry::Vacant(entry) => {
10047                    entry.insert(progress.clone());
10048                    did_update = true;
10049                }
10050                btree_map::Entry::Occupied(mut entry) => {
10051                    let entry = entry.get_mut();
10052                    if (progress.last_update_at - entry.last_update_at)
10053                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10054                    {
10055                        entry.last_update_at = progress.last_update_at;
10056                        if progress.message.is_some() {
10057                            entry.message = progress.message.clone();
10058                        }
10059                        if progress.percentage.is_some() {
10060                            entry.percentage = progress.percentage;
10061                        }
10062                        if progress.is_cancellable != entry.is_cancellable {
10063                            entry.is_cancellable = progress.is_cancellable;
10064                        }
10065                        did_update = true;
10066                    }
10067                }
10068            }
10069        }
10070
10071        if did_update {
10072            cx.emit(LspStoreEvent::LanguageServerUpdate {
10073                language_server_id,
10074                name: self
10075                    .language_server_adapter_for_id(language_server_id)
10076                    .map(|adapter| adapter.name()),
10077                message: proto::update_language_server::Variant::WorkProgress(
10078                    proto::LspWorkProgress {
10079                        token: Some(token.to_proto()),
10080                        message: progress.message,
10081                        percentage: progress.percentage.map(|p| p as u32),
10082                        is_cancellable: Some(progress.is_cancellable),
10083                    },
10084                ),
10085            })
10086        }
10087    }
10088
10089    fn on_lsp_work_end(
10090        &mut self,
10091        language_server_id: LanguageServerId,
10092        token: ProgressToken,
10093        cx: &mut Context<Self>,
10094    ) {
10095        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10096            if let Some(work) = status.pending_work.remove(&token)
10097                && !work.is_disk_based_diagnostics_progress
10098            {
10099                cx.emit(LspStoreEvent::RefreshInlayHints {
10100                    server_id: language_server_id,
10101                    request_id: None,
10102                });
10103            }
10104            cx.notify();
10105        }
10106
10107        cx.emit(LspStoreEvent::LanguageServerUpdate {
10108            language_server_id,
10109            name: self
10110                .language_server_adapter_for_id(language_server_id)
10111                .map(|adapter| adapter.name()),
10112            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10113                token: Some(token.to_proto()),
10114            }),
10115        })
10116    }
10117
10118    pub async fn handle_resolve_completion_documentation(
10119        this: Entity<Self>,
10120        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10121        mut cx: AsyncApp,
10122    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10123        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10124
10125        let completion = this
10126            .read_with(&cx, |this, cx| {
10127                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10128                let server = this
10129                    .language_server_for_id(id)
10130                    .with_context(|| format!("No language server {id}"))?;
10131
10132                anyhow::Ok(cx.background_spawn(async move {
10133                    let can_resolve = server
10134                        .capabilities()
10135                        .completion_provider
10136                        .as_ref()
10137                        .and_then(|options| options.resolve_provider)
10138                        .unwrap_or(false);
10139                    if can_resolve {
10140                        server
10141                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
10142                            .await
10143                            .into_response()
10144                            .context("resolve completion item")
10145                    } else {
10146                        anyhow::Ok(lsp_completion)
10147                    }
10148                }))
10149            })?
10150            .await?;
10151
10152        let mut documentation_is_markdown = false;
10153        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10154        let documentation = match completion.documentation {
10155            Some(lsp::Documentation::String(text)) => text,
10156
10157            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10158                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10159                value
10160            }
10161
10162            _ => String::new(),
10163        };
10164
10165        // If we have a new buffer_id, that means we're talking to a new client
10166        // and want to check for new text_edits in the completion too.
10167        let mut old_replace_start = None;
10168        let mut old_replace_end = None;
10169        let mut old_insert_start = None;
10170        let mut old_insert_end = None;
10171        let mut new_text = String::default();
10172        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10173            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10174                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10175                anyhow::Ok(buffer.read(cx).snapshot())
10176            })?;
10177
10178            if let Some(text_edit) = completion.text_edit.as_ref() {
10179                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10180
10181                if let Some(mut edit) = edit {
10182                    LineEnding::normalize(&mut edit.new_text);
10183
10184                    new_text = edit.new_text;
10185                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10186                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10187                    if let Some(insert_range) = edit.insert_range {
10188                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10189                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10190                    }
10191                }
10192            }
10193        }
10194
10195        Ok(proto::ResolveCompletionDocumentationResponse {
10196            documentation,
10197            documentation_is_markdown,
10198            old_replace_start,
10199            old_replace_end,
10200            new_text,
10201            lsp_completion,
10202            old_insert_start,
10203            old_insert_end,
10204        })
10205    }
10206
10207    async fn handle_on_type_formatting(
10208        this: Entity<Self>,
10209        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10210        mut cx: AsyncApp,
10211    ) -> Result<proto::OnTypeFormattingResponse> {
10212        let on_type_formatting = this.update(&mut cx, |this, cx| {
10213            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10214            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10215            let position = envelope
10216                .payload
10217                .position
10218                .and_then(deserialize_anchor)
10219                .context("invalid position")?;
10220            anyhow::Ok(this.apply_on_type_formatting(
10221                buffer,
10222                position,
10223                envelope.payload.trigger.clone(),
10224                cx,
10225            ))
10226        })?;
10227
10228        let transaction = on_type_formatting
10229            .await?
10230            .as_ref()
10231            .map(language::proto::serialize_transaction);
10232        Ok(proto::OnTypeFormattingResponse { transaction })
10233    }
10234
10235    async fn handle_refresh_inlay_hints(
10236        lsp_store: Entity<Self>,
10237        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10238        mut cx: AsyncApp,
10239    ) -> Result<proto::Ack> {
10240        lsp_store.update(&mut cx, |_, cx| {
10241            cx.emit(LspStoreEvent::RefreshInlayHints {
10242                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10243                request_id: envelope.payload.request_id.map(|id| id as usize),
10244            });
10245        });
10246        Ok(proto::Ack {})
10247    }
10248
10249    async fn handle_pull_workspace_diagnostics(
10250        lsp_store: Entity<Self>,
10251        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10252        mut cx: AsyncApp,
10253    ) -> Result<proto::Ack> {
10254        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10255        lsp_store.update(&mut cx, |lsp_store, _| {
10256            lsp_store.pull_workspace_diagnostics(server_id);
10257        });
10258        Ok(proto::Ack {})
10259    }
10260
10261    async fn handle_get_color_presentation(
10262        lsp_store: Entity<Self>,
10263        envelope: TypedEnvelope<proto::GetColorPresentation>,
10264        mut cx: AsyncApp,
10265    ) -> Result<proto::GetColorPresentationResponse> {
10266        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10267        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10268            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10269        })?;
10270
10271        let color = envelope
10272            .payload
10273            .color
10274            .context("invalid color resolve request")?;
10275        let start = color
10276            .lsp_range_start
10277            .context("invalid color resolve request")?;
10278        let end = color
10279            .lsp_range_end
10280            .context("invalid color resolve request")?;
10281
10282        let color = DocumentColor {
10283            lsp_range: lsp::Range {
10284                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10285                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10286            },
10287            color: lsp::Color {
10288                red: color.red,
10289                green: color.green,
10290                blue: color.blue,
10291                alpha: color.alpha,
10292            },
10293            resolved: false,
10294            color_presentations: Vec::new(),
10295        };
10296        let resolved_color = lsp_store
10297            .update(&mut cx, |lsp_store, cx| {
10298                lsp_store.resolve_color_presentation(
10299                    color,
10300                    buffer.clone(),
10301                    LanguageServerId(envelope.payload.server_id as usize),
10302                    cx,
10303                )
10304            })
10305            .await
10306            .context("resolving color presentation")?;
10307
10308        Ok(proto::GetColorPresentationResponse {
10309            presentations: resolved_color
10310                .color_presentations
10311                .into_iter()
10312                .map(|presentation| proto::ColorPresentation {
10313                    label: presentation.label.to_string(),
10314                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10315                    additional_text_edits: presentation
10316                        .additional_text_edits
10317                        .into_iter()
10318                        .map(serialize_lsp_edit)
10319                        .collect(),
10320                })
10321                .collect(),
10322        })
10323    }
10324
10325    async fn handle_resolve_inlay_hint(
10326        lsp_store: Entity<Self>,
10327        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10328        mut cx: AsyncApp,
10329    ) -> Result<proto::ResolveInlayHintResponse> {
10330        let proto_hint = envelope
10331            .payload
10332            .hint
10333            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10334        let hint = InlayHints::proto_to_project_hint(proto_hint)
10335            .context("resolved proto inlay hint conversion")?;
10336        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10337            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10338            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10339        })?;
10340        let response_hint = lsp_store
10341            .update(&mut cx, |lsp_store, cx| {
10342                lsp_store.resolve_inlay_hint(
10343                    hint,
10344                    buffer,
10345                    LanguageServerId(envelope.payload.language_server_id as usize),
10346                    cx,
10347                )
10348            })
10349            .await
10350            .context("inlay hints fetch")?;
10351        Ok(proto::ResolveInlayHintResponse {
10352            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10353        })
10354    }
10355
10356    async fn handle_refresh_code_lens(
10357        this: Entity<Self>,
10358        _: TypedEnvelope<proto::RefreshCodeLens>,
10359        mut cx: AsyncApp,
10360    ) -> Result<proto::Ack> {
10361        this.update(&mut cx, |_, cx| {
10362            cx.emit(LspStoreEvent::RefreshCodeLens);
10363        });
10364        Ok(proto::Ack {})
10365    }
10366
10367    async fn handle_open_buffer_for_symbol(
10368        this: Entity<Self>,
10369        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10370        mut cx: AsyncApp,
10371    ) -> Result<proto::OpenBufferForSymbolResponse> {
10372        let peer_id = envelope.original_sender_id().unwrap_or_default();
10373        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10374        let symbol = Self::deserialize_symbol(symbol)?;
10375        this.read_with(&cx, |this, _| {
10376            if let SymbolLocation::OutsideProject {
10377                abs_path,
10378                signature,
10379            } = &symbol.path
10380            {
10381                let new_signature = this.symbol_signature(&abs_path);
10382                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10383            }
10384            Ok(())
10385        })?;
10386        let buffer = this
10387            .update(&mut cx, |this, cx| {
10388                this.open_buffer_for_symbol(
10389                    &Symbol {
10390                        language_server_name: symbol.language_server_name,
10391                        source_worktree_id: symbol.source_worktree_id,
10392                        source_language_server_id: symbol.source_language_server_id,
10393                        path: symbol.path,
10394                        name: symbol.name,
10395                        kind: symbol.kind,
10396                        range: symbol.range,
10397                        label: CodeLabel::default(),
10398                    },
10399                    cx,
10400                )
10401            })
10402            .await?;
10403
10404        this.update(&mut cx, |this, cx| {
10405            let is_private = buffer
10406                .read(cx)
10407                .file()
10408                .map(|f| f.is_private())
10409                .unwrap_or_default();
10410            if is_private {
10411                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10412            } else {
10413                this.buffer_store
10414                    .update(cx, |buffer_store, cx| {
10415                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10416                    })
10417                    .detach_and_log_err(cx);
10418                let buffer_id = buffer.read(cx).remote_id().to_proto();
10419                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10420            }
10421        })
10422    }
10423
10424    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10425        let mut hasher = Sha256::new();
10426        hasher.update(abs_path.to_string_lossy().as_bytes());
10427        hasher.update(self.nonce.to_be_bytes());
10428        hasher.finalize().as_slice().try_into().unwrap()
10429    }
10430
10431    pub async fn handle_get_project_symbols(
10432        this: Entity<Self>,
10433        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10434        mut cx: AsyncApp,
10435    ) -> Result<proto::GetProjectSymbolsResponse> {
10436        let symbols = this
10437            .update(&mut cx, |this, cx| {
10438                this.symbols(&envelope.payload.query, cx)
10439            })
10440            .await?;
10441
10442        Ok(proto::GetProjectSymbolsResponse {
10443            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10444        })
10445    }
10446
10447    pub async fn handle_restart_language_servers(
10448        this: Entity<Self>,
10449        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10450        mut cx: AsyncApp,
10451    ) -> Result<proto::Ack> {
10452        this.update(&mut cx, |lsp_store, cx| {
10453            let buffers =
10454                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10455            lsp_store.restart_language_servers_for_buffers(
10456                buffers,
10457                envelope
10458                    .payload
10459                    .only_servers
10460                    .into_iter()
10461                    .filter_map(|selector| {
10462                        Some(match selector.selector? {
10463                            proto::language_server_selector::Selector::ServerId(server_id) => {
10464                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10465                            }
10466                            proto::language_server_selector::Selector::Name(name) => {
10467                                LanguageServerSelector::Name(LanguageServerName(
10468                                    SharedString::from(name),
10469                                ))
10470                            }
10471                        })
10472                    })
10473                    .collect(),
10474                cx,
10475            );
10476        });
10477
10478        Ok(proto::Ack {})
10479    }
10480
10481    pub async fn handle_stop_language_servers(
10482        lsp_store: Entity<Self>,
10483        envelope: TypedEnvelope<proto::StopLanguageServers>,
10484        mut cx: AsyncApp,
10485    ) -> Result<proto::Ack> {
10486        lsp_store.update(&mut cx, |lsp_store, cx| {
10487            if envelope.payload.all
10488                && envelope.payload.also_servers.is_empty()
10489                && envelope.payload.buffer_ids.is_empty()
10490            {
10491                lsp_store.stop_all_language_servers(cx);
10492            } else {
10493                let buffers =
10494                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10495                lsp_store
10496                    .stop_language_servers_for_buffers(
10497                        buffers,
10498                        envelope
10499                            .payload
10500                            .also_servers
10501                            .into_iter()
10502                            .filter_map(|selector| {
10503                                Some(match selector.selector? {
10504                                    proto::language_server_selector::Selector::ServerId(
10505                                        server_id,
10506                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10507                                        server_id,
10508                                    )),
10509                                    proto::language_server_selector::Selector::Name(name) => {
10510                                        LanguageServerSelector::Name(LanguageServerName(
10511                                            SharedString::from(name),
10512                                        ))
10513                                    }
10514                                })
10515                            })
10516                            .collect(),
10517                        cx,
10518                    )
10519                    .detach_and_log_err(cx);
10520            }
10521        });
10522
10523        Ok(proto::Ack {})
10524    }
10525
10526    pub async fn handle_cancel_language_server_work(
10527        lsp_store: Entity<Self>,
10528        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10529        mut cx: AsyncApp,
10530    ) -> Result<proto::Ack> {
10531        lsp_store.update(&mut cx, |lsp_store, cx| {
10532            if let Some(work) = envelope.payload.work {
10533                match work {
10534                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10535                        let buffers =
10536                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10537                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10538                    }
10539                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10540                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10541                        let token = work
10542                            .token
10543                            .map(|token| {
10544                                ProgressToken::from_proto(token)
10545                                    .context("invalid work progress token")
10546                            })
10547                            .transpose()?;
10548                        lsp_store.cancel_language_server_work(server_id, token, cx);
10549                    }
10550                }
10551            }
10552            anyhow::Ok(())
10553        })?;
10554
10555        Ok(proto::Ack {})
10556    }
10557
10558    fn buffer_ids_to_buffers(
10559        &mut self,
10560        buffer_ids: impl Iterator<Item = u64>,
10561        cx: &mut Context<Self>,
10562    ) -> Vec<Entity<Buffer>> {
10563        buffer_ids
10564            .into_iter()
10565            .flat_map(|buffer_id| {
10566                self.buffer_store
10567                    .read(cx)
10568                    .get(BufferId::new(buffer_id).log_err()?)
10569            })
10570            .collect::<Vec<_>>()
10571    }
10572
10573    async fn handle_apply_additional_edits_for_completion(
10574        this: Entity<Self>,
10575        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10576        mut cx: AsyncApp,
10577    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10578        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10579            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10580            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10581            let completion = Self::deserialize_completion(
10582                envelope.payload.completion.context("invalid completion")?,
10583            )?;
10584            anyhow::Ok((buffer, completion))
10585        })?;
10586
10587        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10588            this.apply_additional_edits_for_completion(
10589                buffer,
10590                Rc::new(RefCell::new(Box::new([Completion {
10591                    replace_range: completion.replace_range,
10592                    new_text: completion.new_text,
10593                    source: completion.source,
10594                    documentation: None,
10595                    label: CodeLabel::default(),
10596                    match_start: None,
10597                    snippet_deduplication_key: None,
10598                    insert_text_mode: None,
10599                    icon_path: None,
10600                    confirm: None,
10601                }]))),
10602                0,
10603                false,
10604                cx,
10605            )
10606        });
10607
10608        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10609            transaction: apply_additional_edits
10610                .await?
10611                .as_ref()
10612                .map(language::proto::serialize_transaction),
10613        })
10614    }
10615
10616    pub fn last_formatting_failure(&self) -> Option<&str> {
10617        self.last_formatting_failure.as_deref()
10618    }
10619
10620    pub fn reset_last_formatting_failure(&mut self) {
10621        self.last_formatting_failure = None;
10622    }
10623
10624    pub fn environment_for_buffer(
10625        &self,
10626        buffer: &Entity<Buffer>,
10627        cx: &mut Context<Self>,
10628    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10629        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10630            environment.update(cx, |env, cx| {
10631                env.buffer_environment(buffer, &self.worktree_store, cx)
10632            })
10633        } else {
10634            Task::ready(None).shared()
10635        }
10636    }
10637
10638    pub fn format(
10639        &mut self,
10640        buffers: HashSet<Entity<Buffer>>,
10641        target: LspFormatTarget,
10642        push_to_history: bool,
10643        trigger: FormatTrigger,
10644        cx: &mut Context<Self>,
10645    ) -> Task<anyhow::Result<ProjectTransaction>> {
10646        let logger = zlog::scoped!("format");
10647        if self.as_local().is_some() {
10648            zlog::trace!(logger => "Formatting locally");
10649            let logger = zlog::scoped!(logger => "local");
10650            let buffers = buffers
10651                .into_iter()
10652                .map(|buffer_handle| {
10653                    let buffer = buffer_handle.read(cx);
10654                    let buffer_abs_path = File::from_dyn(buffer.file())
10655                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10656
10657                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10658                })
10659                .collect::<Vec<_>>();
10660
10661            cx.spawn(async move |lsp_store, cx| {
10662                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10663
10664                for (handle, abs_path, id) in buffers {
10665                    let env = lsp_store
10666                        .update(cx, |lsp_store, cx| {
10667                            lsp_store.environment_for_buffer(&handle, cx)
10668                        })?
10669                        .await;
10670
10671                    let ranges = match &target {
10672                        LspFormatTarget::Buffers => None,
10673                        LspFormatTarget::Ranges(ranges) => {
10674                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10675                        }
10676                    };
10677
10678                    formattable_buffers.push(FormattableBuffer {
10679                        handle,
10680                        abs_path,
10681                        env,
10682                        ranges,
10683                    });
10684                }
10685                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10686
10687                let format_timer = zlog::time!(logger => "Formatting buffers");
10688                let result = LocalLspStore::format_locally(
10689                    lsp_store.clone(),
10690                    formattable_buffers,
10691                    push_to_history,
10692                    trigger,
10693                    logger,
10694                    cx,
10695                )
10696                .await;
10697                format_timer.end();
10698
10699                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10700
10701                lsp_store.update(cx, |lsp_store, _| {
10702                    lsp_store.update_last_formatting_failure(&result);
10703                })?;
10704
10705                result
10706            })
10707        } else if let Some((client, project_id)) = self.upstream_client() {
10708            zlog::trace!(logger => "Formatting remotely");
10709            let logger = zlog::scoped!(logger => "remote");
10710            // Don't support formatting ranges via remote
10711            match target {
10712                LspFormatTarget::Buffers => {}
10713                LspFormatTarget::Ranges(_) => {
10714                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10715                    return Task::ready(Ok(ProjectTransaction::default()));
10716                }
10717            }
10718
10719            let buffer_store = self.buffer_store();
10720            cx.spawn(async move |lsp_store, cx| {
10721                zlog::trace!(logger => "Sending remote format request");
10722                let request_timer = zlog::time!(logger => "remote format request");
10723                let result = client
10724                    .request(proto::FormatBuffers {
10725                        project_id,
10726                        trigger: trigger as i32,
10727                        buffer_ids: buffers
10728                            .iter()
10729                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10730                            .collect(),
10731                    })
10732                    .await
10733                    .and_then(|result| result.transaction.context("missing transaction"));
10734                request_timer.end();
10735
10736                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10737
10738                lsp_store.update(cx, |lsp_store, _| {
10739                    lsp_store.update_last_formatting_failure(&result);
10740                })?;
10741
10742                let transaction_response = result?;
10743                let _timer = zlog::time!(logger => "deserializing project transaction");
10744                buffer_store
10745                    .update(cx, |buffer_store, cx| {
10746                        buffer_store.deserialize_project_transaction(
10747                            transaction_response,
10748                            push_to_history,
10749                            cx,
10750                        )
10751                    })
10752                    .await
10753            })
10754        } else {
10755            zlog::trace!(logger => "Not formatting");
10756            Task::ready(Ok(ProjectTransaction::default()))
10757        }
10758    }
10759
10760    async fn handle_format_buffers(
10761        this: Entity<Self>,
10762        envelope: TypedEnvelope<proto::FormatBuffers>,
10763        mut cx: AsyncApp,
10764    ) -> Result<proto::FormatBuffersResponse> {
10765        let sender_id = envelope.original_sender_id().unwrap_or_default();
10766        let format = this.update(&mut cx, |this, cx| {
10767            let mut buffers = HashSet::default();
10768            for buffer_id in &envelope.payload.buffer_ids {
10769                let buffer_id = BufferId::new(*buffer_id)?;
10770                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10771            }
10772            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10773            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10774        })?;
10775
10776        let project_transaction = format.await?;
10777        let project_transaction = this.update(&mut cx, |this, cx| {
10778            this.buffer_store.update(cx, |buffer_store, cx| {
10779                buffer_store.serialize_project_transaction_for_peer(
10780                    project_transaction,
10781                    sender_id,
10782                    cx,
10783                )
10784            })
10785        });
10786        Ok(proto::FormatBuffersResponse {
10787            transaction: Some(project_transaction),
10788        })
10789    }
10790
10791    async fn handle_apply_code_action_kind(
10792        this: Entity<Self>,
10793        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10794        mut cx: AsyncApp,
10795    ) -> Result<proto::ApplyCodeActionKindResponse> {
10796        let sender_id = envelope.original_sender_id().unwrap_or_default();
10797        let format = this.update(&mut cx, |this, cx| {
10798            let mut buffers = HashSet::default();
10799            for buffer_id in &envelope.payload.buffer_ids {
10800                let buffer_id = BufferId::new(*buffer_id)?;
10801                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10802            }
10803            let kind = match envelope.payload.kind.as_str() {
10804                "" => CodeActionKind::EMPTY,
10805                "quickfix" => CodeActionKind::QUICKFIX,
10806                "refactor" => CodeActionKind::REFACTOR,
10807                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10808                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10809                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10810                "source" => CodeActionKind::SOURCE,
10811                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10812                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10813                _ => anyhow::bail!(
10814                    "Invalid code action kind {}",
10815                    envelope.payload.kind.as_str()
10816                ),
10817            };
10818            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10819        })?;
10820
10821        let project_transaction = format.await?;
10822        let project_transaction = this.update(&mut cx, |this, cx| {
10823            this.buffer_store.update(cx, |buffer_store, cx| {
10824                buffer_store.serialize_project_transaction_for_peer(
10825                    project_transaction,
10826                    sender_id,
10827                    cx,
10828                )
10829            })
10830        });
10831        Ok(proto::ApplyCodeActionKindResponse {
10832            transaction: Some(project_transaction),
10833        })
10834    }
10835
10836    async fn shutdown_language_server(
10837        server_state: Option<LanguageServerState>,
10838        name: LanguageServerName,
10839        cx: &mut AsyncApp,
10840    ) {
10841        let server = match server_state {
10842            Some(LanguageServerState::Starting { startup, .. }) => {
10843                let mut timer = cx
10844                    .background_executor()
10845                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10846                    .fuse();
10847
10848                select! {
10849                    server = startup.fuse() => server,
10850                    () = timer => {
10851                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10852                        None
10853                    },
10854                }
10855            }
10856
10857            Some(LanguageServerState::Running { server, .. }) => Some(server),
10858
10859            None => None,
10860        };
10861
10862        if let Some(server) = server
10863            && let Some(shutdown) = server.shutdown()
10864        {
10865            shutdown.await;
10866        }
10867    }
10868
10869    // Returns a list of all of the worktrees which no longer have a language server and the root path
10870    // for the stopped server
10871    fn stop_local_language_server(
10872        &mut self,
10873        server_id: LanguageServerId,
10874        cx: &mut Context<Self>,
10875    ) -> Task<()> {
10876        let local = match &mut self.mode {
10877            LspStoreMode::Local(local) => local,
10878            _ => {
10879                return Task::ready(());
10880            }
10881        };
10882
10883        // Remove this server ID from all entries in the given worktree.
10884        local
10885            .language_server_ids
10886            .retain(|_, state| state.id != server_id);
10887        self.buffer_store.update(cx, |buffer_store, cx| {
10888            for buffer in buffer_store.buffers() {
10889                buffer.update(cx, |buffer, cx| {
10890                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10891                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10892                });
10893            }
10894        });
10895
10896        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10897            summaries.retain(|path, summaries_by_server_id| {
10898                if summaries_by_server_id.remove(&server_id).is_some() {
10899                    if let Some((client, project_id)) = self.downstream_client.clone() {
10900                        client
10901                            .send(proto::UpdateDiagnosticSummary {
10902                                project_id,
10903                                worktree_id: worktree_id.to_proto(),
10904                                summary: Some(proto::DiagnosticSummary {
10905                                    path: path.as_ref().to_proto(),
10906                                    language_server_id: server_id.0 as u64,
10907                                    error_count: 0,
10908                                    warning_count: 0,
10909                                }),
10910                                more_summaries: Vec::new(),
10911                            })
10912                            .log_err();
10913                    }
10914                    !summaries_by_server_id.is_empty()
10915                } else {
10916                    true
10917                }
10918            });
10919        }
10920
10921        let local = self.as_local_mut().unwrap();
10922        for diagnostics in local.diagnostics.values_mut() {
10923            diagnostics.retain(|_, diagnostics_by_server_id| {
10924                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10925                    diagnostics_by_server_id.remove(ix);
10926                    !diagnostics_by_server_id.is_empty()
10927                } else {
10928                    true
10929                }
10930            });
10931        }
10932        local.language_server_watched_paths.remove(&server_id);
10933
10934        let server_state = local.language_servers.remove(&server_id);
10935        self.cleanup_lsp_data(server_id);
10936        let name = self
10937            .language_server_statuses
10938            .remove(&server_id)
10939            .map(|status| status.name)
10940            .or_else(|| {
10941                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10942                    Some(adapter.name())
10943                } else {
10944                    None
10945                }
10946            });
10947
10948        if let Some(name) = name {
10949            log::info!("stopping language server {name}");
10950            self.languages
10951                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10952            cx.notify();
10953
10954            return cx.spawn(async move |lsp_store, cx| {
10955                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10956                lsp_store
10957                    .update(cx, |lsp_store, cx| {
10958                        lsp_store
10959                            .languages
10960                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10961                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10962                        cx.notify();
10963                    })
10964                    .ok();
10965            });
10966        }
10967
10968        if server_state.is_some() {
10969            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10970        }
10971        Task::ready(())
10972    }
10973
10974    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10975        if let Some((client, project_id)) = self.upstream_client() {
10976            let request = client.request(proto::StopLanguageServers {
10977                project_id,
10978                buffer_ids: Vec::new(),
10979                also_servers: Vec::new(),
10980                all: true,
10981            });
10982            cx.background_spawn(request).detach_and_log_err(cx);
10983        } else {
10984            let Some(local) = self.as_local_mut() else {
10985                return;
10986            };
10987            let language_servers_to_stop = local
10988                .language_server_ids
10989                .values()
10990                .map(|state| state.id)
10991                .collect();
10992            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10993            let tasks = language_servers_to_stop
10994                .into_iter()
10995                .map(|server| self.stop_local_language_server(server, cx))
10996                .collect::<Vec<_>>();
10997            cx.background_spawn(async move {
10998                futures::future::join_all(tasks).await;
10999            })
11000            .detach();
11001        }
11002    }
11003
11004    pub fn restart_language_servers_for_buffers(
11005        &mut self,
11006        buffers: Vec<Entity<Buffer>>,
11007        only_restart_servers: HashSet<LanguageServerSelector>,
11008        cx: &mut Context<Self>,
11009    ) {
11010        if let Some((client, project_id)) = self.upstream_client() {
11011            let request = client.request(proto::RestartLanguageServers {
11012                project_id,
11013                buffer_ids: buffers
11014                    .into_iter()
11015                    .map(|b| b.read(cx).remote_id().to_proto())
11016                    .collect(),
11017                only_servers: only_restart_servers
11018                    .into_iter()
11019                    .map(|selector| {
11020                        let selector = match selector {
11021                            LanguageServerSelector::Id(language_server_id) => {
11022                                proto::language_server_selector::Selector::ServerId(
11023                                    language_server_id.to_proto(),
11024                                )
11025                            }
11026                            LanguageServerSelector::Name(language_server_name) => {
11027                                proto::language_server_selector::Selector::Name(
11028                                    language_server_name.to_string(),
11029                                )
11030                            }
11031                        };
11032                        proto::LanguageServerSelector {
11033                            selector: Some(selector),
11034                        }
11035                    })
11036                    .collect(),
11037                all: false,
11038            });
11039            cx.background_spawn(request).detach_and_log_err(cx);
11040        } else {
11041            let stop_task = if only_restart_servers.is_empty() {
11042                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11043            } else {
11044                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11045            };
11046            cx.spawn(async move |lsp_store, cx| {
11047                stop_task.await;
11048                lsp_store.update(cx, |lsp_store, cx| {
11049                    for buffer in buffers {
11050                        lsp_store.register_buffer_with_language_servers(
11051                            &buffer,
11052                            only_restart_servers.clone(),
11053                            true,
11054                            cx,
11055                        );
11056                    }
11057                })
11058            })
11059            .detach();
11060        }
11061    }
11062
11063    pub fn stop_language_servers_for_buffers(
11064        &mut self,
11065        buffers: Vec<Entity<Buffer>>,
11066        also_stop_servers: HashSet<LanguageServerSelector>,
11067        cx: &mut Context<Self>,
11068    ) -> Task<Result<()>> {
11069        if let Some((client, project_id)) = self.upstream_client() {
11070            let request = client.request(proto::StopLanguageServers {
11071                project_id,
11072                buffer_ids: buffers
11073                    .into_iter()
11074                    .map(|b| b.read(cx).remote_id().to_proto())
11075                    .collect(),
11076                also_servers: also_stop_servers
11077                    .into_iter()
11078                    .map(|selector| {
11079                        let selector = match selector {
11080                            LanguageServerSelector::Id(language_server_id) => {
11081                                proto::language_server_selector::Selector::ServerId(
11082                                    language_server_id.to_proto(),
11083                                )
11084                            }
11085                            LanguageServerSelector::Name(language_server_name) => {
11086                                proto::language_server_selector::Selector::Name(
11087                                    language_server_name.to_string(),
11088                                )
11089                            }
11090                        };
11091                        proto::LanguageServerSelector {
11092                            selector: Some(selector),
11093                        }
11094                    })
11095                    .collect(),
11096                all: false,
11097            });
11098            cx.background_spawn(async move {
11099                let _ = request.await?;
11100                Ok(())
11101            })
11102        } else {
11103            let task =
11104                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11105            cx.background_spawn(async move {
11106                task.await;
11107                Ok(())
11108            })
11109        }
11110    }
11111
11112    fn stop_local_language_servers_for_buffers(
11113        &mut self,
11114        buffers: &[Entity<Buffer>],
11115        also_stop_servers: HashSet<LanguageServerSelector>,
11116        cx: &mut Context<Self>,
11117    ) -> Task<()> {
11118        let Some(local) = self.as_local_mut() else {
11119            return Task::ready(());
11120        };
11121        let mut language_server_names_to_stop = BTreeSet::default();
11122        let mut language_servers_to_stop = also_stop_servers
11123            .into_iter()
11124            .flat_map(|selector| match selector {
11125                LanguageServerSelector::Id(id) => Some(id),
11126                LanguageServerSelector::Name(name) => {
11127                    language_server_names_to_stop.insert(name);
11128                    None
11129                }
11130            })
11131            .collect::<BTreeSet<_>>();
11132
11133        let mut covered_worktrees = HashSet::default();
11134        for buffer in buffers {
11135            buffer.update(cx, |buffer, cx| {
11136                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11137                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11138                    && covered_worktrees.insert(worktree_id)
11139                {
11140                    language_server_names_to_stop.retain(|name| {
11141                        let old_ids_count = language_servers_to_stop.len();
11142                        let all_language_servers_with_this_name = local
11143                            .language_server_ids
11144                            .iter()
11145                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11146                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11147                        old_ids_count == language_servers_to_stop.len()
11148                    });
11149                }
11150            });
11151        }
11152        for name in language_server_names_to_stop {
11153            language_servers_to_stop.extend(
11154                local
11155                    .language_server_ids
11156                    .iter()
11157                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11158            );
11159        }
11160
11161        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11162        let tasks = language_servers_to_stop
11163            .into_iter()
11164            .map(|server| self.stop_local_language_server(server, cx))
11165            .collect::<Vec<_>>();
11166
11167        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11168    }
11169
11170    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11171        let (worktree, relative_path) =
11172            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11173
11174        let project_path = ProjectPath {
11175            worktree_id: worktree.read(cx).id(),
11176            path: relative_path,
11177        };
11178
11179        Some(
11180            self.buffer_store()
11181                .read(cx)
11182                .get_by_path(&project_path)?
11183                .read(cx),
11184        )
11185    }
11186
11187    #[cfg(any(test, feature = "test-support"))]
11188    pub fn update_diagnostics(
11189        &mut self,
11190        server_id: LanguageServerId,
11191        diagnostics: lsp::PublishDiagnosticsParams,
11192        result_id: Option<SharedString>,
11193        source_kind: DiagnosticSourceKind,
11194        disk_based_sources: &[String],
11195        cx: &mut Context<Self>,
11196    ) -> Result<()> {
11197        self.merge_lsp_diagnostics(
11198            source_kind,
11199            vec![DocumentDiagnosticsUpdate {
11200                diagnostics,
11201                result_id,
11202                server_id,
11203                disk_based_sources: Cow::Borrowed(disk_based_sources),
11204                registration_id: None,
11205            }],
11206            |_, _, _| false,
11207            cx,
11208        )
11209    }
11210
11211    pub fn merge_lsp_diagnostics(
11212        &mut self,
11213        source_kind: DiagnosticSourceKind,
11214        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11215        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11216        cx: &mut Context<Self>,
11217    ) -> Result<()> {
11218        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11219        let updates = lsp_diagnostics
11220            .into_iter()
11221            .filter_map(|update| {
11222                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11223                Some(DocumentDiagnosticsUpdate {
11224                    diagnostics: self.lsp_to_document_diagnostics(
11225                        abs_path,
11226                        source_kind,
11227                        update.server_id,
11228                        update.diagnostics,
11229                        &update.disk_based_sources,
11230                        update.registration_id.clone(),
11231                    ),
11232                    result_id: update.result_id,
11233                    server_id: update.server_id,
11234                    disk_based_sources: update.disk_based_sources,
11235                    registration_id: update.registration_id,
11236                })
11237            })
11238            .collect();
11239        self.merge_diagnostic_entries(updates, merge, cx)?;
11240        Ok(())
11241    }
11242
11243    fn lsp_to_document_diagnostics(
11244        &mut self,
11245        document_abs_path: PathBuf,
11246        source_kind: DiagnosticSourceKind,
11247        server_id: LanguageServerId,
11248        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11249        disk_based_sources: &[String],
11250        registration_id: Option<SharedString>,
11251    ) -> DocumentDiagnostics {
11252        let mut diagnostics = Vec::default();
11253        let mut primary_diagnostic_group_ids = HashMap::default();
11254        let mut sources_by_group_id = HashMap::default();
11255        let mut supporting_diagnostics = HashMap::default();
11256
11257        let adapter = self.language_server_adapter_for_id(server_id);
11258
11259        // Ensure that primary diagnostics are always the most severe
11260        lsp_diagnostics
11261            .diagnostics
11262            .sort_by_key(|item| item.severity);
11263
11264        for diagnostic in &lsp_diagnostics.diagnostics {
11265            let source = diagnostic.source.as_ref();
11266            let range = range_from_lsp(diagnostic.range);
11267            let is_supporting = diagnostic
11268                .related_information
11269                .as_ref()
11270                .is_some_and(|infos| {
11271                    infos.iter().any(|info| {
11272                        primary_diagnostic_group_ids.contains_key(&(
11273                            source,
11274                            diagnostic.code.clone(),
11275                            range_from_lsp(info.location.range),
11276                        ))
11277                    })
11278                });
11279
11280            let is_unnecessary = diagnostic
11281                .tags
11282                .as_ref()
11283                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11284
11285            let underline = self
11286                .language_server_adapter_for_id(server_id)
11287                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11288
11289            if is_supporting {
11290                supporting_diagnostics.insert(
11291                    (source, diagnostic.code.clone(), range),
11292                    (diagnostic.severity, is_unnecessary),
11293                );
11294            } else {
11295                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11296                let is_disk_based =
11297                    source.is_some_and(|source| disk_based_sources.contains(source));
11298
11299                sources_by_group_id.insert(group_id, source);
11300                primary_diagnostic_group_ids
11301                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11302
11303                diagnostics.push(DiagnosticEntry {
11304                    range,
11305                    diagnostic: Diagnostic {
11306                        source: diagnostic.source.clone(),
11307                        source_kind,
11308                        code: diagnostic.code.clone(),
11309                        code_description: diagnostic
11310                            .code_description
11311                            .as_ref()
11312                            .and_then(|d| d.href.clone()),
11313                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11314                        markdown: adapter.as_ref().and_then(|adapter| {
11315                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11316                        }),
11317                        message: diagnostic.message.trim().to_string(),
11318                        group_id,
11319                        is_primary: true,
11320                        is_disk_based,
11321                        is_unnecessary,
11322                        underline,
11323                        data: diagnostic.data.clone(),
11324                        registration_id: registration_id.clone(),
11325                    },
11326                });
11327                if let Some(infos) = &diagnostic.related_information {
11328                    for info in infos {
11329                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11330                            let range = range_from_lsp(info.location.range);
11331                            diagnostics.push(DiagnosticEntry {
11332                                range,
11333                                diagnostic: Diagnostic {
11334                                    source: diagnostic.source.clone(),
11335                                    source_kind,
11336                                    code: diagnostic.code.clone(),
11337                                    code_description: diagnostic
11338                                        .code_description
11339                                        .as_ref()
11340                                        .and_then(|d| d.href.clone()),
11341                                    severity: DiagnosticSeverity::INFORMATION,
11342                                    markdown: adapter.as_ref().and_then(|adapter| {
11343                                        adapter.diagnostic_message_to_markdown(&info.message)
11344                                    }),
11345                                    message: info.message.trim().to_string(),
11346                                    group_id,
11347                                    is_primary: false,
11348                                    is_disk_based,
11349                                    is_unnecessary: false,
11350                                    underline,
11351                                    data: diagnostic.data.clone(),
11352                                    registration_id: registration_id.clone(),
11353                                },
11354                            });
11355                        }
11356                    }
11357                }
11358            }
11359        }
11360
11361        for entry in &mut diagnostics {
11362            let diagnostic = &mut entry.diagnostic;
11363            if !diagnostic.is_primary {
11364                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11365                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11366                    source,
11367                    diagnostic.code.clone(),
11368                    entry.range.clone(),
11369                )) {
11370                    if let Some(severity) = severity {
11371                        diagnostic.severity = severity;
11372                    }
11373                    diagnostic.is_unnecessary = is_unnecessary;
11374                }
11375            }
11376        }
11377
11378        DocumentDiagnostics {
11379            diagnostics,
11380            document_abs_path,
11381            version: lsp_diagnostics.version,
11382        }
11383    }
11384
11385    fn insert_newly_running_language_server(
11386        &mut self,
11387        adapter: Arc<CachedLspAdapter>,
11388        language_server: Arc<LanguageServer>,
11389        server_id: LanguageServerId,
11390        key: LanguageServerSeed,
11391        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11392        cx: &mut Context<Self>,
11393    ) {
11394        let Some(local) = self.as_local_mut() else {
11395            return;
11396        };
11397        // If the language server for this key doesn't match the server id, don't store the
11398        // server. Which will cause it to be dropped, killing the process
11399        if local
11400            .language_server_ids
11401            .get(&key)
11402            .map(|state| state.id != server_id)
11403            .unwrap_or(false)
11404        {
11405            return;
11406        }
11407
11408        // Update language_servers collection with Running variant of LanguageServerState
11409        // indicating that the server is up and running and ready
11410        let workspace_folders = workspace_folders.lock().clone();
11411        language_server.set_workspace_folders(workspace_folders);
11412
11413        let workspace_diagnostics_refresh_tasks = language_server
11414            .capabilities()
11415            .diagnostic_provider
11416            .and_then(|provider| {
11417                local
11418                    .language_server_dynamic_registrations
11419                    .entry(server_id)
11420                    .or_default()
11421                    .diagnostics
11422                    .entry(None)
11423                    .or_insert(provider.clone());
11424                let workspace_refresher =
11425                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11426
11427                Some((None, workspace_refresher))
11428            })
11429            .into_iter()
11430            .collect();
11431        local.language_servers.insert(
11432            server_id,
11433            LanguageServerState::Running {
11434                workspace_diagnostics_refresh_tasks,
11435                adapter: adapter.clone(),
11436                server: language_server.clone(),
11437                simulate_disk_based_diagnostics_completion: None,
11438            },
11439        );
11440        local
11441            .languages
11442            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11443        if let Some(file_ops_caps) = language_server
11444            .capabilities()
11445            .workspace
11446            .as_ref()
11447            .and_then(|ws| ws.file_operations.as_ref())
11448        {
11449            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11450            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11451            if did_rename_caps.or(will_rename_caps).is_some() {
11452                let watcher = RenamePathsWatchedForServer::default()
11453                    .with_did_rename_patterns(did_rename_caps)
11454                    .with_will_rename_patterns(will_rename_caps);
11455                local
11456                    .language_server_paths_watched_for_rename
11457                    .insert(server_id, watcher);
11458            }
11459        }
11460
11461        self.language_server_statuses.insert(
11462            server_id,
11463            LanguageServerStatus {
11464                name: language_server.name(),
11465                server_version: language_server.version(),
11466                pending_work: Default::default(),
11467                has_pending_diagnostic_updates: false,
11468                progress_tokens: Default::default(),
11469                worktree: Some(key.worktree_id),
11470                binary: Some(language_server.binary().clone()),
11471                configuration: Some(language_server.configuration().clone()),
11472                workspace_folders: language_server.workspace_folders(),
11473            },
11474        );
11475
11476        cx.emit(LspStoreEvent::LanguageServerAdded(
11477            server_id,
11478            language_server.name(),
11479            Some(key.worktree_id),
11480        ));
11481
11482        let server_capabilities = language_server.capabilities();
11483        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11484            downstream_client
11485                .send(proto::StartLanguageServer {
11486                    project_id: *project_id,
11487                    server: Some(proto::LanguageServer {
11488                        id: server_id.to_proto(),
11489                        name: language_server.name().to_string(),
11490                        worktree_id: Some(key.worktree_id.to_proto()),
11491                    }),
11492                    capabilities: serde_json::to_string(&server_capabilities)
11493                        .expect("serializing server LSP capabilities"),
11494                })
11495                .log_err();
11496        }
11497        self.lsp_server_capabilities
11498            .insert(server_id, server_capabilities);
11499
11500        // Tell the language server about every open buffer in the worktree that matches the language.
11501        // Also check for buffers in worktrees that reused this server
11502        let mut worktrees_using_server = vec![key.worktree_id];
11503        if let Some(local) = self.as_local() {
11504            // Find all worktrees that have this server in their language server tree
11505            for (worktree_id, servers) in &local.lsp_tree.instances {
11506                if *worktree_id != key.worktree_id {
11507                    for server_map in servers.roots.values() {
11508                        if server_map
11509                            .values()
11510                            .any(|(node, _)| node.id() == Some(server_id))
11511                        {
11512                            worktrees_using_server.push(*worktree_id);
11513                        }
11514                    }
11515                }
11516            }
11517        }
11518
11519        let mut buffer_paths_registered = Vec::new();
11520        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11521            let mut lsp_adapters = HashMap::default();
11522            for buffer_handle in buffer_store.buffers() {
11523                let buffer = buffer_handle.read(cx);
11524                let file = match File::from_dyn(buffer.file()) {
11525                    Some(file) => file,
11526                    None => continue,
11527                };
11528                let language = match buffer.language() {
11529                    Some(language) => language,
11530                    None => continue,
11531                };
11532
11533                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11534                    || !lsp_adapters
11535                        .entry(language.name())
11536                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11537                        .iter()
11538                        .any(|a| a.name == key.name)
11539                {
11540                    continue;
11541                }
11542                // didOpen
11543                let file = match file.as_local() {
11544                    Some(file) => file,
11545                    None => continue,
11546                };
11547
11548                let local = self.as_local_mut().unwrap();
11549
11550                let buffer_id = buffer.remote_id();
11551                if local.registered_buffers.contains_key(&buffer_id) {
11552                    let versions = local
11553                        .buffer_snapshots
11554                        .entry(buffer_id)
11555                        .or_default()
11556                        .entry(server_id)
11557                        .and_modify(|_| {
11558                            assert!(
11559                            false,
11560                            "There should not be an existing snapshot for a newly inserted buffer"
11561                        )
11562                        })
11563                        .or_insert_with(|| {
11564                            vec![LspBufferSnapshot {
11565                                version: 0,
11566                                snapshot: buffer.text_snapshot(),
11567                            }]
11568                        });
11569
11570                    let snapshot = versions.last().unwrap();
11571                    let version = snapshot.version;
11572                    let initial_snapshot = &snapshot.snapshot;
11573                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11574                    language_server.register_buffer(
11575                        uri,
11576                        adapter.language_id(&language.name()),
11577                        version,
11578                        initial_snapshot.text(),
11579                    );
11580                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11581                    local
11582                        .buffers_opened_in_servers
11583                        .entry(buffer_id)
11584                        .or_default()
11585                        .insert(server_id);
11586                }
11587                buffer_handle.update(cx, |buffer, cx| {
11588                    buffer.set_completion_triggers(
11589                        server_id,
11590                        language_server
11591                            .capabilities()
11592                            .completion_provider
11593                            .as_ref()
11594                            .and_then(|provider| {
11595                                provider
11596                                    .trigger_characters
11597                                    .as_ref()
11598                                    .map(|characters| characters.iter().cloned().collect())
11599                            })
11600                            .unwrap_or_default(),
11601                        cx,
11602                    )
11603                });
11604            }
11605        });
11606
11607        for (buffer_id, abs_path) in buffer_paths_registered {
11608            cx.emit(LspStoreEvent::LanguageServerUpdate {
11609                language_server_id: server_id,
11610                name: Some(adapter.name()),
11611                message: proto::update_language_server::Variant::RegisteredForBuffer(
11612                    proto::RegisteredForBuffer {
11613                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11614                        buffer_id: buffer_id.to_proto(),
11615                    },
11616                ),
11617            });
11618        }
11619
11620        cx.notify();
11621    }
11622
11623    pub fn language_servers_running_disk_based_diagnostics(
11624        &self,
11625    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11626        self.language_server_statuses
11627            .iter()
11628            .filter_map(|(id, status)| {
11629                if status.has_pending_diagnostic_updates {
11630                    Some(*id)
11631                } else {
11632                    None
11633                }
11634            })
11635    }
11636
11637    pub(crate) fn cancel_language_server_work_for_buffers(
11638        &mut self,
11639        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11640        cx: &mut Context<Self>,
11641    ) {
11642        if let Some((client, project_id)) = self.upstream_client() {
11643            let request = client.request(proto::CancelLanguageServerWork {
11644                project_id,
11645                work: Some(proto::cancel_language_server_work::Work::Buffers(
11646                    proto::cancel_language_server_work::Buffers {
11647                        buffer_ids: buffers
11648                            .into_iter()
11649                            .map(|b| b.read(cx).remote_id().to_proto())
11650                            .collect(),
11651                    },
11652                )),
11653            });
11654            cx.background_spawn(request).detach_and_log_err(cx);
11655        } else if let Some(local) = self.as_local() {
11656            let servers = buffers
11657                .into_iter()
11658                .flat_map(|buffer| {
11659                    buffer.update(cx, |buffer, cx| {
11660                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11661                    })
11662                })
11663                .collect::<HashSet<_>>();
11664            for server_id in servers {
11665                self.cancel_language_server_work(server_id, None, cx);
11666            }
11667        }
11668    }
11669
11670    pub(crate) fn cancel_language_server_work(
11671        &mut self,
11672        server_id: LanguageServerId,
11673        token_to_cancel: Option<ProgressToken>,
11674        cx: &mut Context<Self>,
11675    ) {
11676        if let Some(local) = self.as_local() {
11677            let status = self.language_server_statuses.get(&server_id);
11678            let server = local.language_servers.get(&server_id);
11679            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11680            {
11681                for (token, progress) in &status.pending_work {
11682                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11683                        && token != token_to_cancel
11684                    {
11685                        continue;
11686                    }
11687                    if progress.is_cancellable {
11688                        server
11689                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11690                                WorkDoneProgressCancelParams {
11691                                    token: token.to_lsp(),
11692                                },
11693                            )
11694                            .ok();
11695                    }
11696                }
11697            }
11698        } else if let Some((client, project_id)) = self.upstream_client() {
11699            let request = client.request(proto::CancelLanguageServerWork {
11700                project_id,
11701                work: Some(
11702                    proto::cancel_language_server_work::Work::LanguageServerWork(
11703                        proto::cancel_language_server_work::LanguageServerWork {
11704                            language_server_id: server_id.to_proto(),
11705                            token: token_to_cancel.map(|token| token.to_proto()),
11706                        },
11707                    ),
11708                ),
11709            });
11710            cx.background_spawn(request).detach_and_log_err(cx);
11711        }
11712    }
11713
11714    fn register_supplementary_language_server(
11715        &mut self,
11716        id: LanguageServerId,
11717        name: LanguageServerName,
11718        server: Arc<LanguageServer>,
11719        cx: &mut Context<Self>,
11720    ) {
11721        if let Some(local) = self.as_local_mut() {
11722            local
11723                .supplementary_language_servers
11724                .insert(id, (name.clone(), server));
11725            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11726        }
11727    }
11728
11729    fn unregister_supplementary_language_server(
11730        &mut self,
11731        id: LanguageServerId,
11732        cx: &mut Context<Self>,
11733    ) {
11734        if let Some(local) = self.as_local_mut() {
11735            local.supplementary_language_servers.remove(&id);
11736            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11737        }
11738    }
11739
11740    pub(crate) fn supplementary_language_servers(
11741        &self,
11742    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11743        self.as_local().into_iter().flat_map(|local| {
11744            local
11745                .supplementary_language_servers
11746                .iter()
11747                .map(|(id, (name, _))| (*id, name.clone()))
11748        })
11749    }
11750
11751    pub fn language_server_adapter_for_id(
11752        &self,
11753        id: LanguageServerId,
11754    ) -> Option<Arc<CachedLspAdapter>> {
11755        self.as_local()
11756            .and_then(|local| local.language_servers.get(&id))
11757            .and_then(|language_server_state| match language_server_state {
11758                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11759                _ => None,
11760            })
11761    }
11762
11763    pub(super) fn update_local_worktree_language_servers(
11764        &mut self,
11765        worktree_handle: &Entity<Worktree>,
11766        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11767        cx: &mut Context<Self>,
11768    ) {
11769        if changes.is_empty() {
11770            return;
11771        }
11772
11773        let Some(local) = self.as_local() else { return };
11774
11775        local.prettier_store.update(cx, |prettier_store, cx| {
11776            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11777        });
11778
11779        let worktree_id = worktree_handle.read(cx).id();
11780        let mut language_server_ids = local
11781            .language_server_ids
11782            .iter()
11783            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11784            .collect::<Vec<_>>();
11785        language_server_ids.sort();
11786        language_server_ids.dedup();
11787
11788        // let abs_path = worktree_handle.read(cx).abs_path();
11789        for server_id in &language_server_ids {
11790            if let Some(LanguageServerState::Running { server, .. }) =
11791                local.language_servers.get(server_id)
11792                && let Some(watched_paths) = local
11793                    .language_server_watched_paths
11794                    .get(server_id)
11795                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11796            {
11797                let params = lsp::DidChangeWatchedFilesParams {
11798                    changes: changes
11799                        .iter()
11800                        .filter_map(|(path, _, change)| {
11801                            if !watched_paths.is_match(path.as_std_path()) {
11802                                return None;
11803                            }
11804                            let typ = match change {
11805                                PathChange::Loaded => return None,
11806                                PathChange::Added => lsp::FileChangeType::CREATED,
11807                                PathChange::Removed => lsp::FileChangeType::DELETED,
11808                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11809                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11810                            };
11811                            let uri = lsp::Uri::from_file_path(
11812                                worktree_handle.read(cx).absolutize(&path),
11813                            )
11814                            .ok()?;
11815                            Some(lsp::FileEvent { uri, typ })
11816                        })
11817                        .collect(),
11818                };
11819                if !params.changes.is_empty() {
11820                    server
11821                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11822                        .ok();
11823                }
11824            }
11825        }
11826        for (path, _, _) in changes {
11827            if let Some(file_name) = path.file_name()
11828                && local.watched_manifest_filenames.contains(file_name)
11829            {
11830                self.request_workspace_config_refresh();
11831                break;
11832            }
11833        }
11834    }
11835
11836    pub fn wait_for_remote_buffer(
11837        &mut self,
11838        id: BufferId,
11839        cx: &mut Context<Self>,
11840    ) -> Task<Result<Entity<Buffer>>> {
11841        self.buffer_store.update(cx, |buffer_store, cx| {
11842            buffer_store.wait_for_remote_buffer(id, cx)
11843        })
11844    }
11845
11846    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11847        let mut result = proto::Symbol {
11848            language_server_name: symbol.language_server_name.0.to_string(),
11849            source_worktree_id: symbol.source_worktree_id.to_proto(),
11850            language_server_id: symbol.source_language_server_id.to_proto(),
11851            name: symbol.name.clone(),
11852            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11853            start: Some(proto::PointUtf16 {
11854                row: symbol.range.start.0.row,
11855                column: symbol.range.start.0.column,
11856            }),
11857            end: Some(proto::PointUtf16 {
11858                row: symbol.range.end.0.row,
11859                column: symbol.range.end.0.column,
11860            }),
11861            worktree_id: Default::default(),
11862            path: Default::default(),
11863            signature: Default::default(),
11864        };
11865        match &symbol.path {
11866            SymbolLocation::InProject(path) => {
11867                result.worktree_id = path.worktree_id.to_proto();
11868                result.path = path.path.to_proto();
11869            }
11870            SymbolLocation::OutsideProject {
11871                abs_path,
11872                signature,
11873            } => {
11874                result.path = abs_path.to_string_lossy().into_owned();
11875                result.signature = signature.to_vec();
11876            }
11877        }
11878        result
11879    }
11880
11881    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11882        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11883        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11884        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11885
11886        let path = if serialized_symbol.signature.is_empty() {
11887            SymbolLocation::InProject(ProjectPath {
11888                worktree_id,
11889                path: RelPath::from_proto(&serialized_symbol.path)
11890                    .context("invalid symbol path")?,
11891            })
11892        } else {
11893            SymbolLocation::OutsideProject {
11894                abs_path: Path::new(&serialized_symbol.path).into(),
11895                signature: serialized_symbol
11896                    .signature
11897                    .try_into()
11898                    .map_err(|_| anyhow!("invalid signature"))?,
11899            }
11900        };
11901
11902        let start = serialized_symbol.start.context("invalid start")?;
11903        let end = serialized_symbol.end.context("invalid end")?;
11904        Ok(CoreSymbol {
11905            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11906            source_worktree_id,
11907            source_language_server_id: LanguageServerId::from_proto(
11908                serialized_symbol.language_server_id,
11909            ),
11910            path,
11911            name: serialized_symbol.name,
11912            range: Unclipped(PointUtf16::new(start.row, start.column))
11913                ..Unclipped(PointUtf16::new(end.row, end.column)),
11914            kind,
11915        })
11916    }
11917
11918    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11919        let mut serialized_completion = proto::Completion {
11920            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11921            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11922            new_text: completion.new_text.clone(),
11923            ..proto::Completion::default()
11924        };
11925        match &completion.source {
11926            CompletionSource::Lsp {
11927                insert_range,
11928                server_id,
11929                lsp_completion,
11930                lsp_defaults,
11931                resolved,
11932            } => {
11933                let (old_insert_start, old_insert_end) = insert_range
11934                    .as_ref()
11935                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11936                    .unzip();
11937
11938                serialized_completion.old_insert_start = old_insert_start;
11939                serialized_completion.old_insert_end = old_insert_end;
11940                serialized_completion.source = proto::completion::Source::Lsp as i32;
11941                serialized_completion.server_id = server_id.0 as u64;
11942                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11943                serialized_completion.lsp_defaults = lsp_defaults
11944                    .as_deref()
11945                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11946                serialized_completion.resolved = *resolved;
11947            }
11948            CompletionSource::BufferWord {
11949                word_range,
11950                resolved,
11951            } => {
11952                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11953                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11954                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11955                serialized_completion.resolved = *resolved;
11956            }
11957            CompletionSource::Custom => {
11958                serialized_completion.source = proto::completion::Source::Custom as i32;
11959                serialized_completion.resolved = true;
11960            }
11961            CompletionSource::Dap { sort_text } => {
11962                serialized_completion.source = proto::completion::Source::Dap as i32;
11963                serialized_completion.sort_text = Some(sort_text.clone());
11964            }
11965        }
11966
11967        serialized_completion
11968    }
11969
11970    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11971        let old_replace_start = completion
11972            .old_replace_start
11973            .and_then(deserialize_anchor)
11974            .context("invalid old start")?;
11975        let old_replace_end = completion
11976            .old_replace_end
11977            .and_then(deserialize_anchor)
11978            .context("invalid old end")?;
11979        let insert_range = {
11980            match completion.old_insert_start.zip(completion.old_insert_end) {
11981                Some((start, end)) => {
11982                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11983                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11984                    Some(start..end)
11985                }
11986                None => None,
11987            }
11988        };
11989        Ok(CoreCompletion {
11990            replace_range: old_replace_start..old_replace_end,
11991            new_text: completion.new_text,
11992            source: match proto::completion::Source::from_i32(completion.source) {
11993                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11994                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11995                    insert_range,
11996                    server_id: LanguageServerId::from_proto(completion.server_id),
11997                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11998                    lsp_defaults: completion
11999                        .lsp_defaults
12000                        .as_deref()
12001                        .map(serde_json::from_slice)
12002                        .transpose()?,
12003                    resolved: completion.resolved,
12004                },
12005                Some(proto::completion::Source::BufferWord) => {
12006                    let word_range = completion
12007                        .buffer_word_start
12008                        .and_then(deserialize_anchor)
12009                        .context("invalid buffer word start")?
12010                        ..completion
12011                            .buffer_word_end
12012                            .and_then(deserialize_anchor)
12013                            .context("invalid buffer word end")?;
12014                    CompletionSource::BufferWord {
12015                        word_range,
12016                        resolved: completion.resolved,
12017                    }
12018                }
12019                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12020                    sort_text: completion
12021                        .sort_text
12022                        .context("expected sort text to exist")?,
12023                },
12024                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12025            },
12026        })
12027    }
12028
12029    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12030        let (kind, lsp_action) = match &action.lsp_action {
12031            LspAction::Action(code_action) => (
12032                proto::code_action::Kind::Action as i32,
12033                serde_json::to_vec(code_action).unwrap(),
12034            ),
12035            LspAction::Command(command) => (
12036                proto::code_action::Kind::Command as i32,
12037                serde_json::to_vec(command).unwrap(),
12038            ),
12039            LspAction::CodeLens(code_lens) => (
12040                proto::code_action::Kind::CodeLens as i32,
12041                serde_json::to_vec(code_lens).unwrap(),
12042            ),
12043        };
12044
12045        proto::CodeAction {
12046            server_id: action.server_id.0 as u64,
12047            start: Some(serialize_anchor(&action.range.start)),
12048            end: Some(serialize_anchor(&action.range.end)),
12049            lsp_action,
12050            kind,
12051            resolved: action.resolved,
12052        }
12053    }
12054
12055    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12056        let start = action
12057            .start
12058            .and_then(deserialize_anchor)
12059            .context("invalid start")?;
12060        let end = action
12061            .end
12062            .and_then(deserialize_anchor)
12063            .context("invalid end")?;
12064        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12065            Some(proto::code_action::Kind::Action) => {
12066                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12067            }
12068            Some(proto::code_action::Kind::Command) => {
12069                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12070            }
12071            Some(proto::code_action::Kind::CodeLens) => {
12072                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12073            }
12074            None => anyhow::bail!("Unknown action kind {}", action.kind),
12075        };
12076        Ok(CodeAction {
12077            server_id: LanguageServerId(action.server_id as usize),
12078            range: start..end,
12079            resolved: action.resolved,
12080            lsp_action,
12081        })
12082    }
12083
12084    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12085        match &formatting_result {
12086            Ok(_) => self.last_formatting_failure = None,
12087            Err(error) => {
12088                let error_string = format!("{error:#}");
12089                log::error!("Formatting failed: {error_string}");
12090                self.last_formatting_failure
12091                    .replace(error_string.lines().join(" "));
12092            }
12093        }
12094    }
12095
12096    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12097        self.lsp_server_capabilities.remove(&for_server);
12098        for lsp_data in self.lsp_data.values_mut() {
12099            lsp_data.remove_server_data(for_server);
12100        }
12101        if let Some(local) = self.as_local_mut() {
12102            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12103            local
12104                .workspace_pull_diagnostics_result_ids
12105                .remove(&for_server);
12106            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12107                buffer_servers.remove(&for_server);
12108            }
12109        }
12110    }
12111
12112    pub fn result_id_for_buffer_pull(
12113        &self,
12114        server_id: LanguageServerId,
12115        buffer_id: BufferId,
12116        registration_id: &Option<SharedString>,
12117        cx: &App,
12118    ) -> Option<SharedString> {
12119        let abs_path = self
12120            .buffer_store
12121            .read(cx)
12122            .get(buffer_id)
12123            .and_then(|b| File::from_dyn(b.read(cx).file()))
12124            .map(|f| f.abs_path(cx))?;
12125        self.as_local()?
12126            .buffer_pull_diagnostics_result_ids
12127            .get(&server_id)?
12128            .get(registration_id)?
12129            .get(&abs_path)?
12130            .clone()
12131    }
12132
12133    /// Gets all result_ids for a workspace diagnostics pull request.
12134    /// 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.
12135    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12136    pub fn result_ids_for_workspace_refresh(
12137        &self,
12138        server_id: LanguageServerId,
12139        registration_id: &Option<SharedString>,
12140    ) -> HashMap<PathBuf, SharedString> {
12141        let Some(local) = self.as_local() else {
12142            return HashMap::default();
12143        };
12144        local
12145            .workspace_pull_diagnostics_result_ids
12146            .get(&server_id)
12147            .into_iter()
12148            .filter_map(|diagnostics| diagnostics.get(registration_id))
12149            .flatten()
12150            .filter_map(|(abs_path, result_id)| {
12151                let result_id = local
12152                    .buffer_pull_diagnostics_result_ids
12153                    .get(&server_id)
12154                    .and_then(|buffer_ids_result_ids| {
12155                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12156                    })
12157                    .cloned()
12158                    .flatten()
12159                    .or_else(|| result_id.clone())?;
12160                Some((abs_path.clone(), result_id))
12161            })
12162            .collect()
12163    }
12164
12165    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12166        if let Some(LanguageServerState::Running {
12167            workspace_diagnostics_refresh_tasks,
12168            ..
12169        }) = self
12170            .as_local_mut()
12171            .and_then(|local| local.language_servers.get_mut(&server_id))
12172        {
12173            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12174                diagnostics.refresh_tx.try_send(()).ok();
12175            }
12176        }
12177    }
12178
12179    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12180    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12181    /// which requires refreshing both workspace and document diagnostics.
12182    pub fn pull_document_diagnostics_for_server(
12183        &mut self,
12184        server_id: LanguageServerId,
12185        cx: &mut Context<Self>,
12186    ) -> Task<()> {
12187        let buffers_to_pull = self
12188            .as_local()
12189            .into_iter()
12190            .flat_map(|local| {
12191                self.buffer_store.read(cx).buffers().filter(|buffer| {
12192                    let buffer_id = buffer.read(cx).remote_id();
12193                    local
12194                        .buffers_opened_in_servers
12195                        .get(&buffer_id)
12196                        .is_some_and(|servers| servers.contains(&server_id))
12197                })
12198            })
12199            .collect::<Vec<_>>();
12200
12201        let pulls = join_all(buffers_to_pull.into_iter().map(|buffer| {
12202            let buffer_path = buffer.read(cx).file().map(|f| f.full_path(cx));
12203            let pull_task = self.pull_diagnostics_for_buffer(buffer, cx);
12204            async move { (buffer_path, pull_task.await) }
12205        }));
12206        cx.background_spawn(async move {
12207            for (pull_task_path, pull_task_result) in pulls.await {
12208                if let Err(e) = pull_task_result {
12209                    match pull_task_path {
12210                        Some(path) => {
12211                            log::error!("Failed to pull diagnostics for buffer {path:?}: {e:#}");
12212                        }
12213                        None => log::error!("Failed to pull diagnostics: {e:#}"),
12214                    }
12215                }
12216            }
12217        })
12218    }
12219
12220    fn apply_workspace_diagnostic_report(
12221        &mut self,
12222        server_id: LanguageServerId,
12223        report: lsp::WorkspaceDiagnosticReportResult,
12224        registration_id: Option<SharedString>,
12225        cx: &mut Context<Self>,
12226    ) {
12227        let mut workspace_diagnostics =
12228            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12229                report,
12230                server_id,
12231                registration_id,
12232            );
12233        workspace_diagnostics.retain(|d| match &d.diagnostics {
12234            LspPullDiagnostics::Response {
12235                server_id,
12236                registration_id,
12237                ..
12238            } => self.diagnostic_registration_exists(*server_id, registration_id),
12239            LspPullDiagnostics::Default => false,
12240        });
12241        let mut unchanged_buffers = HashMap::default();
12242        let workspace_diagnostics_updates = workspace_diagnostics
12243            .into_iter()
12244            .filter_map(
12245                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12246                    LspPullDiagnostics::Response {
12247                        server_id,
12248                        uri,
12249                        diagnostics,
12250                        registration_id,
12251                    } => Some((
12252                        server_id,
12253                        uri,
12254                        diagnostics,
12255                        workspace_diagnostics.version,
12256                        registration_id,
12257                    )),
12258                    LspPullDiagnostics::Default => None,
12259                },
12260            )
12261            .fold(
12262                HashMap::default(),
12263                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12264                    let (result_id, diagnostics) = match diagnostics {
12265                        PulledDiagnostics::Unchanged { result_id } => {
12266                            unchanged_buffers
12267                                .entry(new_registration_id.clone())
12268                                .or_insert_with(HashSet::default)
12269                                .insert(uri.clone());
12270                            (Some(result_id), Vec::new())
12271                        }
12272                        PulledDiagnostics::Changed {
12273                            result_id,
12274                            diagnostics,
12275                        } => (result_id, diagnostics),
12276                    };
12277                    let disk_based_sources = Cow::Owned(
12278                        self.language_server_adapter_for_id(server_id)
12279                            .as_ref()
12280                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12281                            .unwrap_or(&[])
12282                            .to_vec(),
12283                    );
12284
12285                    let Some(abs_path) = uri.to_file_path().ok() else {
12286                        return acc;
12287                    };
12288                    let Some((worktree, relative_path)) =
12289                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12290                    else {
12291                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12292                        return acc;
12293                    };
12294                    let worktree_id = worktree.read(cx).id();
12295                    let project_path = ProjectPath {
12296                        worktree_id,
12297                        path: relative_path,
12298                    };
12299                    if let Some(local_lsp_store) = self.as_local_mut() {
12300                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12301                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12302                    }
12303                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12304                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12305                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12306                        acc.entry(server_id)
12307                            .or_insert_with(HashMap::default)
12308                            .entry(new_registration_id.clone())
12309                            .or_insert_with(Vec::new)
12310                            .push(DocumentDiagnosticsUpdate {
12311                                server_id,
12312                                diagnostics: lsp::PublishDiagnosticsParams {
12313                                    uri,
12314                                    diagnostics,
12315                                    version,
12316                                },
12317                                result_id,
12318                                disk_based_sources,
12319                                registration_id: new_registration_id,
12320                            });
12321                    }
12322                    acc
12323                },
12324            );
12325
12326        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12327            for (registration_id, diagnostic_updates) in diagnostic_updates {
12328                self.merge_lsp_diagnostics(
12329                    DiagnosticSourceKind::Pulled,
12330                    diagnostic_updates,
12331                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12332                        DiagnosticSourceKind::Pulled => {
12333                            old_diagnostic.registration_id != registration_id
12334                                || unchanged_buffers
12335                                    .get(&old_diagnostic.registration_id)
12336                                    .is_some_and(|unchanged_buffers| {
12337                                        unchanged_buffers.contains(&document_uri)
12338                                    })
12339                        }
12340                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12341                    },
12342                    cx,
12343                )
12344                .log_err();
12345            }
12346        }
12347    }
12348
12349    fn register_server_capabilities(
12350        &mut self,
12351        server_id: LanguageServerId,
12352        params: lsp::RegistrationParams,
12353        cx: &mut Context<Self>,
12354    ) -> anyhow::Result<()> {
12355        let server = self
12356            .language_server_for_id(server_id)
12357            .with_context(|| format!("no server {server_id} found"))?;
12358        for reg in params.registrations {
12359            match reg.method.as_str() {
12360                "workspace/didChangeWatchedFiles" => {
12361                    if let Some(options) = reg.register_options {
12362                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12363                            let caps = serde_json::from_value(options)?;
12364                            local_lsp_store
12365                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12366                            true
12367                        } else {
12368                            false
12369                        };
12370                        if notify {
12371                            notify_server_capabilities_updated(&server, cx);
12372                        }
12373                    }
12374                }
12375                "workspace/didChangeConfiguration" => {
12376                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12377                }
12378                "workspace/didChangeWorkspaceFolders" => {
12379                    // In this case register options is an empty object, we can ignore it
12380                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12381                        supported: Some(true),
12382                        change_notifications: Some(OneOf::Right(reg.id)),
12383                    };
12384                    server.update_capabilities(|capabilities| {
12385                        capabilities
12386                            .workspace
12387                            .get_or_insert_default()
12388                            .workspace_folders = Some(caps);
12389                    });
12390                    notify_server_capabilities_updated(&server, cx);
12391                }
12392                "workspace/symbol" => {
12393                    let options = parse_register_capabilities(reg)?;
12394                    server.update_capabilities(|capabilities| {
12395                        capabilities.workspace_symbol_provider = Some(options);
12396                    });
12397                    notify_server_capabilities_updated(&server, cx);
12398                }
12399                "workspace/fileOperations" => {
12400                    if let Some(options) = reg.register_options {
12401                        let caps = serde_json::from_value(options)?;
12402                        server.update_capabilities(|capabilities| {
12403                            capabilities
12404                                .workspace
12405                                .get_or_insert_default()
12406                                .file_operations = Some(caps);
12407                        });
12408                        notify_server_capabilities_updated(&server, cx);
12409                    }
12410                }
12411                "workspace/executeCommand" => {
12412                    if let Some(options) = reg.register_options {
12413                        let options = serde_json::from_value(options)?;
12414                        server.update_capabilities(|capabilities| {
12415                            capabilities.execute_command_provider = Some(options);
12416                        });
12417                        notify_server_capabilities_updated(&server, cx);
12418                    }
12419                }
12420                "textDocument/rangeFormatting" => {
12421                    let options = parse_register_capabilities(reg)?;
12422                    server.update_capabilities(|capabilities| {
12423                        capabilities.document_range_formatting_provider = Some(options);
12424                    });
12425                    notify_server_capabilities_updated(&server, cx);
12426                }
12427                "textDocument/onTypeFormatting" => {
12428                    if let Some(options) = reg
12429                        .register_options
12430                        .map(serde_json::from_value)
12431                        .transpose()?
12432                    {
12433                        server.update_capabilities(|capabilities| {
12434                            capabilities.document_on_type_formatting_provider = Some(options);
12435                        });
12436                        notify_server_capabilities_updated(&server, cx);
12437                    }
12438                }
12439                "textDocument/formatting" => {
12440                    let options = parse_register_capabilities(reg)?;
12441                    server.update_capabilities(|capabilities| {
12442                        capabilities.document_formatting_provider = Some(options);
12443                    });
12444                    notify_server_capabilities_updated(&server, cx);
12445                }
12446                "textDocument/rename" => {
12447                    let options = parse_register_capabilities(reg)?;
12448                    server.update_capabilities(|capabilities| {
12449                        capabilities.rename_provider = Some(options);
12450                    });
12451                    notify_server_capabilities_updated(&server, cx);
12452                }
12453                "textDocument/inlayHint" => {
12454                    let options = parse_register_capabilities(reg)?;
12455                    server.update_capabilities(|capabilities| {
12456                        capabilities.inlay_hint_provider = Some(options);
12457                    });
12458                    notify_server_capabilities_updated(&server, cx);
12459                }
12460                "textDocument/documentSymbol" => {
12461                    let options = parse_register_capabilities(reg)?;
12462                    server.update_capabilities(|capabilities| {
12463                        capabilities.document_symbol_provider = Some(options);
12464                    });
12465                    notify_server_capabilities_updated(&server, cx);
12466                }
12467                "textDocument/codeAction" => {
12468                    let options = parse_register_capabilities(reg)?;
12469                    let provider = match options {
12470                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12471                        OneOf::Right(caps) => caps,
12472                    };
12473                    server.update_capabilities(|capabilities| {
12474                        capabilities.code_action_provider = Some(provider);
12475                    });
12476                    notify_server_capabilities_updated(&server, cx);
12477                }
12478                "textDocument/definition" => {
12479                    let options = parse_register_capabilities(reg)?;
12480                    server.update_capabilities(|capabilities| {
12481                        capabilities.definition_provider = Some(options);
12482                    });
12483                    notify_server_capabilities_updated(&server, cx);
12484                }
12485                "textDocument/completion" => {
12486                    if let Some(caps) = reg
12487                        .register_options
12488                        .map(serde_json::from_value::<CompletionOptions>)
12489                        .transpose()?
12490                    {
12491                        server.update_capabilities(|capabilities| {
12492                            capabilities.completion_provider = Some(caps.clone());
12493                        });
12494
12495                        if let Some(local) = self.as_local() {
12496                            let mut buffers_with_language_server = Vec::new();
12497                            for handle in self.buffer_store.read(cx).buffers() {
12498                                let buffer_id = handle.read(cx).remote_id();
12499                                if local
12500                                    .buffers_opened_in_servers
12501                                    .get(&buffer_id)
12502                                    .filter(|s| s.contains(&server_id))
12503                                    .is_some()
12504                                {
12505                                    buffers_with_language_server.push(handle);
12506                                }
12507                            }
12508                            let triggers = caps
12509                                .trigger_characters
12510                                .unwrap_or_default()
12511                                .into_iter()
12512                                .collect::<BTreeSet<_>>();
12513                            for handle in buffers_with_language_server {
12514                                let triggers = triggers.clone();
12515                                let _ = handle.update(cx, move |buffer, cx| {
12516                                    buffer.set_completion_triggers(server_id, triggers, cx);
12517                                });
12518                            }
12519                        }
12520                        notify_server_capabilities_updated(&server, cx);
12521                    }
12522                }
12523                "textDocument/hover" => {
12524                    let options = parse_register_capabilities(reg)?;
12525                    let provider = match options {
12526                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12527                        OneOf::Right(caps) => caps,
12528                    };
12529                    server.update_capabilities(|capabilities| {
12530                        capabilities.hover_provider = Some(provider);
12531                    });
12532                    notify_server_capabilities_updated(&server, cx);
12533                }
12534                "textDocument/signatureHelp" => {
12535                    if let Some(caps) = reg
12536                        .register_options
12537                        .map(serde_json::from_value)
12538                        .transpose()?
12539                    {
12540                        server.update_capabilities(|capabilities| {
12541                            capabilities.signature_help_provider = Some(caps);
12542                        });
12543                        notify_server_capabilities_updated(&server, cx);
12544                    }
12545                }
12546                "textDocument/didChange" => {
12547                    if let Some(sync_kind) = reg
12548                        .register_options
12549                        .and_then(|opts| opts.get("syncKind").cloned())
12550                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12551                        .transpose()?
12552                    {
12553                        server.update_capabilities(|capabilities| {
12554                            let mut sync_options =
12555                                Self::take_text_document_sync_options(capabilities);
12556                            sync_options.change = Some(sync_kind);
12557                            capabilities.text_document_sync =
12558                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12559                        });
12560                        notify_server_capabilities_updated(&server, cx);
12561                    }
12562                }
12563                "textDocument/didSave" => {
12564                    if let Some(include_text) = reg
12565                        .register_options
12566                        .map(|opts| {
12567                            let transpose = opts
12568                                .get("includeText")
12569                                .cloned()
12570                                .map(serde_json::from_value::<Option<bool>>)
12571                                .transpose();
12572                            match transpose {
12573                                Ok(value) => Ok(value.flatten()),
12574                                Err(e) => Err(e),
12575                            }
12576                        })
12577                        .transpose()?
12578                    {
12579                        server.update_capabilities(|capabilities| {
12580                            let mut sync_options =
12581                                Self::take_text_document_sync_options(capabilities);
12582                            sync_options.save =
12583                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12584                                    include_text,
12585                                }));
12586                            capabilities.text_document_sync =
12587                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12588                        });
12589                        notify_server_capabilities_updated(&server, cx);
12590                    }
12591                }
12592                "textDocument/codeLens" => {
12593                    if let Some(caps) = reg
12594                        .register_options
12595                        .map(serde_json::from_value)
12596                        .transpose()?
12597                    {
12598                        server.update_capabilities(|capabilities| {
12599                            capabilities.code_lens_provider = Some(caps);
12600                        });
12601                        notify_server_capabilities_updated(&server, cx);
12602                    }
12603                }
12604                "textDocument/diagnostic" => {
12605                    if let Some(caps) = reg
12606                        .register_options
12607                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12608                        .transpose()?
12609                    {
12610                        let local = self
12611                            .as_local_mut()
12612                            .context("Expected LSP Store to be local")?;
12613                        let state = local
12614                            .language_servers
12615                            .get_mut(&server_id)
12616                            .context("Could not obtain Language Servers state")?;
12617                        local
12618                            .language_server_dynamic_registrations
12619                            .entry(server_id)
12620                            .or_default()
12621                            .diagnostics
12622                            .insert(Some(reg.id.clone()), caps.clone());
12623
12624                        let supports_workspace_diagnostics =
12625                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12626                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12627                                    diagnostic_options.workspace_diagnostics
12628                                }
12629                                DiagnosticServerCapabilities::RegistrationOptions(
12630                                    diagnostic_registration_options,
12631                                ) => {
12632                                    diagnostic_registration_options
12633                                        .diagnostic_options
12634                                        .workspace_diagnostics
12635                                }
12636                            };
12637
12638                        if supports_workspace_diagnostics(&caps) {
12639                            if let LanguageServerState::Running {
12640                                workspace_diagnostics_refresh_tasks,
12641                                ..
12642                            } = state
12643                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12644                                    Some(reg.id.clone()),
12645                                    caps.clone(),
12646                                    server.clone(),
12647                                    cx,
12648                                )
12649                            {
12650                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12651                            }
12652                        }
12653
12654                        server.update_capabilities(|capabilities| {
12655                            capabilities.diagnostic_provider = Some(caps);
12656                        });
12657
12658                        notify_server_capabilities_updated(&server, cx);
12659
12660                        self.pull_document_diagnostics_for_server(server_id, cx)
12661                            .detach();
12662                    }
12663                }
12664                "textDocument/documentColor" => {
12665                    let options = parse_register_capabilities(reg)?;
12666                    let provider = match options {
12667                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12668                        OneOf::Right(caps) => caps,
12669                    };
12670                    server.update_capabilities(|capabilities| {
12671                        capabilities.color_provider = Some(provider);
12672                    });
12673                    notify_server_capabilities_updated(&server, cx);
12674                }
12675                _ => log::warn!("unhandled capability registration: {reg:?}"),
12676            }
12677        }
12678
12679        Ok(())
12680    }
12681
12682    fn unregister_server_capabilities(
12683        &mut self,
12684        server_id: LanguageServerId,
12685        params: lsp::UnregistrationParams,
12686        cx: &mut Context<Self>,
12687    ) -> anyhow::Result<()> {
12688        let server = self
12689            .language_server_for_id(server_id)
12690            .with_context(|| format!("no server {server_id} found"))?;
12691        for unreg in params.unregisterations.iter() {
12692            match unreg.method.as_str() {
12693                "workspace/didChangeWatchedFiles" => {
12694                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12695                        local_lsp_store
12696                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12697                        true
12698                    } else {
12699                        false
12700                    };
12701                    if notify {
12702                        notify_server_capabilities_updated(&server, cx);
12703                    }
12704                }
12705                "workspace/didChangeConfiguration" => {
12706                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12707                }
12708                "workspace/didChangeWorkspaceFolders" => {
12709                    server.update_capabilities(|capabilities| {
12710                        capabilities
12711                            .workspace
12712                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12713                                workspace_folders: None,
12714                                file_operations: None,
12715                            })
12716                            .workspace_folders = None;
12717                    });
12718                    notify_server_capabilities_updated(&server, cx);
12719                }
12720                "workspace/symbol" => {
12721                    server.update_capabilities(|capabilities| {
12722                        capabilities.workspace_symbol_provider = None
12723                    });
12724                    notify_server_capabilities_updated(&server, cx);
12725                }
12726                "workspace/fileOperations" => {
12727                    server.update_capabilities(|capabilities| {
12728                        capabilities
12729                            .workspace
12730                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12731                                workspace_folders: None,
12732                                file_operations: None,
12733                            })
12734                            .file_operations = None;
12735                    });
12736                    notify_server_capabilities_updated(&server, cx);
12737                }
12738                "workspace/executeCommand" => {
12739                    server.update_capabilities(|capabilities| {
12740                        capabilities.execute_command_provider = None;
12741                    });
12742                    notify_server_capabilities_updated(&server, cx);
12743                }
12744                "textDocument/rangeFormatting" => {
12745                    server.update_capabilities(|capabilities| {
12746                        capabilities.document_range_formatting_provider = None
12747                    });
12748                    notify_server_capabilities_updated(&server, cx);
12749                }
12750                "textDocument/onTypeFormatting" => {
12751                    server.update_capabilities(|capabilities| {
12752                        capabilities.document_on_type_formatting_provider = None;
12753                    });
12754                    notify_server_capabilities_updated(&server, cx);
12755                }
12756                "textDocument/formatting" => {
12757                    server.update_capabilities(|capabilities| {
12758                        capabilities.document_formatting_provider = None;
12759                    });
12760                    notify_server_capabilities_updated(&server, cx);
12761                }
12762                "textDocument/rename" => {
12763                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12764                    notify_server_capabilities_updated(&server, cx);
12765                }
12766                "textDocument/codeAction" => {
12767                    server.update_capabilities(|capabilities| {
12768                        capabilities.code_action_provider = None;
12769                    });
12770                    notify_server_capabilities_updated(&server, cx);
12771                }
12772                "textDocument/definition" => {
12773                    server.update_capabilities(|capabilities| {
12774                        capabilities.definition_provider = None;
12775                    });
12776                    notify_server_capabilities_updated(&server, cx);
12777                }
12778                "textDocument/completion" => {
12779                    server.update_capabilities(|capabilities| {
12780                        capabilities.completion_provider = None;
12781                    });
12782                    notify_server_capabilities_updated(&server, cx);
12783                }
12784                "textDocument/hover" => {
12785                    server.update_capabilities(|capabilities| {
12786                        capabilities.hover_provider = None;
12787                    });
12788                    notify_server_capabilities_updated(&server, cx);
12789                }
12790                "textDocument/signatureHelp" => {
12791                    server.update_capabilities(|capabilities| {
12792                        capabilities.signature_help_provider = None;
12793                    });
12794                    notify_server_capabilities_updated(&server, cx);
12795                }
12796                "textDocument/didChange" => {
12797                    server.update_capabilities(|capabilities| {
12798                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12799                        sync_options.change = None;
12800                        capabilities.text_document_sync =
12801                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12802                    });
12803                    notify_server_capabilities_updated(&server, cx);
12804                }
12805                "textDocument/didSave" => {
12806                    server.update_capabilities(|capabilities| {
12807                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12808                        sync_options.save = None;
12809                        capabilities.text_document_sync =
12810                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12811                    });
12812                    notify_server_capabilities_updated(&server, cx);
12813                }
12814                "textDocument/codeLens" => {
12815                    server.update_capabilities(|capabilities| {
12816                        capabilities.code_lens_provider = None;
12817                    });
12818                    notify_server_capabilities_updated(&server, cx);
12819                }
12820                "textDocument/diagnostic" => {
12821                    let local = self
12822                        .as_local_mut()
12823                        .context("Expected LSP Store to be local")?;
12824
12825                    let state = local
12826                        .language_servers
12827                        .get_mut(&server_id)
12828                        .context("Could not obtain Language Servers state")?;
12829                    let registrations = local
12830                        .language_server_dynamic_registrations
12831                        .get_mut(&server_id)
12832                        .with_context(|| {
12833                            format!("Expected dynamic registration to exist for server {server_id}")
12834                        })?;
12835                    registrations.diagnostics
12836                        .remove(&Some(unreg.id.clone()))
12837                        .with_context(|| format!(
12838                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12839                            unreg.id)
12840                        )?;
12841                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12842
12843                    if let LanguageServerState::Running {
12844                        workspace_diagnostics_refresh_tasks,
12845                        ..
12846                    } = state
12847                    {
12848                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12849                    }
12850
12851                    self.clear_unregistered_diagnostics(
12852                        server_id,
12853                        SharedString::from(unreg.id.clone()),
12854                        cx,
12855                    )?;
12856
12857                    if removed_last_diagnostic_provider {
12858                        server.update_capabilities(|capabilities| {
12859                            debug_assert!(capabilities.diagnostic_provider.is_some());
12860                            capabilities.diagnostic_provider = None;
12861                        });
12862                    }
12863
12864                    notify_server_capabilities_updated(&server, cx);
12865                }
12866                "textDocument/documentColor" => {
12867                    server.update_capabilities(|capabilities| {
12868                        capabilities.color_provider = None;
12869                    });
12870                    notify_server_capabilities_updated(&server, cx);
12871                }
12872                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12873            }
12874        }
12875
12876        Ok(())
12877    }
12878
12879    fn clear_unregistered_diagnostics(
12880        &mut self,
12881        server_id: LanguageServerId,
12882        cleared_registration_id: SharedString,
12883        cx: &mut Context<Self>,
12884    ) -> anyhow::Result<()> {
12885        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12886
12887        self.buffer_store.update(cx, |buffer_store, cx| {
12888            for buffer_handle in buffer_store.buffers() {
12889                let buffer = buffer_handle.read(cx);
12890                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12891                let Some(abs_path) = abs_path else {
12892                    continue;
12893                };
12894                affected_abs_paths.insert(abs_path);
12895            }
12896        });
12897
12898        let local = self.as_local().context("Expected LSP Store to be local")?;
12899        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12900            let Some(worktree) = self
12901                .worktree_store
12902                .read(cx)
12903                .worktree_for_id(*worktree_id, cx)
12904            else {
12905                continue;
12906            };
12907
12908            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
12909                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
12910                    let has_matching_registration =
12911                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
12912                            entry.diagnostic.registration_id.as_ref()
12913                                == Some(&cleared_registration_id)
12914                        });
12915                    if has_matching_registration {
12916                        let abs_path = worktree.read(cx).absolutize(rel_path);
12917                        affected_abs_paths.insert(abs_path);
12918                    }
12919                }
12920            }
12921        }
12922
12923        if affected_abs_paths.is_empty() {
12924            return Ok(());
12925        }
12926
12927        // Send a fake diagnostic update which clears the state for the registration ID
12928        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
12929            affected_abs_paths
12930                .into_iter()
12931                .map(|abs_path| DocumentDiagnosticsUpdate {
12932                    diagnostics: DocumentDiagnostics {
12933                        diagnostics: Vec::new(),
12934                        document_abs_path: abs_path,
12935                        version: None,
12936                    },
12937                    result_id: None,
12938                    registration_id: Some(cleared_registration_id.clone()),
12939                    server_id,
12940                    disk_based_sources: Cow::Borrowed(&[]),
12941                })
12942                .collect();
12943
12944        let merge_registration_id = cleared_registration_id.clone();
12945        self.merge_diagnostic_entries(
12946            clears,
12947            move |_, diagnostic, _| {
12948                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
12949                    diagnostic.registration_id != Some(merge_registration_id.clone())
12950                } else {
12951                    true
12952                }
12953            },
12954            cx,
12955        )?;
12956
12957        Ok(())
12958    }
12959
12960    async fn deduplicate_range_based_lsp_requests<T>(
12961        lsp_store: &Entity<Self>,
12962        server_id: Option<LanguageServerId>,
12963        lsp_request_id: LspRequestId,
12964        proto_request: &T::ProtoRequest,
12965        range: Range<Anchor>,
12966        cx: &mut AsyncApp,
12967    ) -> Result<()>
12968    where
12969        T: LspCommand,
12970        T::ProtoRequest: proto::LspRequestMessage,
12971    {
12972        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12973        let version = deserialize_version(proto_request.buffer_version());
12974        let buffer = lsp_store.update(cx, |this, cx| {
12975            this.buffer_store.read(cx).get_existing(buffer_id)
12976        })?;
12977        buffer
12978            .update(cx, |buffer, _| buffer.wait_for_version(version))
12979            .await?;
12980        lsp_store.update(cx, |lsp_store, cx| {
12981            let buffer_snapshot = buffer.read(cx).snapshot();
12982            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12983            let chunks_queried_for = lsp_data
12984                .inlay_hints
12985                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12986                .collect::<Vec<_>>();
12987            match chunks_queried_for.as_slice() {
12988                &[chunk] => {
12989                    let key = LspKey {
12990                        request_type: TypeId::of::<T>(),
12991                        server_queried: server_id,
12992                    };
12993                    let previous_request = lsp_data
12994                        .chunk_lsp_requests
12995                        .entry(key)
12996                        .or_default()
12997                        .insert(chunk, lsp_request_id);
12998                    if let Some((previous_request, running_requests)) =
12999                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13000                    {
13001                        running_requests.remove(&previous_request);
13002                    }
13003                }
13004                _ambiguous_chunks => {
13005                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13006                    // there, a buffer version-based check will be performed and outdated requests discarded.
13007                }
13008            }
13009            anyhow::Ok(())
13010        })?;
13011
13012        Ok(())
13013    }
13014
13015    async fn query_lsp_locally<T>(
13016        lsp_store: Entity<Self>,
13017        for_server_id: Option<LanguageServerId>,
13018        sender_id: proto::PeerId,
13019        lsp_request_id: LspRequestId,
13020        proto_request: T::ProtoRequest,
13021        position: Option<Anchor>,
13022        cx: &mut AsyncApp,
13023    ) -> Result<()>
13024    where
13025        T: LspCommand + Clone,
13026        T::ProtoRequest: proto::LspRequestMessage,
13027        <T::ProtoRequest as proto::RequestMessage>::Response:
13028            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13029    {
13030        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13031        let version = deserialize_version(proto_request.buffer_version());
13032        let buffer = lsp_store.update(cx, |this, cx| {
13033            this.buffer_store.read(cx).get_existing(buffer_id)
13034        })?;
13035        buffer
13036            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13037            .await?;
13038        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13039        let request =
13040            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13041        let key = LspKey {
13042            request_type: TypeId::of::<T>(),
13043            server_queried: for_server_id,
13044        };
13045        lsp_store.update(cx, |lsp_store, cx| {
13046            let request_task = match for_server_id {
13047                Some(server_id) => {
13048                    let server_task = lsp_store.request_lsp(
13049                        buffer.clone(),
13050                        LanguageServerToQuery::Other(server_id),
13051                        request.clone(),
13052                        cx,
13053                    );
13054                    cx.background_spawn(async move {
13055                        let mut responses = Vec::new();
13056                        match server_task.await {
13057                            Ok(response) => responses.push((server_id, response)),
13058                            // rust-analyzer likes to error with this when its still loading up
13059                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13060                            Err(e) => log::error!(
13061                                "Error handling response for request {request:?}: {e:#}"
13062                            ),
13063                        }
13064                        responses
13065                    })
13066                }
13067                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13068            };
13069            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13070            if T::ProtoRequest::stop_previous_requests() {
13071                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13072                    lsp_requests.clear();
13073                }
13074            }
13075            lsp_data.lsp_requests.entry(key).or_default().insert(
13076                lsp_request_id,
13077                cx.spawn(async move |lsp_store, cx| {
13078                    let response = request_task.await;
13079                    lsp_store
13080                        .update(cx, |lsp_store, cx| {
13081                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13082                            {
13083                                let response = response
13084                                    .into_iter()
13085                                    .map(|(server_id, response)| {
13086                                        (
13087                                            server_id.to_proto(),
13088                                            T::response_to_proto(
13089                                                response,
13090                                                lsp_store,
13091                                                sender_id,
13092                                                &buffer_version,
13093                                                cx,
13094                                            )
13095                                            .into(),
13096                                        )
13097                                    })
13098                                    .collect::<HashMap<_, _>>();
13099                                match client.send_lsp_response::<T::ProtoRequest>(
13100                                    project_id,
13101                                    lsp_request_id,
13102                                    response,
13103                                ) {
13104                                    Ok(()) => {}
13105                                    Err(e) => {
13106                                        log::error!("Failed to send LSP response: {e:#}",)
13107                                    }
13108                                }
13109                            }
13110                        })
13111                        .ok();
13112                }),
13113            );
13114        });
13115        Ok(())
13116    }
13117
13118    fn take_text_document_sync_options(
13119        capabilities: &mut lsp::ServerCapabilities,
13120    ) -> lsp::TextDocumentSyncOptions {
13121        match capabilities.text_document_sync.take() {
13122            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13123            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13124                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13125                sync_options.change = Some(sync_kind);
13126                sync_options
13127            }
13128            None => lsp::TextDocumentSyncOptions::default(),
13129        }
13130    }
13131
13132    #[cfg(any(test, feature = "test-support"))]
13133    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
13134        Some(
13135            self.lsp_data
13136                .get_mut(&buffer_id)?
13137                .code_lens
13138                .take()?
13139                .update
13140                .take()?
13141                .1,
13142        )
13143    }
13144
13145    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13146        self.downstream_client.clone()
13147    }
13148
13149    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13150        self.worktree_store.clone()
13151    }
13152
13153    /// Gets what's stored in the LSP data for the given buffer.
13154    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13155        self.lsp_data.get_mut(&buffer_id)
13156    }
13157
13158    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13159    /// new [`BufferLspData`] will be created to replace the previous state.
13160    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13161        let (buffer_id, buffer_version) =
13162            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13163        let lsp_data = self
13164            .lsp_data
13165            .entry(buffer_id)
13166            .or_insert_with(|| BufferLspData::new(buffer, cx));
13167        if buffer_version.changed_since(&lsp_data.buffer_version) {
13168            *lsp_data = BufferLspData::new(buffer, cx);
13169        }
13170        lsp_data
13171    }
13172}
13173
13174// Registration with registerOptions as null, should fallback to true.
13175// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13176fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13177    reg: lsp::Registration,
13178) -> Result<OneOf<bool, T>> {
13179    Ok(match reg.register_options {
13180        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13181        None => OneOf::Left(true),
13182    })
13183}
13184
13185fn subscribe_to_binary_statuses(
13186    languages: &Arc<LanguageRegistry>,
13187    cx: &mut Context<'_, LspStore>,
13188) -> Task<()> {
13189    let mut server_statuses = languages.language_server_binary_statuses();
13190    cx.spawn(async move |lsp_store, cx| {
13191        while let Some((server_name, binary_status)) = server_statuses.next().await {
13192            if lsp_store
13193                .update(cx, |_, cx| {
13194                    let mut message = None;
13195                    let binary_status = match binary_status {
13196                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13197                        BinaryStatus::CheckingForUpdate => {
13198                            proto::ServerBinaryStatus::CheckingForUpdate
13199                        }
13200                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13201                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13202                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13203                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13204                        BinaryStatus::Failed { error } => {
13205                            message = Some(error);
13206                            proto::ServerBinaryStatus::Failed
13207                        }
13208                    };
13209                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13210                        // Binary updates are about the binary that might not have any language server id at that point.
13211                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13212                        language_server_id: LanguageServerId(0),
13213                        name: Some(server_name),
13214                        message: proto::update_language_server::Variant::StatusUpdate(
13215                            proto::StatusUpdate {
13216                                message,
13217                                status: Some(proto::status_update::Status::Binary(
13218                                    binary_status as i32,
13219                                )),
13220                            },
13221                        ),
13222                    });
13223                })
13224                .is_err()
13225            {
13226                break;
13227            }
13228        }
13229    })
13230}
13231
13232fn lsp_workspace_diagnostics_refresh(
13233    registration_id: Option<String>,
13234    options: DiagnosticServerCapabilities,
13235    server: Arc<LanguageServer>,
13236    cx: &mut Context<'_, LspStore>,
13237) -> Option<WorkspaceRefreshTask> {
13238    let identifier = workspace_diagnostic_identifier(&options)?;
13239    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13240
13241    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13242    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13243    refresh_tx.try_send(()).ok();
13244
13245    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13246        let mut attempts = 0;
13247        let max_attempts = 50;
13248        let mut requests = 0;
13249
13250        loop {
13251            let Some(()) = refresh_rx.recv().await else {
13252                return;
13253            };
13254
13255            'request: loop {
13256                requests += 1;
13257                if attempts > max_attempts {
13258                    log::error!(
13259                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13260                    );
13261                    return;
13262                }
13263                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13264                cx.background_executor()
13265                    .timer(Duration::from_millis(backoff_millis))
13266                    .await;
13267                attempts += 1;
13268
13269                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13270                    lsp_store
13271                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13272                        .into_iter()
13273                        .filter_map(|(abs_path, result_id)| {
13274                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13275                            Some(lsp::PreviousResultId {
13276                                uri,
13277                                value: result_id.to_string(),
13278                            })
13279                        })
13280                        .collect()
13281                }) else {
13282                    return;
13283                };
13284
13285                let token = if let Some(registration_id) = &registration_id {
13286                    format!(
13287                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13288                        server.server_id(),
13289                    )
13290                } else {
13291                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13292                };
13293
13294                progress_rx.try_recv().ok();
13295                let timer =
13296                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13297                let progress = pin!(progress_rx.recv().fuse());
13298                let response_result = server
13299                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13300                        lsp::WorkspaceDiagnosticParams {
13301                            previous_result_ids,
13302                            identifier: identifier.clone(),
13303                            work_done_progress_params: Default::default(),
13304                            partial_result_params: lsp::PartialResultParams {
13305                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13306                            },
13307                        },
13308                        select(timer, progress).then(|either| match either {
13309                            Either::Left((message, ..)) => ready(message).left_future(),
13310                            Either::Right(..) => pending::<String>().right_future(),
13311                        }),
13312                    )
13313                    .await;
13314
13315                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13316                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13317                match response_result {
13318                    ConnectionResult::Timeout => {
13319                        log::error!("Timeout during workspace diagnostics pull");
13320                        continue 'request;
13321                    }
13322                    ConnectionResult::ConnectionReset => {
13323                        log::error!("Server closed a workspace diagnostics pull request");
13324                        continue 'request;
13325                    }
13326                    ConnectionResult::Result(Err(e)) => {
13327                        log::error!("Error during workspace diagnostics pull: {e:#}");
13328                        break 'request;
13329                    }
13330                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13331                        attempts = 0;
13332                        if lsp_store
13333                            .update(cx, |lsp_store, cx| {
13334                                lsp_store.apply_workspace_diagnostic_report(
13335                                    server.server_id(),
13336                                    pulled_diagnostics,
13337                                    registration_id_shared.clone(),
13338                                    cx,
13339                                )
13340                            })
13341                            .is_err()
13342                        {
13343                            return;
13344                        }
13345                        break 'request;
13346                    }
13347                }
13348            }
13349        }
13350    });
13351
13352    Some(WorkspaceRefreshTask {
13353        refresh_tx,
13354        progress_tx,
13355        task: workspace_query_language_server,
13356    })
13357}
13358
13359fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13360    match &options {
13361        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13362            diagnostic_options.identifier.clone()
13363        }
13364        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13365            let diagnostic_options = &registration_options.diagnostic_options;
13366            diagnostic_options.identifier.clone()
13367        }
13368    }
13369}
13370
13371fn workspace_diagnostic_identifier(
13372    options: &DiagnosticServerCapabilities,
13373) -> Option<Option<String>> {
13374    match &options {
13375        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13376            if !diagnostic_options.workspace_diagnostics {
13377                return None;
13378            }
13379            Some(diagnostic_options.identifier.clone())
13380        }
13381        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13382            let diagnostic_options = &registration_options.diagnostic_options;
13383            if !diagnostic_options.workspace_diagnostics {
13384                return None;
13385            }
13386            Some(diagnostic_options.identifier.clone())
13387        }
13388    }
13389}
13390
13391fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13392    let CompletionSource::BufferWord {
13393        word_range,
13394        resolved,
13395    } = &mut completion.source
13396    else {
13397        return;
13398    };
13399    if *resolved {
13400        return;
13401    }
13402
13403    if completion.new_text
13404        != snapshot
13405            .text_for_range(word_range.clone())
13406            .collect::<String>()
13407    {
13408        return;
13409    }
13410
13411    let mut offset = 0;
13412    for chunk in snapshot.chunks(word_range.clone(), true) {
13413        let end_offset = offset + chunk.text.len();
13414        if let Some(highlight_id) = chunk.syntax_highlight_id {
13415            completion
13416                .label
13417                .runs
13418                .push((offset..end_offset, highlight_id));
13419        }
13420        offset = end_offset;
13421    }
13422    *resolved = true;
13423}
13424
13425impl EventEmitter<LspStoreEvent> for LspStore {}
13426
13427fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13428    hover
13429        .contents
13430        .retain(|hover_block| !hover_block.text.trim().is_empty());
13431    if hover.contents.is_empty() {
13432        None
13433    } else {
13434        Some(hover)
13435    }
13436}
13437
13438async fn populate_labels_for_completions(
13439    new_completions: Vec<CoreCompletion>,
13440    language: Option<Arc<Language>>,
13441    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13442) -> Vec<Completion> {
13443    let lsp_completions = new_completions
13444        .iter()
13445        .filter_map(|new_completion| {
13446            new_completion
13447                .source
13448                .lsp_completion(true)
13449                .map(|lsp_completion| lsp_completion.into_owned())
13450        })
13451        .collect::<Vec<_>>();
13452
13453    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13454        lsp_adapter
13455            .labels_for_completions(&lsp_completions, language)
13456            .await
13457            .log_err()
13458            .unwrap_or_default()
13459    } else {
13460        Vec::new()
13461    }
13462    .into_iter()
13463    .fuse();
13464
13465    let mut completions = Vec::new();
13466    for completion in new_completions {
13467        match completion.source.lsp_completion(true) {
13468            Some(lsp_completion) => {
13469                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13470
13471                let mut label = labels.next().flatten().unwrap_or_else(|| {
13472                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13473                });
13474                ensure_uniform_list_compatible_label(&mut label);
13475                completions.push(Completion {
13476                    label,
13477                    documentation,
13478                    replace_range: completion.replace_range,
13479                    new_text: completion.new_text,
13480                    insert_text_mode: lsp_completion.insert_text_mode,
13481                    source: completion.source,
13482                    icon_path: None,
13483                    confirm: None,
13484                    match_start: None,
13485                    snippet_deduplication_key: None,
13486                });
13487            }
13488            None => {
13489                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13490                ensure_uniform_list_compatible_label(&mut label);
13491                completions.push(Completion {
13492                    label,
13493                    documentation: None,
13494                    replace_range: completion.replace_range,
13495                    new_text: completion.new_text,
13496                    source: completion.source,
13497                    insert_text_mode: None,
13498                    icon_path: None,
13499                    confirm: None,
13500                    match_start: None,
13501                    snippet_deduplication_key: None,
13502                });
13503            }
13504        }
13505    }
13506    completions
13507}
13508
13509#[derive(Debug)]
13510pub enum LanguageServerToQuery {
13511    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13512    FirstCapable,
13513    /// Query a specific language server.
13514    Other(LanguageServerId),
13515}
13516
13517#[derive(Default)]
13518struct RenamePathsWatchedForServer {
13519    did_rename: Vec<RenameActionPredicate>,
13520    will_rename: Vec<RenameActionPredicate>,
13521}
13522
13523impl RenamePathsWatchedForServer {
13524    fn with_did_rename_patterns(
13525        mut self,
13526        did_rename: Option<&FileOperationRegistrationOptions>,
13527    ) -> Self {
13528        if let Some(did_rename) = did_rename {
13529            self.did_rename = did_rename
13530                .filters
13531                .iter()
13532                .filter_map(|filter| filter.try_into().log_err())
13533                .collect();
13534        }
13535        self
13536    }
13537    fn with_will_rename_patterns(
13538        mut self,
13539        will_rename: Option<&FileOperationRegistrationOptions>,
13540    ) -> Self {
13541        if let Some(will_rename) = will_rename {
13542            self.will_rename = will_rename
13543                .filters
13544                .iter()
13545                .filter_map(|filter| filter.try_into().log_err())
13546                .collect();
13547        }
13548        self
13549    }
13550
13551    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13552        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13553    }
13554    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13555        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13556    }
13557}
13558
13559impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13560    type Error = globset::Error;
13561    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13562        Ok(Self {
13563            kind: ops.pattern.matches.clone(),
13564            glob: GlobBuilder::new(&ops.pattern.glob)
13565                .case_insensitive(
13566                    ops.pattern
13567                        .options
13568                        .as_ref()
13569                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13570                )
13571                .build()?
13572                .compile_matcher(),
13573        })
13574    }
13575}
13576struct RenameActionPredicate {
13577    glob: GlobMatcher,
13578    kind: Option<FileOperationPatternKind>,
13579}
13580
13581impl RenameActionPredicate {
13582    // Returns true if language server should be notified
13583    fn eval(&self, path: &str, is_dir: bool) -> bool {
13584        self.kind.as_ref().is_none_or(|kind| {
13585            let expected_kind = if is_dir {
13586                FileOperationPatternKind::Folder
13587            } else {
13588                FileOperationPatternKind::File
13589            };
13590            kind == &expected_kind
13591        }) && self.glob.is_match(path)
13592    }
13593}
13594
13595#[derive(Default)]
13596struct LanguageServerWatchedPaths {
13597    worktree_paths: HashMap<WorktreeId, GlobSet>,
13598    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13599}
13600
13601#[derive(Default)]
13602struct LanguageServerWatchedPathsBuilder {
13603    worktree_paths: HashMap<WorktreeId, GlobSet>,
13604    abs_paths: HashMap<Arc<Path>, GlobSet>,
13605}
13606
13607impl LanguageServerWatchedPathsBuilder {
13608    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13609        self.worktree_paths.insert(worktree_id, glob_set);
13610    }
13611    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13612        self.abs_paths.insert(path, glob_set);
13613    }
13614    fn build(
13615        self,
13616        fs: Arc<dyn Fs>,
13617        language_server_id: LanguageServerId,
13618        cx: &mut Context<LspStore>,
13619    ) -> LanguageServerWatchedPaths {
13620        let lsp_store = cx.weak_entity();
13621
13622        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13623        let abs_paths = self
13624            .abs_paths
13625            .into_iter()
13626            .map(|(abs_path, globset)| {
13627                let task = cx.spawn({
13628                    let abs_path = abs_path.clone();
13629                    let fs = fs.clone();
13630
13631                    let lsp_store = lsp_store.clone();
13632                    async move |_, cx| {
13633                        maybe!(async move {
13634                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13635                            while let Some(update) = push_updates.0.next().await {
13636                                let action = lsp_store
13637                                    .update(cx, |this, _| {
13638                                        let Some(local) = this.as_local() else {
13639                                            return ControlFlow::Break(());
13640                                        };
13641                                        let Some(watcher) = local
13642                                            .language_server_watched_paths
13643                                            .get(&language_server_id)
13644                                        else {
13645                                            return ControlFlow::Break(());
13646                                        };
13647                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13648                                            "Watched abs path is not registered with a watcher",
13649                                        );
13650                                        let matching_entries = update
13651                                            .into_iter()
13652                                            .filter(|event| globs.is_match(&event.path))
13653                                            .collect::<Vec<_>>();
13654                                        this.lsp_notify_abs_paths_changed(
13655                                            language_server_id,
13656                                            matching_entries,
13657                                        );
13658                                        ControlFlow::Continue(())
13659                                    })
13660                                    .ok()?;
13661
13662                                if action.is_break() {
13663                                    break;
13664                                }
13665                            }
13666                            Some(())
13667                        })
13668                        .await;
13669                    }
13670                });
13671                (abs_path, (globset, task))
13672            })
13673            .collect();
13674        LanguageServerWatchedPaths {
13675            worktree_paths: self.worktree_paths,
13676            abs_paths,
13677        }
13678    }
13679}
13680
13681struct LspBufferSnapshot {
13682    version: i32,
13683    snapshot: TextBufferSnapshot,
13684}
13685
13686/// A prompt requested by LSP server.
13687#[derive(Clone, Debug)]
13688pub struct LanguageServerPromptRequest {
13689    pub level: PromptLevel,
13690    pub message: String,
13691    pub actions: Vec<MessageActionItem>,
13692    pub lsp_name: String,
13693    pub(crate) response_channel: Sender<MessageActionItem>,
13694}
13695
13696impl LanguageServerPromptRequest {
13697    pub async fn respond(self, index: usize) -> Option<()> {
13698        if let Some(response) = self.actions.into_iter().nth(index) {
13699            self.response_channel.send(response).await.ok()
13700        } else {
13701            None
13702        }
13703    }
13704}
13705impl PartialEq for LanguageServerPromptRequest {
13706    fn eq(&self, other: &Self) -> bool {
13707        self.message == other.message && self.actions == other.actions
13708    }
13709}
13710
13711#[derive(Clone, Debug, PartialEq)]
13712pub enum LanguageServerLogType {
13713    Log(MessageType),
13714    Trace { verbose_info: Option<String> },
13715    Rpc { received: bool },
13716}
13717
13718impl LanguageServerLogType {
13719    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13720        match self {
13721            Self::Log(log_type) => {
13722                use proto::log_message::LogLevel;
13723                let level = match *log_type {
13724                    MessageType::ERROR => LogLevel::Error,
13725                    MessageType::WARNING => LogLevel::Warning,
13726                    MessageType::INFO => LogLevel::Info,
13727                    MessageType::LOG => LogLevel::Log,
13728                    other => {
13729                        log::warn!("Unknown lsp log message type: {other:?}");
13730                        LogLevel::Log
13731                    }
13732                };
13733                proto::language_server_log::LogType::Log(proto::LogMessage {
13734                    level: level as i32,
13735                })
13736            }
13737            Self::Trace { verbose_info } => {
13738                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13739                    verbose_info: verbose_info.to_owned(),
13740                })
13741            }
13742            Self::Rpc { received } => {
13743                let kind = if *received {
13744                    proto::rpc_message::Kind::Received
13745                } else {
13746                    proto::rpc_message::Kind::Sent
13747                };
13748                let kind = kind as i32;
13749                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13750            }
13751        }
13752    }
13753
13754    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13755        use proto::log_message::LogLevel;
13756        use proto::rpc_message;
13757        match log_type {
13758            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13759                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13760                    LogLevel::Error => MessageType::ERROR,
13761                    LogLevel::Warning => MessageType::WARNING,
13762                    LogLevel::Info => MessageType::INFO,
13763                    LogLevel::Log => MessageType::LOG,
13764                },
13765            ),
13766            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13767                verbose_info: trace_message.verbose_info,
13768            },
13769            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13770                received: match rpc_message::Kind::from_i32(message.kind)
13771                    .unwrap_or(rpc_message::Kind::Received)
13772                {
13773                    rpc_message::Kind::Received => true,
13774                    rpc_message::Kind::Sent => false,
13775                },
13776            },
13777        }
13778    }
13779}
13780
13781pub struct WorkspaceRefreshTask {
13782    refresh_tx: mpsc::Sender<()>,
13783    progress_tx: mpsc::Sender<()>,
13784    #[allow(dead_code)]
13785    task: Task<()>,
13786}
13787
13788pub enum LanguageServerState {
13789    Starting {
13790        startup: Task<Option<Arc<LanguageServer>>>,
13791        /// List of language servers that will be added to the workspace once it's initialization completes.
13792        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13793    },
13794
13795    Running {
13796        adapter: Arc<CachedLspAdapter>,
13797        server: Arc<LanguageServer>,
13798        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13799        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13800    },
13801}
13802
13803impl LanguageServerState {
13804    fn add_workspace_folder(&self, uri: Uri) {
13805        match self {
13806            LanguageServerState::Starting {
13807                pending_workspace_folders,
13808                ..
13809            } => {
13810                pending_workspace_folders.lock().insert(uri);
13811            }
13812            LanguageServerState::Running { server, .. } => {
13813                server.add_workspace_folder(uri);
13814            }
13815        }
13816    }
13817    fn _remove_workspace_folder(&self, uri: Uri) {
13818        match self {
13819            LanguageServerState::Starting {
13820                pending_workspace_folders,
13821                ..
13822            } => {
13823                pending_workspace_folders.lock().remove(&uri);
13824            }
13825            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13826        }
13827    }
13828}
13829
13830impl std::fmt::Debug for LanguageServerState {
13831    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13832        match self {
13833            LanguageServerState::Starting { .. } => {
13834                f.debug_struct("LanguageServerState::Starting").finish()
13835            }
13836            LanguageServerState::Running { .. } => {
13837                f.debug_struct("LanguageServerState::Running").finish()
13838            }
13839        }
13840    }
13841}
13842
13843#[derive(Clone, Debug, Serialize)]
13844pub struct LanguageServerProgress {
13845    pub is_disk_based_diagnostics_progress: bool,
13846    pub is_cancellable: bool,
13847    pub title: Option<String>,
13848    pub message: Option<String>,
13849    pub percentage: Option<usize>,
13850    #[serde(skip_serializing)]
13851    pub last_update_at: Instant,
13852}
13853
13854#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13855pub struct DiagnosticSummary {
13856    pub error_count: usize,
13857    pub warning_count: usize,
13858}
13859
13860impl DiagnosticSummary {
13861    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13862        let mut this = Self {
13863            error_count: 0,
13864            warning_count: 0,
13865        };
13866
13867        for entry in diagnostics {
13868            if entry.diagnostic.is_primary {
13869                match entry.diagnostic.severity {
13870                    DiagnosticSeverity::ERROR => this.error_count += 1,
13871                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13872                    _ => {}
13873                }
13874            }
13875        }
13876
13877        this
13878    }
13879
13880    pub fn is_empty(&self) -> bool {
13881        self.error_count == 0 && self.warning_count == 0
13882    }
13883
13884    pub fn to_proto(
13885        self,
13886        language_server_id: LanguageServerId,
13887        path: &RelPath,
13888    ) -> proto::DiagnosticSummary {
13889        proto::DiagnosticSummary {
13890            path: path.to_proto(),
13891            language_server_id: language_server_id.0 as u64,
13892            error_count: self.error_count as u32,
13893            warning_count: self.warning_count as u32,
13894        }
13895    }
13896}
13897
13898#[derive(Clone, Debug)]
13899pub enum CompletionDocumentation {
13900    /// There is no documentation for this completion.
13901    Undocumented,
13902    /// A single line of documentation.
13903    SingleLine(SharedString),
13904    /// Multiple lines of plain text documentation.
13905    MultiLinePlainText(SharedString),
13906    /// Markdown documentation.
13907    MultiLineMarkdown(SharedString),
13908    /// Both single line and multiple lines of plain text documentation.
13909    SingleLineAndMultiLinePlainText {
13910        single_line: SharedString,
13911        plain_text: Option<SharedString>,
13912    },
13913}
13914
13915impl CompletionDocumentation {
13916    #[cfg(any(test, feature = "test-support"))]
13917    pub fn text(&self) -> SharedString {
13918        match self {
13919            CompletionDocumentation::Undocumented => "".into(),
13920            CompletionDocumentation::SingleLine(s) => s.clone(),
13921            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13922            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13923            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13924                single_line.clone()
13925            }
13926        }
13927    }
13928}
13929
13930impl From<lsp::Documentation> for CompletionDocumentation {
13931    fn from(docs: lsp::Documentation) -> Self {
13932        match docs {
13933            lsp::Documentation::String(text) => {
13934                if text.lines().count() <= 1 {
13935                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
13936                } else {
13937                    CompletionDocumentation::MultiLinePlainText(text.into())
13938                }
13939            }
13940
13941            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13942                lsp::MarkupKind::PlainText => {
13943                    if value.lines().count() <= 1 {
13944                        CompletionDocumentation::SingleLine(value.into())
13945                    } else {
13946                        CompletionDocumentation::MultiLinePlainText(value.into())
13947                    }
13948                }
13949
13950                lsp::MarkupKind::Markdown => {
13951                    CompletionDocumentation::MultiLineMarkdown(value.into())
13952                }
13953            },
13954        }
13955    }
13956}
13957
13958pub enum ResolvedHint {
13959    Resolved(InlayHint),
13960    Resolving(Shared<Task<()>>),
13961}
13962
13963fn glob_literal_prefix(glob: &Path) -> PathBuf {
13964    glob.components()
13965        .take_while(|component| match component {
13966            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13967            _ => true,
13968        })
13969        .collect()
13970}
13971
13972pub struct SshLspAdapter {
13973    name: LanguageServerName,
13974    binary: LanguageServerBinary,
13975    initialization_options: Option<String>,
13976    code_action_kinds: Option<Vec<CodeActionKind>>,
13977}
13978
13979impl SshLspAdapter {
13980    pub fn new(
13981        name: LanguageServerName,
13982        binary: LanguageServerBinary,
13983        initialization_options: Option<String>,
13984        code_action_kinds: Option<String>,
13985    ) -> Self {
13986        Self {
13987            name,
13988            binary,
13989            initialization_options,
13990            code_action_kinds: code_action_kinds
13991                .as_ref()
13992                .and_then(|c| serde_json::from_str(c).ok()),
13993        }
13994    }
13995}
13996
13997impl LspInstaller for SshLspAdapter {
13998    type BinaryVersion = ();
13999    async fn check_if_user_installed(
14000        &self,
14001        _: &dyn LspAdapterDelegate,
14002        _: Option<Toolchain>,
14003        _: &AsyncApp,
14004    ) -> Option<LanguageServerBinary> {
14005        Some(self.binary.clone())
14006    }
14007
14008    async fn cached_server_binary(
14009        &self,
14010        _: PathBuf,
14011        _: &dyn LspAdapterDelegate,
14012    ) -> Option<LanguageServerBinary> {
14013        None
14014    }
14015
14016    async fn fetch_latest_server_version(
14017        &self,
14018        _: &dyn LspAdapterDelegate,
14019        _: bool,
14020        _: &mut AsyncApp,
14021    ) -> Result<()> {
14022        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14023    }
14024
14025    async fn fetch_server_binary(
14026        &self,
14027        _: (),
14028        _: PathBuf,
14029        _: &dyn LspAdapterDelegate,
14030    ) -> Result<LanguageServerBinary> {
14031        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14032    }
14033}
14034
14035#[async_trait(?Send)]
14036impl LspAdapter for SshLspAdapter {
14037    fn name(&self) -> LanguageServerName {
14038        self.name.clone()
14039    }
14040
14041    async fn initialization_options(
14042        self: Arc<Self>,
14043        _: &Arc<dyn LspAdapterDelegate>,
14044    ) -> Result<Option<serde_json::Value>> {
14045        let Some(options) = &self.initialization_options else {
14046            return Ok(None);
14047        };
14048        let result = serde_json::from_str(options)?;
14049        Ok(result)
14050    }
14051
14052    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14053        self.code_action_kinds.clone()
14054    }
14055}
14056
14057pub fn language_server_settings<'a>(
14058    delegate: &'a dyn LspAdapterDelegate,
14059    language: &LanguageServerName,
14060    cx: &'a App,
14061) -> Option<&'a LspSettings> {
14062    language_server_settings_for(
14063        SettingsLocation {
14064            worktree_id: delegate.worktree_id(),
14065            path: RelPath::empty(),
14066        },
14067        language,
14068        cx,
14069    )
14070}
14071
14072pub fn language_server_settings_for<'a>(
14073    location: SettingsLocation<'a>,
14074    language: &LanguageServerName,
14075    cx: &'a App,
14076) -> Option<&'a LspSettings> {
14077    ProjectSettings::get(Some(location), cx).lsp.get(language)
14078}
14079
14080pub struct LocalLspAdapterDelegate {
14081    lsp_store: WeakEntity<LspStore>,
14082    worktree: worktree::Snapshot,
14083    fs: Arc<dyn Fs>,
14084    http_client: Arc<dyn HttpClient>,
14085    language_registry: Arc<LanguageRegistry>,
14086    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14087}
14088
14089impl LocalLspAdapterDelegate {
14090    pub fn new(
14091        language_registry: Arc<LanguageRegistry>,
14092        environment: &Entity<ProjectEnvironment>,
14093        lsp_store: WeakEntity<LspStore>,
14094        worktree: &Entity<Worktree>,
14095        http_client: Arc<dyn HttpClient>,
14096        fs: Arc<dyn Fs>,
14097        cx: &mut App,
14098    ) -> Arc<Self> {
14099        let load_shell_env_task =
14100            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14101
14102        Arc::new(Self {
14103            lsp_store,
14104            worktree: worktree.read(cx).snapshot(),
14105            fs,
14106            http_client,
14107            language_registry,
14108            load_shell_env_task,
14109        })
14110    }
14111
14112    pub fn from_local_lsp(
14113        local: &LocalLspStore,
14114        worktree: &Entity<Worktree>,
14115        cx: &mut App,
14116    ) -> Arc<Self> {
14117        Self::new(
14118            local.languages.clone(),
14119            &local.environment,
14120            local.weak.clone(),
14121            worktree,
14122            local.http_client.clone(),
14123            local.fs.clone(),
14124            cx,
14125        )
14126    }
14127}
14128
14129#[async_trait]
14130impl LspAdapterDelegate for LocalLspAdapterDelegate {
14131    fn show_notification(&self, message: &str, cx: &mut App) {
14132        self.lsp_store
14133            .update(cx, |_, cx| {
14134                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14135            })
14136            .ok();
14137    }
14138
14139    fn http_client(&self) -> Arc<dyn HttpClient> {
14140        self.http_client.clone()
14141    }
14142
14143    fn worktree_id(&self) -> WorktreeId {
14144        self.worktree.id()
14145    }
14146
14147    fn worktree_root_path(&self) -> &Path {
14148        self.worktree.abs_path().as_ref()
14149    }
14150
14151    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
14152        self.worktree.resolve_executable_path(path)
14153    }
14154
14155    async fn shell_env(&self) -> HashMap<String, String> {
14156        let task = self.load_shell_env_task.clone();
14157        task.await.unwrap_or_default()
14158    }
14159
14160    async fn npm_package_installed_version(
14161        &self,
14162        package_name: &str,
14163    ) -> Result<Option<(PathBuf, Version)>> {
14164        let local_package_directory = self.worktree_root_path();
14165        let node_modules_directory = local_package_directory.join("node_modules");
14166
14167        if let Some(version) =
14168            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14169        {
14170            return Ok(Some((node_modules_directory, version)));
14171        }
14172        let Some(npm) = self.which("npm".as_ref()).await else {
14173            log::warn!(
14174                "Failed to find npm executable for {:?}",
14175                local_package_directory
14176            );
14177            return Ok(None);
14178        };
14179
14180        let env = self.shell_env().await;
14181        let output = util::command::new_smol_command(&npm)
14182            .args(["root", "-g"])
14183            .envs(env)
14184            .current_dir(local_package_directory)
14185            .output()
14186            .await?;
14187        let global_node_modules =
14188            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14189
14190        if let Some(version) =
14191            read_package_installed_version(global_node_modules.clone(), package_name).await?
14192        {
14193            return Ok(Some((global_node_modules, version)));
14194        }
14195        return Ok(None);
14196    }
14197
14198    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14199        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14200        if self.fs.is_file(&worktree_abs_path).await {
14201            worktree_abs_path.pop();
14202        }
14203
14204        let env = self.shell_env().await;
14205
14206        let shell_path = env.get("PATH").cloned();
14207
14208        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14209    }
14210
14211    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14212        let mut working_dir = self.worktree_root_path().to_path_buf();
14213        if self.fs.is_file(&working_dir).await {
14214            working_dir.pop();
14215        }
14216        let output = util::command::new_smol_command(&command.path)
14217            .args(command.arguments)
14218            .envs(command.env.clone().unwrap_or_default())
14219            .current_dir(working_dir)
14220            .output()
14221            .await?;
14222
14223        anyhow::ensure!(
14224            output.status.success(),
14225            "{}, stdout: {:?}, stderr: {:?}",
14226            output.status,
14227            String::from_utf8_lossy(&output.stdout),
14228            String::from_utf8_lossy(&output.stderr)
14229        );
14230        Ok(())
14231    }
14232
14233    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14234        self.language_registry
14235            .update_lsp_binary_status(server_name, status);
14236    }
14237
14238    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14239        self.language_registry
14240            .all_lsp_adapters()
14241            .into_iter()
14242            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14243            .collect()
14244    }
14245
14246    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14247        let dir = self.language_registry.language_server_download_dir(name)?;
14248
14249        if !dir.exists() {
14250            smol::fs::create_dir_all(&dir)
14251                .await
14252                .context("failed to create container directory")
14253                .log_err()?;
14254        }
14255
14256        Some(dir)
14257    }
14258
14259    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14260        let entry = self
14261            .worktree
14262            .entry_for_path(path)
14263            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14264        let abs_path = self.worktree.absolutize(&entry.path);
14265        self.fs.load(&abs_path).await
14266    }
14267}
14268
14269async fn populate_labels_for_symbols(
14270    symbols: Vec<CoreSymbol>,
14271    language_registry: &Arc<LanguageRegistry>,
14272    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14273    output: &mut Vec<Symbol>,
14274) {
14275    #[allow(clippy::mutable_key_type)]
14276    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14277
14278    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14279    for symbol in symbols {
14280        let Some(file_name) = symbol.path.file_name() else {
14281            continue;
14282        };
14283        let language = language_registry
14284            .load_language_for_file_path(Path::new(file_name))
14285            .await
14286            .ok()
14287            .or_else(|| {
14288                unknown_paths.insert(file_name.into());
14289                None
14290            });
14291        symbols_by_language
14292            .entry(language)
14293            .or_default()
14294            .push(symbol);
14295    }
14296
14297    for unknown_path in unknown_paths {
14298        log::info!("no language found for symbol in file {unknown_path:?}");
14299    }
14300
14301    let mut label_params = Vec::new();
14302    for (language, mut symbols) in symbols_by_language {
14303        label_params.clear();
14304        label_params.extend(
14305            symbols
14306                .iter_mut()
14307                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14308        );
14309
14310        let mut labels = Vec::new();
14311        if let Some(language) = language {
14312            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14313                language_registry
14314                    .lsp_adapters(&language.name())
14315                    .first()
14316                    .cloned()
14317            });
14318            if let Some(lsp_adapter) = lsp_adapter {
14319                labels = lsp_adapter
14320                    .labels_for_symbols(&label_params, &language)
14321                    .await
14322                    .log_err()
14323                    .unwrap_or_default();
14324            }
14325        }
14326
14327        for ((symbol, (name, _)), label) in symbols
14328            .into_iter()
14329            .zip(label_params.drain(..))
14330            .zip(labels.into_iter().chain(iter::repeat(None)))
14331        {
14332            output.push(Symbol {
14333                language_server_name: symbol.language_server_name,
14334                source_worktree_id: symbol.source_worktree_id,
14335                source_language_server_id: symbol.source_language_server_id,
14336                path: symbol.path,
14337                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14338                name,
14339                kind: symbol.kind,
14340                range: symbol.range,
14341            });
14342        }
14343    }
14344}
14345
14346fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14347    match server.capabilities().text_document_sync.as_ref()? {
14348        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14349            // Server wants didSave but didn't specify includeText.
14350            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14351            // Server doesn't want didSave at all.
14352            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14353            // Server provided SaveOptions.
14354            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14355                Some(save_options.include_text.unwrap_or(false))
14356            }
14357        },
14358        // We do not have any save info. Kind affects didChange only.
14359        lsp::TextDocumentSyncCapability::Kind(_) => None,
14360    }
14361}
14362
14363/// Completion items are displayed in a `UniformList`.
14364/// Usually, those items are single-line strings, but in LSP responses,
14365/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14366/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14367/// 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,
14368/// breaking the completions menu presentation.
14369///
14370/// 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.
14371fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14372    let mut new_text = String::with_capacity(label.text.len());
14373    let mut offset_map = vec![0; label.text.len() + 1];
14374    let mut last_char_was_space = false;
14375    let mut new_idx = 0;
14376    let chars = label.text.char_indices().fuse();
14377    let mut newlines_removed = false;
14378
14379    for (idx, c) in chars {
14380        offset_map[idx] = new_idx;
14381
14382        match c {
14383            '\n' if last_char_was_space => {
14384                newlines_removed = true;
14385            }
14386            '\t' | ' ' if last_char_was_space => {}
14387            '\n' if !last_char_was_space => {
14388                new_text.push(' ');
14389                new_idx += 1;
14390                last_char_was_space = true;
14391                newlines_removed = true;
14392            }
14393            ' ' | '\t' => {
14394                new_text.push(' ');
14395                new_idx += 1;
14396                last_char_was_space = true;
14397            }
14398            _ => {
14399                new_text.push(c);
14400                new_idx += c.len_utf8();
14401                last_char_was_space = false;
14402            }
14403        }
14404    }
14405    offset_map[label.text.len()] = new_idx;
14406
14407    // Only modify the label if newlines were removed.
14408    if !newlines_removed {
14409        return;
14410    }
14411
14412    let last_index = new_idx;
14413    let mut run_ranges_errors = Vec::new();
14414    label.runs.retain_mut(|(range, _)| {
14415        match offset_map.get(range.start) {
14416            Some(&start) => range.start = start,
14417            None => {
14418                run_ranges_errors.push(range.clone());
14419                return false;
14420            }
14421        }
14422
14423        match offset_map.get(range.end) {
14424            Some(&end) => range.end = end,
14425            None => {
14426                run_ranges_errors.push(range.clone());
14427                range.end = last_index;
14428            }
14429        }
14430        true
14431    });
14432    if !run_ranges_errors.is_empty() {
14433        log::error!(
14434            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14435            label.text
14436        );
14437    }
14438
14439    let mut wrong_filter_range = None;
14440    if label.filter_range == (0..label.text.len()) {
14441        label.filter_range = 0..new_text.len();
14442    } else {
14443        let mut original_filter_range = Some(label.filter_range.clone());
14444        match offset_map.get(label.filter_range.start) {
14445            Some(&start) => label.filter_range.start = start,
14446            None => {
14447                wrong_filter_range = original_filter_range.take();
14448                label.filter_range.start = last_index;
14449            }
14450        }
14451
14452        match offset_map.get(label.filter_range.end) {
14453            Some(&end) => label.filter_range.end = end,
14454            None => {
14455                wrong_filter_range = original_filter_range.take();
14456                label.filter_range.end = last_index;
14457            }
14458        }
14459    }
14460    if let Some(wrong_filter_range) = wrong_filter_range {
14461        log::error!(
14462            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14463            label.text
14464        );
14465    }
14466
14467    label.text = new_text;
14468}
14469
14470#[cfg(test)]
14471mod tests {
14472    use language::HighlightId;
14473
14474    use super::*;
14475
14476    #[test]
14477    fn test_glob_literal_prefix() {
14478        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14479        assert_eq!(
14480            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14481            Path::new("node_modules")
14482        );
14483        assert_eq!(
14484            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14485            Path::new("foo")
14486        );
14487        assert_eq!(
14488            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14489            Path::new("foo/bar/baz.js")
14490        );
14491
14492        #[cfg(target_os = "windows")]
14493        {
14494            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14495            assert_eq!(
14496                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14497                Path::new("node_modules")
14498            );
14499            assert_eq!(
14500                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14501                Path::new("foo")
14502            );
14503            assert_eq!(
14504                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14505                Path::new("foo/bar/baz.js")
14506            );
14507        }
14508    }
14509
14510    #[test]
14511    fn test_multi_len_chars_normalization() {
14512        let mut label = CodeLabel::new(
14513            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14514            0..6,
14515            vec![(0..6, HighlightId(1))],
14516        );
14517        ensure_uniform_list_compatible_label(&mut label);
14518        assert_eq!(
14519            label,
14520            CodeLabel::new(
14521                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14522                0..6,
14523                vec![(0..6, HighlightId(1))],
14524            )
14525        );
14526    }
14527
14528    #[test]
14529    fn test_trailing_newline_in_completion_documentation() {
14530        let doc = lsp::Documentation::String(
14531            "Inappropriate argument value (of correct type).\n".to_string(),
14532        );
14533        let completion_doc: CompletionDocumentation = doc.into();
14534        assert!(
14535            matches!(completion_doc, CompletionDocumentation::SingleLine(s) if s == "Inappropriate argument value (of correct type).")
14536        );
14537
14538        let doc = lsp::Documentation::String("  some value  \n".to_string());
14539        let completion_doc: CompletionDocumentation = doc.into();
14540        assert!(matches!(
14541            completion_doc,
14542            CompletionDocumentation::SingleLine(s) if s == "some value"
14543        ));
14544    }
14545}