lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13pub mod json_language_server_ext;
   14pub mod log_store;
   15pub mod lsp_ext_command;
   16pub mod rust_analyzer_ext;
   17pub mod vue_language_server_ext;
   18
   19mod inlay_hint_cache;
   20
   21use self::inlay_hint_cache::BufferInlayHints;
   22use crate::{
   23    CodeAction, ColorPresentation, Completion, CompletionDisplayOptions, CompletionResponse,
   24    CompletionSource, CoreCompletion, DocumentColor, Hover, InlayHint, InlayId, LocationLink,
   25    LspAction, LspPullDiagnostics, ManifestProvidersStore, Project, ProjectItem, ProjectPath,
   26    ProjectTransaction, PulledDiagnostics, ResolveState, Symbol,
   27    buffer_store::{BufferStore, BufferStoreEvent},
   28    environment::ProjectEnvironment,
   29    lsp_command::{self, *},
   30    lsp_store::{
   31        self,
   32        log_store::{GlobalLogStore, LanguageServerKind},
   33    },
   34    manifest_tree::{
   35        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   36        ManifestTree,
   37    },
   38    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   39    project_settings::{LspSettings, ProjectSettings},
   40    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   41    trusted_worktrees::{PathTrust, TrustedWorktrees, TrustedWorktreesEvent},
   42    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   43    yarn::YarnPathStore,
   44};
   45use anyhow::{Context as _, Result, anyhow};
   46use async_trait::async_trait;
   47use client::{TypedEnvelope, proto};
   48use clock::Global;
   49use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   50use futures::{
   51    AsyncWriteExt, Future, FutureExt, StreamExt,
   52    future::{Either, Shared, join_all, pending, select},
   53    select, select_biased,
   54    stream::FuturesUnordered,
   55};
   56use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   57use gpui::{
   58    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString,
   59    Subscription, Task, WeakEntity,
   60};
   61use http_client::HttpClient;
   62use itertools::Itertools as _;
   63use language::{
   64    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, Capability, CodeLabel,
   65    Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language,
   66    LanguageName, LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller,
   67    ManifestDelegate, ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16,
   68    Toolchain, Transaction, Unclipped,
   69    language_settings::{FormatOnSave, Formatter, LanguageSettings, language_settings},
   70    point_to_lsp,
   71    proto::{
   72        deserialize_anchor, deserialize_anchor_range, deserialize_lsp_edit, deserialize_version,
   73        serialize_anchor, serialize_anchor_range, serialize_lsp_edit, serialize_version,
   74    },
   75    range_from_lsp, range_to_lsp,
   76    row_chunk::RowChunk,
   77};
   78use lsp::{
   79    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   80    DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   81    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   82    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LSP_REQUEST_TIMEOUT,
   83    LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId,
   84    LanguageServerName, LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType,
   85    OneOf, RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri,
   86    WillRenameFiles, WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   87};
   88use node_runtime::read_package_installed_version;
   89use parking_lot::Mutex;
   90use postage::{mpsc, sink::Sink, stream::Stream, watch};
   91use rand::prelude::*;
   92use rpc::{
   93    AnyProtoClient, ErrorCode, ErrorExt as _,
   94    proto::{LspRequestId, LspRequestMessage as _},
   95};
   96use semver::Version;
   97use serde::Serialize;
   98use serde_json::Value;
   99use settings::{Settings, SettingsLocation, SettingsStore};
  100use sha2::{Digest, Sha256};
  101use snippet::Snippet;
  102use std::{
  103    any::TypeId,
  104    borrow::Cow,
  105    cell::RefCell,
  106    cmp::{Ordering, Reverse},
  107    collections::hash_map,
  108    convert::TryInto,
  109    ffi::OsStr,
  110    future::ready,
  111    iter, mem,
  112    ops::{ControlFlow, Range},
  113    path::{self, Path, PathBuf},
  114    pin::pin,
  115    rc::Rc,
  116    sync::{
  117        Arc,
  118        atomic::{self, AtomicUsize},
  119    },
  120    time::{Duration, Instant},
  121    vec,
  122};
  123use sum_tree::Dimensions;
  124use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  125
  126use util::{
  127    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  128    paths::{PathStyle, SanitizedPath},
  129    post_inc,
  130    redact::redact_command,
  131    rel_path::RelPath,
  132};
  133
  134pub use fs::*;
  135pub use language::Location;
  136pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  137#[cfg(any(test, feature = "test-support"))]
  138pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  139pub use worktree::{
  140    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  141    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  142};
  143
  144const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  145pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  146const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  147const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  148static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  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, watch::Receiver<bool>)>,
  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 wait_until_worktree_trust =
  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 (mut tx, rx) = watch::channel::<bool>();
  401                            let lsp_store = self.weak.clone();
  402                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  403                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  404                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  405                                        tx.blocking_send(true).ok();
  406                                        lsp_store
  407                                            .update(cx, |lsp_store, _| {
  408                                                if let Some(local_lsp_store) =
  409                                                    lsp_store.as_local_mut()
  410                                                {
  411                                                    local_lsp_store
  412                                                        .restricted_worktrees_tasks
  413                                                        .remove(&worktree_id);
  414                                                }
  415                                            })
  416                                            .ok();
  417                                    }
  418                                }
  419                            });
  420                            v.insert((subscription, rx.clone()));
  421                            Some(rx)
  422                        }
  423                    }
  424                }
  425            });
  426        let update_binary_status = wait_until_worktree_trust.is_none();
  427
  428        let binary = self.get_language_server_binary(
  429            worktree_abs_path.clone(),
  430            adapter.clone(),
  431            settings,
  432            toolchain.clone(),
  433            delegate.clone(),
  434            true,
  435            wait_until_worktree_trust,
  436            cx,
  437        );
  438        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  439
  440        let pending_server = cx.spawn({
  441            let adapter = adapter.clone();
  442            let server_name = adapter.name.clone();
  443            let stderr_capture = stderr_capture.clone();
  444            #[cfg(any(test, feature = "test-support"))]
  445            let lsp_store = self.weak.clone();
  446            let pending_workspace_folders = pending_workspace_folders.clone();
  447            async move |cx| {
  448                let binary = binary.await?;
  449                #[cfg(any(test, feature = "test-support"))]
  450                if let Some(server) = lsp_store
  451                    .update(&mut cx.clone(), |this, cx| {
  452                        this.languages.create_fake_language_server(
  453                            server_id,
  454                            &server_name,
  455                            binary.clone(),
  456                            &mut cx.to_async(),
  457                        )
  458                    })
  459                    .ok()
  460                    .flatten()
  461                {
  462                    return Ok(server);
  463                }
  464
  465                let code_action_kinds = adapter.code_action_kinds();
  466                lsp::LanguageServer::new(
  467                    stderr_capture,
  468                    server_id,
  469                    server_name,
  470                    binary,
  471                    &worktree_abs_path,
  472                    code_action_kinds,
  473                    Some(pending_workspace_folders),
  474                    cx,
  475                )
  476            }
  477        });
  478
  479        let startup = {
  480            let server_name = adapter.name.0.clone();
  481            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  482            let key = key.clone();
  483            let adapter = adapter.clone();
  484            let lsp_store = self.weak.clone();
  485            let pending_workspace_folders = pending_workspace_folders.clone();
  486
  487            let pull_diagnostics = ProjectSettings::get_global(cx)
  488                .diagnostics
  489                .lsp_pull_diagnostics
  490                .enabled;
  491            cx.spawn(async move |cx| {
  492                let result = async {
  493                    let language_server = pending_server.await?;
  494
  495                    let workspace_config = Self::workspace_configuration_for_adapter(
  496                        adapter.adapter.clone(),
  497                        &delegate,
  498                        toolchain,
  499                        None,
  500                        cx,
  501                    )
  502                    .await?;
  503
  504                    let mut initialization_options = Self::initialization_options_for_adapter(
  505                        adapter.adapter.clone(),
  506                        &delegate,
  507                    )
  508                    .await?;
  509
  510                    match (&mut initialization_options, override_options) {
  511                        (Some(initialization_options), Some(override_options)) => {
  512                            merge_json_value_into(override_options, initialization_options);
  513                        }
  514                        (None, override_options) => initialization_options = override_options,
  515                        _ => {}
  516                    }
  517
  518                    let initialization_params = cx.update(|cx| {
  519                        let mut params =
  520                            language_server.default_initialize_params(pull_diagnostics, cx);
  521                        params.initialization_options = initialization_options;
  522                        adapter.adapter.prepare_initialize_params(params, cx)
  523                    })?;
  524
  525                    Self::setup_lsp_messages(
  526                        lsp_store.clone(),
  527                        &language_server,
  528                        delegate.clone(),
  529                        adapter.clone(),
  530                    );
  531
  532                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  533                        settings: workspace_config,
  534                    };
  535                    let language_server = cx
  536                        .update(|cx| {
  537                            language_server.initialize(
  538                                initialization_params,
  539                                Arc::new(did_change_configuration_params.clone()),
  540                                cx,
  541                            )
  542                        })
  543                        .await
  544                        .inspect_err(|_| {
  545                            if let Some(lsp_store) = lsp_store.upgrade() {
  546                                lsp_store.update(cx, |lsp_store, cx| {
  547                                    lsp_store.cleanup_lsp_data(server_id);
  548                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  549                                });
  550                            }
  551                        })?;
  552
  553                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  554                        did_change_configuration_params,
  555                    )?;
  556
  557                    anyhow::Ok(language_server)
  558                }
  559                .await;
  560
  561                match result {
  562                    Ok(server) => {
  563                        lsp_store
  564                            .update(cx, |lsp_store, cx| {
  565                                lsp_store.insert_newly_running_language_server(
  566                                    adapter,
  567                                    server.clone(),
  568                                    server_id,
  569                                    key,
  570                                    pending_workspace_folders,
  571                                    cx,
  572                                );
  573                            })
  574                            .ok();
  575                        stderr_capture.lock().take();
  576                        Some(server)
  577                    }
  578
  579                    Err(err) => {
  580                        let log = stderr_capture.lock().take().unwrap_or_default();
  581                        delegate.update_status(
  582                            adapter.name(),
  583                            BinaryStatus::Failed {
  584                                error: if log.is_empty() {
  585                                    format!("{err:#}")
  586                                } else {
  587                                    format!("{err:#}\n-- stderr --\n{log}")
  588                                },
  589                            },
  590                        );
  591                        log::error!(
  592                            "Failed to start language server {server_name:?}: {}",
  593                            redact_command(&format!("{err:?}"))
  594                        );
  595                        if !log.is_empty() {
  596                            log::error!("server stderr: {}", redact_command(&log));
  597                        }
  598                        None
  599                    }
  600                }
  601            })
  602        };
  603        let state = LanguageServerState::Starting {
  604            startup,
  605            pending_workspace_folders,
  606        };
  607
  608        if update_binary_status {
  609            self.languages
  610                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  611        }
  612
  613        self.language_servers.insert(server_id, state);
  614        self.language_server_ids
  615            .entry(key)
  616            .or_insert(UnifiedLanguageServer {
  617                id: server_id,
  618                project_roots: Default::default(),
  619            });
  620        server_id
  621    }
  622
  623    fn get_language_server_binary(
  624        &self,
  625        worktree_abs_path: Arc<Path>,
  626        adapter: Arc<CachedLspAdapter>,
  627        settings: Arc<LspSettings>,
  628        toolchain: Option<Toolchain>,
  629        delegate: Arc<dyn LspAdapterDelegate>,
  630        allow_binary_download: bool,
  631        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  632        cx: &mut App,
  633    ) -> Task<Result<LanguageServerBinary>> {
  634        if let Some(settings) = &settings.binary
  635            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  636        {
  637            let settings = settings.clone();
  638            let languages = self.languages.clone();
  639            return cx.background_spawn(async move {
  640                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  641                    let already_trusted =  *wait_until_worktree_trust.borrow();
  642                    if !already_trusted {
  643                        log::info!(
  644                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  645                            adapter.name(),
  646                        );
  647                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  648                            if worktree_trusted {
  649                                break;
  650                            }
  651                        }
  652                        log::info!(
  653                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  654                            adapter.name(),
  655                        );
  656                    }
  657                    languages
  658                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  659                }
  660                let mut env = delegate.shell_env().await;
  661                env.extend(settings.env.unwrap_or_default());
  662
  663                Ok(LanguageServerBinary {
  664                    path: delegate.resolve_executable_path(path),
  665                    env: Some(env),
  666                    arguments: settings
  667                        .arguments
  668                        .unwrap_or_default()
  669                        .iter()
  670                        .map(Into::into)
  671                        .collect(),
  672                })
  673            });
  674        }
  675        let lsp_binary_options = LanguageServerBinaryOptions {
  676            allow_path_lookup: !settings
  677                .binary
  678                .as_ref()
  679                .and_then(|b| b.ignore_system_version)
  680                .unwrap_or_default(),
  681            allow_binary_download,
  682            pre_release: settings
  683                .fetch
  684                .as_ref()
  685                .and_then(|f| f.pre_release)
  686                .unwrap_or(false),
  687        };
  688
  689        cx.spawn(async move |cx| {
  690            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  691                let already_trusted =  *wait_until_worktree_trust.borrow();
  692                if !already_trusted {
  693                    log::info!(
  694                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  695                        adapter.name(),
  696                    );
  697                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  698                        if worktree_trusted {
  699                            break;
  700                        }
  701                    }
  702                    log::info!(
  703                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  704                            adapter.name(),
  705                    );
  706                }
  707            }
  708
  709            let (existing_binary, maybe_download_binary) = adapter
  710                .clone()
  711                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  712                .await
  713                .await;
  714
  715            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  716
  717            let mut binary = match (existing_binary, maybe_download_binary) {
  718                (binary, None) => binary?,
  719                (Err(_), Some(downloader)) => downloader.await?,
  720                (Ok(existing_binary), Some(downloader)) => {
  721                    let mut download_timeout = cx
  722                        .background_executor()
  723                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  724                        .fuse();
  725                    let mut downloader = downloader.fuse();
  726                    futures::select! {
  727                        _ = download_timeout => {
  728                            // Return existing binary and kick the existing work to the background.
  729                            cx.spawn(async move |_| downloader.await).detach();
  730                            Ok(existing_binary)
  731                        },
  732                        downloaded_or_existing_binary = downloader => {
  733                            // If download fails, this results in the existing binary.
  734                            downloaded_or_existing_binary
  735                        }
  736                    }?
  737                }
  738            };
  739            let mut shell_env = delegate.shell_env().await;
  740
  741            shell_env.extend(binary.env.unwrap_or_default());
  742
  743            if let Some(settings) = settings.binary.as_ref() {
  744                if let Some(arguments) = &settings.arguments {
  745                    binary.arguments = arguments.iter().map(Into::into).collect();
  746                }
  747                if let Some(env) = &settings.env {
  748                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  749                }
  750            }
  751
  752            binary.env = Some(shell_env);
  753            Ok(binary)
  754        })
  755    }
  756
  757    fn setup_lsp_messages(
  758        lsp_store: WeakEntity<LspStore>,
  759        language_server: &LanguageServer,
  760        delegate: Arc<dyn LspAdapterDelegate>,
  761        adapter: Arc<CachedLspAdapter>,
  762    ) {
  763        let name = language_server.name();
  764        let server_id = language_server.server_id();
  765        language_server
  766            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  767                let adapter = adapter.clone();
  768                let this = lsp_store.clone();
  769                move |mut params, cx| {
  770                    let adapter = adapter.clone();
  771                    if let Some(this) = this.upgrade() {
  772                        this.update(cx, |this, cx| {
  773                            {
  774                                let buffer = params
  775                                    .uri
  776                                    .to_file_path()
  777                                    .map(|file_path| this.get_buffer(&file_path, cx))
  778                                    .ok()
  779                                    .flatten();
  780                                adapter.process_diagnostics(&mut params, server_id, buffer);
  781                            }
  782
  783                            this.merge_lsp_diagnostics(
  784                                DiagnosticSourceKind::Pushed,
  785                                vec![DocumentDiagnosticsUpdate {
  786                                    server_id,
  787                                    diagnostics: params,
  788                                    result_id: None,
  789                                    disk_based_sources: Cow::Borrowed(
  790                                        &adapter.disk_based_diagnostic_sources,
  791                                    ),
  792                                    registration_id: None,
  793                                }],
  794                                |_, diagnostic, cx| match diagnostic.source_kind {
  795                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  796                                        adapter.retain_old_diagnostic(diagnostic, cx)
  797                                    }
  798                                    DiagnosticSourceKind::Pulled => true,
  799                                },
  800                                cx,
  801                            )
  802                            .log_err();
  803                        });
  804                    }
  805                }
  806            })
  807            .detach();
  808        language_server
  809            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  810                let adapter = adapter.adapter.clone();
  811                let delegate = delegate.clone();
  812                let this = lsp_store.clone();
  813                move |params, cx| {
  814                    let adapter = adapter.clone();
  815                    let delegate = delegate.clone();
  816                    let this = this.clone();
  817                    let mut cx = cx.clone();
  818                    async move {
  819                        let toolchain_for_id = this
  820                            .update(&mut cx, |this, _| {
  821                                this.as_local()?.language_server_ids.iter().find_map(
  822                                    |(seed, value)| {
  823                                        (value.id == server_id).then(|| seed.toolchain.clone())
  824                                    },
  825                                )
  826                            })?
  827                            .context("Expected the LSP store to be in a local mode")?;
  828
  829                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  830                        for item in &params.items {
  831                            let scope_uri = item.scope_uri.clone();
  832                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  833                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  834                            else {
  835                                // We've already queried workspace configuration of this URI.
  836                                continue;
  837                            };
  838                            let workspace_config = Self::workspace_configuration_for_adapter(
  839                                adapter.clone(),
  840                                &delegate,
  841                                toolchain_for_id.clone(),
  842                                scope_uri,
  843                                &mut cx,
  844                            )
  845                            .await?;
  846                            new_scope_uri.insert(workspace_config);
  847                        }
  848
  849                        Ok(params
  850                            .items
  851                            .into_iter()
  852                            .filter_map(|item| {
  853                                let workspace_config =
  854                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  855                                if let Some(section) = &item.section {
  856                                    Some(
  857                                        workspace_config
  858                                            .get(section)
  859                                            .cloned()
  860                                            .unwrap_or(serde_json::Value::Null),
  861                                    )
  862                                } else {
  863                                    Some(workspace_config.clone())
  864                                }
  865                            })
  866                            .collect())
  867                    }
  868                }
  869            })
  870            .detach();
  871
  872        language_server
  873            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  874                let this = lsp_store.clone();
  875                move |_, cx| {
  876                    let this = this.clone();
  877                    let cx = cx.clone();
  878                    async move {
  879                        let Some(server) =
  880                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  881                        else {
  882                            return Ok(None);
  883                        };
  884                        let root = server.workspace_folders();
  885                        Ok(Some(
  886                            root.into_iter()
  887                                .map(|uri| WorkspaceFolder {
  888                                    uri,
  889                                    name: Default::default(),
  890                                })
  891                                .collect(),
  892                        ))
  893                    }
  894                }
  895            })
  896            .detach();
  897        // Even though we don't have handling for these requests, respond to them to
  898        // avoid stalling any language server like `gopls` which waits for a response
  899        // to these requests when initializing.
  900        language_server
  901            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  902                let this = lsp_store.clone();
  903                move |params, cx| {
  904                    let this = this.clone();
  905                    let mut cx = cx.clone();
  906                    async move {
  907                        this.update(&mut cx, |this, _| {
  908                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  909                            {
  910                                status
  911                                    .progress_tokens
  912                                    .insert(ProgressToken::from_lsp(params.token));
  913                            }
  914                        })?;
  915
  916                        Ok(())
  917                    }
  918                }
  919            })
  920            .detach();
  921
  922        language_server
  923            .on_request::<lsp::request::RegisterCapability, _, _>({
  924                let lsp_store = lsp_store.clone();
  925                move |params, cx| {
  926                    let lsp_store = lsp_store.clone();
  927                    let mut cx = cx.clone();
  928                    async move {
  929                        lsp_store
  930                            .update(&mut cx, |lsp_store, cx| {
  931                                if lsp_store.as_local().is_some() {
  932                                    match lsp_store
  933                                        .register_server_capabilities(server_id, params, cx)
  934                                    {
  935                                        Ok(()) => {}
  936                                        Err(e) => {
  937                                            log::error!(
  938                                                "Failed to register server capabilities: {e:#}"
  939                                            );
  940                                        }
  941                                    };
  942                                }
  943                            })
  944                            .ok();
  945                        Ok(())
  946                    }
  947                }
  948            })
  949            .detach();
  950
  951        language_server
  952            .on_request::<lsp::request::UnregisterCapability, _, _>({
  953                let lsp_store = lsp_store.clone();
  954                move |params, cx| {
  955                    let lsp_store = lsp_store.clone();
  956                    let mut cx = cx.clone();
  957                    async move {
  958                        lsp_store
  959                            .update(&mut cx, |lsp_store, cx| {
  960                                if lsp_store.as_local().is_some() {
  961                                    match lsp_store
  962                                        .unregister_server_capabilities(server_id, params, cx)
  963                                    {
  964                                        Ok(()) => {}
  965                                        Err(e) => {
  966                                            log::error!(
  967                                                "Failed to unregister server capabilities: {e:#}"
  968                                            );
  969                                        }
  970                                    }
  971                                }
  972                            })
  973                            .ok();
  974                        Ok(())
  975                    }
  976                }
  977            })
  978            .detach();
  979
  980        language_server
  981            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  982                let this = lsp_store.clone();
  983                move |params, cx| {
  984                    let mut cx = cx.clone();
  985                    let this = this.clone();
  986                    async move {
  987                        LocalLspStore::on_lsp_workspace_edit(
  988                            this.clone(),
  989                            params,
  990                            server_id,
  991                            &mut cx,
  992                        )
  993                        .await
  994                    }
  995                }
  996            })
  997            .detach();
  998
  999        language_server
 1000            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1001                let lsp_store = lsp_store.clone();
 1002                let request_id = Arc::new(AtomicUsize::new(0));
 1003                move |(), cx| {
 1004                    let lsp_store = lsp_store.clone();
 1005                    let request_id = request_id.clone();
 1006                    let mut cx = cx.clone();
 1007                    async move {
 1008                        lsp_store
 1009                            .update(&mut cx, |lsp_store, cx| {
 1010                                let request_id =
 1011                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1012                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1013                                    server_id,
 1014                                    request_id,
 1015                                });
 1016                                lsp_store
 1017                                    .downstream_client
 1018                                    .as_ref()
 1019                                    .map(|(client, project_id)| {
 1020                                        client.send(proto::RefreshInlayHints {
 1021                                            project_id: *project_id,
 1022                                            server_id: server_id.to_proto(),
 1023                                            request_id: request_id.map(|id| id as u64),
 1024                                        })
 1025                                    })
 1026                            })?
 1027                            .transpose()?;
 1028                        Ok(())
 1029                    }
 1030                }
 1031            })
 1032            .detach();
 1033
 1034        language_server
 1035            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1036                let this = lsp_store.clone();
 1037                move |(), cx| {
 1038                    let this = this.clone();
 1039                    let mut cx = cx.clone();
 1040                    async move {
 1041                        this.update(&mut cx, |this, cx| {
 1042                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1043                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1044                                client.send(proto::RefreshCodeLens {
 1045                                    project_id: *project_id,
 1046                                })
 1047                            })
 1048                        })?
 1049                        .transpose()?;
 1050                        Ok(())
 1051                    }
 1052                }
 1053            })
 1054            .detach();
 1055
 1056        language_server
 1057            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1058                let this = lsp_store.clone();
 1059                move |(), cx| {
 1060                    let this = this.clone();
 1061                    let mut cx = cx.clone();
 1062                    async move {
 1063                        this.update(&mut cx, |lsp_store, cx| {
 1064                            lsp_store.pull_workspace_diagnostics(server_id);
 1065                            lsp_store
 1066                                .downstream_client
 1067                                .as_ref()
 1068                                .map(|(client, project_id)| {
 1069                                    client.send(proto::PullWorkspaceDiagnostics {
 1070                                        project_id: *project_id,
 1071                                        server_id: server_id.to_proto(),
 1072                                    })
 1073                                })
 1074                                .transpose()?;
 1075                            anyhow::Ok(
 1076                                lsp_store.pull_document_diagnostics_for_server(server_id, cx),
 1077                            )
 1078                        })??
 1079                        .await;
 1080                        Ok(())
 1081                    }
 1082                }
 1083            })
 1084            .detach();
 1085
 1086        language_server
 1087            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1088                let this = lsp_store.clone();
 1089                let name = name.to_string();
 1090                let adapter = adapter.clone();
 1091                move |params, cx| {
 1092                    let this = this.clone();
 1093                    let name = name.to_string();
 1094                    let adapter = adapter.clone();
 1095                    let mut cx = cx.clone();
 1096                    async move {
 1097                        let actions = params.actions.unwrap_or_default();
 1098                        let message = params.message.clone();
 1099                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1100                        let level = match params.typ {
 1101                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1102                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1103                            _ => PromptLevel::Info,
 1104                        };
 1105                        let request = LanguageServerPromptRequest::new(
 1106                            level,
 1107                            params.message,
 1108                            actions,
 1109                            name.clone(),
 1110                            tx,
 1111                        );
 1112
 1113                        let did_update = this
 1114                            .update(&mut cx, |_, cx| {
 1115                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1116                            })
 1117                            .is_ok();
 1118                        if did_update {
 1119                            let response = rx.recv().await.ok();
 1120                            if let Some(ref selected_action) = response {
 1121                                let context = language::PromptResponseContext {
 1122                                    message,
 1123                                    selected_action: selected_action.clone(),
 1124                                };
 1125                                adapter.process_prompt_response(&context, &mut cx)
 1126                            }
 1127
 1128                            Ok(response)
 1129                        } else {
 1130                            Ok(None)
 1131                        }
 1132                    }
 1133                }
 1134            })
 1135            .detach();
 1136        language_server
 1137            .on_notification::<lsp::notification::ShowMessage, _>({
 1138                let this = lsp_store.clone();
 1139                let name = name.to_string();
 1140                move |params, cx| {
 1141                    let this = this.clone();
 1142                    let name = name.to_string();
 1143                    let mut cx = cx.clone();
 1144
 1145                    let (tx, _) = smol::channel::bounded(1);
 1146                    let level = match params.typ {
 1147                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1148                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1149                        _ => PromptLevel::Info,
 1150                    };
 1151                    let request =
 1152                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1153
 1154                    let _ = this.update(&mut cx, |_, cx| {
 1155                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1156                    });
 1157                }
 1158            })
 1159            .detach();
 1160
 1161        let disk_based_diagnostics_progress_token =
 1162            adapter.disk_based_diagnostics_progress_token.clone();
 1163
 1164        language_server
 1165            .on_notification::<lsp::notification::Progress, _>({
 1166                let this = lsp_store.clone();
 1167                move |params, cx| {
 1168                    if let Some(this) = this.upgrade() {
 1169                        this.update(cx, |this, cx| {
 1170                            this.on_lsp_progress(
 1171                                params,
 1172                                server_id,
 1173                                disk_based_diagnostics_progress_token.clone(),
 1174                                cx,
 1175                            );
 1176                        });
 1177                    }
 1178                }
 1179            })
 1180            .detach();
 1181
 1182        language_server
 1183            .on_notification::<lsp::notification::LogMessage, _>({
 1184                let this = lsp_store.clone();
 1185                move |params, cx| {
 1186                    if let Some(this) = this.upgrade() {
 1187                        this.update(cx, |_, cx| {
 1188                            cx.emit(LspStoreEvent::LanguageServerLog(
 1189                                server_id,
 1190                                LanguageServerLogType::Log(params.typ),
 1191                                params.message,
 1192                            ));
 1193                        });
 1194                    }
 1195                }
 1196            })
 1197            .detach();
 1198
 1199        language_server
 1200            .on_notification::<lsp::notification::LogTrace, _>({
 1201                let this = lsp_store.clone();
 1202                move |params, cx| {
 1203                    let mut cx = cx.clone();
 1204                    if let Some(this) = this.upgrade() {
 1205                        this.update(&mut cx, |_, cx| {
 1206                            cx.emit(LspStoreEvent::LanguageServerLog(
 1207                                server_id,
 1208                                LanguageServerLogType::Trace {
 1209                                    verbose_info: params.verbose,
 1210                                },
 1211                                params.message,
 1212                            ));
 1213                        });
 1214                    }
 1215                }
 1216            })
 1217            .detach();
 1218
 1219        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1220        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1221        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1222        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1223    }
 1224
 1225    fn shutdown_language_servers_on_quit(
 1226        &mut self,
 1227        _: &mut Context<LspStore>,
 1228    ) -> impl Future<Output = ()> + use<> {
 1229        let shutdown_futures = self
 1230            .language_servers
 1231            .drain()
 1232            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1233            .collect::<Vec<_>>();
 1234
 1235        async move {
 1236            join_all(shutdown_futures).await;
 1237        }
 1238    }
 1239
 1240    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1241        match server_state {
 1242            LanguageServerState::Running { server, .. } => {
 1243                if let Some(shutdown) = server.shutdown() {
 1244                    shutdown.await;
 1245                }
 1246            }
 1247            LanguageServerState::Starting { startup, .. } => {
 1248                if let Some(server) = startup.await
 1249                    && let Some(shutdown) = server.shutdown()
 1250                {
 1251                    shutdown.await;
 1252                }
 1253            }
 1254        }
 1255        Ok(())
 1256    }
 1257
 1258    fn language_servers_for_worktree(
 1259        &self,
 1260        worktree_id: WorktreeId,
 1261    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1262        self.language_server_ids
 1263            .iter()
 1264            .filter_map(move |(seed, state)| {
 1265                if seed.worktree_id != worktree_id {
 1266                    return None;
 1267                }
 1268
 1269                if let Some(LanguageServerState::Running { server, .. }) =
 1270                    self.language_servers.get(&state.id)
 1271                {
 1272                    Some(server)
 1273                } else {
 1274                    None
 1275                }
 1276            })
 1277    }
 1278
 1279    fn language_server_ids_for_project_path(
 1280        &self,
 1281        project_path: ProjectPath,
 1282        language: &Language,
 1283        cx: &mut App,
 1284    ) -> Vec<LanguageServerId> {
 1285        let Some(worktree) = self
 1286            .worktree_store
 1287            .read(cx)
 1288            .worktree_for_id(project_path.worktree_id, cx)
 1289        else {
 1290            return Vec::new();
 1291        };
 1292        let delegate: Arc<dyn ManifestDelegate> =
 1293            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1294
 1295        self.lsp_tree
 1296            .get(
 1297                project_path,
 1298                language.name(),
 1299                language.manifest(),
 1300                &delegate,
 1301                cx,
 1302            )
 1303            .collect::<Vec<_>>()
 1304    }
 1305
 1306    fn language_server_ids_for_buffer(
 1307        &self,
 1308        buffer: &Buffer,
 1309        cx: &mut App,
 1310    ) -> Vec<LanguageServerId> {
 1311        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1312            let worktree_id = file.worktree_id(cx);
 1313
 1314            let path: Arc<RelPath> = file
 1315                .path()
 1316                .parent()
 1317                .map(Arc::from)
 1318                .unwrap_or_else(|| file.path().clone());
 1319            let worktree_path = ProjectPath { worktree_id, path };
 1320            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1321        } else {
 1322            Vec::new()
 1323        }
 1324    }
 1325
 1326    fn language_servers_for_buffer<'a>(
 1327        &'a self,
 1328        buffer: &'a Buffer,
 1329        cx: &'a mut App,
 1330    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1331        self.language_server_ids_for_buffer(buffer, cx)
 1332            .into_iter()
 1333            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1334                LanguageServerState::Running {
 1335                    adapter, server, ..
 1336                } => Some((adapter, server)),
 1337                _ => None,
 1338            })
 1339    }
 1340
 1341    async fn execute_code_action_kind_locally(
 1342        lsp_store: WeakEntity<LspStore>,
 1343        mut buffers: Vec<Entity<Buffer>>,
 1344        kind: CodeActionKind,
 1345        push_to_history: bool,
 1346        cx: &mut AsyncApp,
 1347    ) -> anyhow::Result<ProjectTransaction> {
 1348        // Do not allow multiple concurrent code actions requests for the
 1349        // same buffer.
 1350        lsp_store.update(cx, |this, cx| {
 1351            let this = this.as_local_mut().unwrap();
 1352            buffers.retain(|buffer| {
 1353                this.buffers_being_formatted
 1354                    .insert(buffer.read(cx).remote_id())
 1355            });
 1356        })?;
 1357        let _cleanup = defer({
 1358            let this = lsp_store.clone();
 1359            let mut cx = cx.clone();
 1360            let buffers = &buffers;
 1361            move || {
 1362                this.update(&mut cx, |this, cx| {
 1363                    let this = this.as_local_mut().unwrap();
 1364                    for buffer in buffers {
 1365                        this.buffers_being_formatted
 1366                            .remove(&buffer.read(cx).remote_id());
 1367                    }
 1368                })
 1369                .ok();
 1370            }
 1371        });
 1372        let mut project_transaction = ProjectTransaction::default();
 1373
 1374        for buffer in &buffers {
 1375            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1376                buffer.update(cx, |buffer, cx| {
 1377                    lsp_store
 1378                        .as_local()
 1379                        .unwrap()
 1380                        .language_servers_for_buffer(buffer, cx)
 1381                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1382                        .collect::<Vec<_>>()
 1383                })
 1384            })?;
 1385            for (_, language_server) in adapters_and_servers.iter() {
 1386                let actions = Self::get_server_code_actions_from_action_kinds(
 1387                    &lsp_store,
 1388                    language_server.server_id(),
 1389                    vec![kind.clone()],
 1390                    buffer,
 1391                    cx,
 1392                )
 1393                .await?;
 1394                Self::execute_code_actions_on_server(
 1395                    &lsp_store,
 1396                    language_server,
 1397                    actions,
 1398                    push_to_history,
 1399                    &mut project_transaction,
 1400                    cx,
 1401                )
 1402                .await?;
 1403            }
 1404        }
 1405        Ok(project_transaction)
 1406    }
 1407
 1408    async fn format_locally(
 1409        lsp_store: WeakEntity<LspStore>,
 1410        mut buffers: Vec<FormattableBuffer>,
 1411        push_to_history: bool,
 1412        trigger: FormatTrigger,
 1413        logger: zlog::Logger,
 1414        cx: &mut AsyncApp,
 1415    ) -> anyhow::Result<ProjectTransaction> {
 1416        // Do not allow multiple concurrent formatting requests for the
 1417        // same buffer.
 1418        lsp_store.update(cx, |this, cx| {
 1419            let this = this.as_local_mut().unwrap();
 1420            buffers.retain(|buffer| {
 1421                this.buffers_being_formatted
 1422                    .insert(buffer.handle.read(cx).remote_id())
 1423            });
 1424        })?;
 1425
 1426        let _cleanup = defer({
 1427            let this = lsp_store.clone();
 1428            let mut cx = cx.clone();
 1429            let buffers = &buffers;
 1430            move || {
 1431                this.update(&mut cx, |this, cx| {
 1432                    let this = this.as_local_mut().unwrap();
 1433                    for buffer in buffers {
 1434                        this.buffers_being_formatted
 1435                            .remove(&buffer.handle.read(cx).remote_id());
 1436                    }
 1437                })
 1438                .ok();
 1439            }
 1440        });
 1441
 1442        let mut project_transaction = ProjectTransaction::default();
 1443
 1444        for buffer in &buffers {
 1445            zlog::debug!(
 1446                logger =>
 1447                "formatting buffer '{:?}'",
 1448                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1449            );
 1450            // Create an empty transaction to hold all of the formatting edits.
 1451            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1452                // ensure no transactions created while formatting are
 1453                // grouped with the previous transaction in the history
 1454                // based on the transaction group interval
 1455                buffer.finalize_last_transaction();
 1456                buffer
 1457                    .start_transaction()
 1458                    .context("transaction already open")?;
 1459                buffer.end_transaction(cx);
 1460                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1461                buffer.finalize_last_transaction();
 1462                anyhow::Ok(transaction_id)
 1463            })?;
 1464
 1465            let result = Self::format_buffer_locally(
 1466                lsp_store.clone(),
 1467                buffer,
 1468                formatting_transaction_id,
 1469                trigger,
 1470                logger,
 1471                cx,
 1472            )
 1473            .await;
 1474
 1475            buffer.handle.update(cx, |buffer, cx| {
 1476                let Some(formatting_transaction) =
 1477                    buffer.get_transaction(formatting_transaction_id).cloned()
 1478                else {
 1479                    zlog::warn!(logger => "no formatting transaction");
 1480                    return;
 1481                };
 1482                if formatting_transaction.edit_ids.is_empty() {
 1483                    zlog::debug!(logger => "no changes made while formatting");
 1484                    buffer.forget_transaction(formatting_transaction_id);
 1485                    return;
 1486                }
 1487                if !push_to_history {
 1488                    zlog::trace!(logger => "forgetting format transaction");
 1489                    buffer.forget_transaction(formatting_transaction.id);
 1490                }
 1491                project_transaction
 1492                    .0
 1493                    .insert(cx.entity(), formatting_transaction);
 1494            });
 1495
 1496            result?;
 1497        }
 1498
 1499        Ok(project_transaction)
 1500    }
 1501
 1502    async fn format_buffer_locally(
 1503        lsp_store: WeakEntity<LspStore>,
 1504        buffer: &FormattableBuffer,
 1505        formatting_transaction_id: clock::Lamport,
 1506        trigger: FormatTrigger,
 1507        logger: zlog::Logger,
 1508        cx: &mut AsyncApp,
 1509    ) -> Result<()> {
 1510        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1511            buffer.handle.update(cx, |buffer, cx| {
 1512                let adapters_and_servers = lsp_store
 1513                    .as_local()
 1514                    .unwrap()
 1515                    .language_servers_for_buffer(buffer, cx)
 1516                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1517                    .collect::<Vec<_>>();
 1518                let settings =
 1519                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1520                        .into_owned();
 1521                (adapters_and_servers, settings)
 1522            })
 1523        })?;
 1524
 1525        /// Apply edits to the buffer that will become part of the formatting transaction.
 1526        /// Fails if the buffer has been edited since the start of that transaction.
 1527        fn extend_formatting_transaction(
 1528            buffer: &FormattableBuffer,
 1529            formatting_transaction_id: text::TransactionId,
 1530            cx: &mut AsyncApp,
 1531            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1532        ) -> anyhow::Result<()> {
 1533            buffer.handle.update(cx, |buffer, cx| {
 1534                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1535                if last_transaction_id != Some(formatting_transaction_id) {
 1536                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1537                }
 1538                buffer.start_transaction();
 1539                operation(buffer, cx);
 1540                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1541                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1542                }
 1543                Ok(())
 1544            })
 1545        }
 1546
 1547        // handle whitespace formatting
 1548        if settings.remove_trailing_whitespace_on_save {
 1549            zlog::trace!(logger => "removing trailing whitespace");
 1550            let diff = buffer
 1551                .handle
 1552                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1553                .await;
 1554            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1555                buffer.apply_diff(diff, cx);
 1556            })?;
 1557        }
 1558
 1559        if settings.ensure_final_newline_on_save {
 1560            zlog::trace!(logger => "ensuring final newline");
 1561            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1562                buffer.ensure_final_newline(cx);
 1563            })?;
 1564        }
 1565
 1566        // Formatter for `code_actions_on_format` that runs before
 1567        // the rest of the formatters
 1568        let mut code_actions_on_format_formatters = None;
 1569        let should_run_code_actions_on_format = !matches!(
 1570            (trigger, &settings.format_on_save),
 1571            (FormatTrigger::Save, &FormatOnSave::Off)
 1572        );
 1573        if should_run_code_actions_on_format {
 1574            let have_code_actions_to_run_on_format = settings
 1575                .code_actions_on_format
 1576                .values()
 1577                .any(|enabled| *enabled);
 1578            if have_code_actions_to_run_on_format {
 1579                zlog::trace!(logger => "going to run code actions on format");
 1580                code_actions_on_format_formatters = Some(
 1581                    settings
 1582                        .code_actions_on_format
 1583                        .iter()
 1584                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1585                        .cloned()
 1586                        .map(Formatter::CodeAction)
 1587                        .collect::<Vec<_>>(),
 1588                );
 1589            }
 1590        }
 1591
 1592        let formatters = match (trigger, &settings.format_on_save) {
 1593            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1594            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1595                settings.formatter.as_ref()
 1596            }
 1597        };
 1598
 1599        let formatters = code_actions_on_format_formatters
 1600            .iter()
 1601            .flatten()
 1602            .chain(formatters);
 1603
 1604        for formatter in formatters {
 1605            let formatter = if formatter == &Formatter::Auto {
 1606                if settings.prettier.allowed {
 1607                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1608                    &Formatter::Prettier
 1609                } else {
 1610                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1611                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1612                }
 1613            } else {
 1614                formatter
 1615            };
 1616            match formatter {
 1617                Formatter::Auto => unreachable!("Auto resolved above"),
 1618                Formatter::Prettier => {
 1619                    let logger = zlog::scoped!(logger => "prettier");
 1620                    zlog::trace!(logger => "formatting");
 1621                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1622
 1623                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1624                        lsp_store.prettier_store().unwrap().downgrade()
 1625                    })?;
 1626                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1627                        .await
 1628                        .transpose()?;
 1629                    let Some(diff) = diff else {
 1630                        zlog::trace!(logger => "No changes");
 1631                        continue;
 1632                    };
 1633
 1634                    extend_formatting_transaction(
 1635                        buffer,
 1636                        formatting_transaction_id,
 1637                        cx,
 1638                        |buffer, cx| {
 1639                            buffer.apply_diff(diff, cx);
 1640                        },
 1641                    )?;
 1642                }
 1643                Formatter::External { command, arguments } => {
 1644                    let logger = zlog::scoped!(logger => "command");
 1645                    zlog::trace!(logger => "formatting");
 1646                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1647
 1648                    let diff = Self::format_via_external_command(
 1649                        buffer,
 1650                        &command,
 1651                        arguments.as_deref(),
 1652                        cx,
 1653                    )
 1654                    .await
 1655                    .with_context(|| {
 1656                        format!("Failed to format buffer via external command: {}", command)
 1657                    })?;
 1658                    let Some(diff) = diff else {
 1659                        zlog::trace!(logger => "No changes");
 1660                        continue;
 1661                    };
 1662
 1663                    extend_formatting_transaction(
 1664                        buffer,
 1665                        formatting_transaction_id,
 1666                        cx,
 1667                        |buffer, cx| {
 1668                            buffer.apply_diff(diff, cx);
 1669                        },
 1670                    )?;
 1671                }
 1672                Formatter::LanguageServer(specifier) => {
 1673                    let logger = zlog::scoped!(logger => "language-server");
 1674                    zlog::trace!(logger => "formatting");
 1675                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1676
 1677                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1678                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1679                        continue;
 1680                    };
 1681
 1682                    let language_server = match specifier {
 1683                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1684                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1685                                if adapter.name.0.as_ref() == name {
 1686                                    Some(server.clone())
 1687                                } else {
 1688                                    None
 1689                                }
 1690                            })
 1691                        }
 1692                        settings::LanguageServerFormatterSpecifier::Current => {
 1693                            adapters_and_servers.first().map(|e| e.1.clone())
 1694                        }
 1695                    };
 1696
 1697                    let Some(language_server) = language_server else {
 1698                        log::debug!(
 1699                            "No language server found to format buffer '{:?}'. Skipping",
 1700                            buffer_path_abs.as_path().to_string_lossy()
 1701                        );
 1702                        continue;
 1703                    };
 1704
 1705                    zlog::trace!(
 1706                        logger =>
 1707                        "Formatting buffer '{:?}' using language server '{:?}'",
 1708                        buffer_path_abs.as_path().to_string_lossy(),
 1709                        language_server.name()
 1710                    );
 1711
 1712                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1713                        zlog::trace!(logger => "formatting ranges");
 1714                        Self::format_ranges_via_lsp(
 1715                            &lsp_store,
 1716                            &buffer.handle,
 1717                            ranges,
 1718                            buffer_path_abs,
 1719                            &language_server,
 1720                            &settings,
 1721                            cx,
 1722                        )
 1723                        .await
 1724                        .context("Failed to format ranges via language server")?
 1725                    } else {
 1726                        zlog::trace!(logger => "formatting full");
 1727                        Self::format_via_lsp(
 1728                            &lsp_store,
 1729                            &buffer.handle,
 1730                            buffer_path_abs,
 1731                            &language_server,
 1732                            &settings,
 1733                            cx,
 1734                        )
 1735                        .await
 1736                        .context("failed to format via language server")?
 1737                    };
 1738
 1739                    if edits.is_empty() {
 1740                        zlog::trace!(logger => "No changes");
 1741                        continue;
 1742                    }
 1743                    extend_formatting_transaction(
 1744                        buffer,
 1745                        formatting_transaction_id,
 1746                        cx,
 1747                        |buffer, cx| {
 1748                            buffer.edit(edits, None, cx);
 1749                        },
 1750                    )?;
 1751                }
 1752                Formatter::CodeAction(code_action_name) => {
 1753                    let logger = zlog::scoped!(logger => "code-actions");
 1754                    zlog::trace!(logger => "formatting");
 1755                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1756
 1757                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1758                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1759                        continue;
 1760                    };
 1761
 1762                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1763                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1764
 1765                    let mut actions_and_servers = Vec::new();
 1766
 1767                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1768                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1769                            &lsp_store,
 1770                            language_server.server_id(),
 1771                            vec![code_action_kind.clone()],
 1772                            &buffer.handle,
 1773                            cx,
 1774                        )
 1775                        .await
 1776                        .with_context(|| {
 1777                            format!(
 1778                                "Failed to resolve code action {:?} with language server {}",
 1779                                code_action_kind,
 1780                                language_server.name()
 1781                            )
 1782                        });
 1783                        let Ok(actions) = actions_result else {
 1784                            // note: it may be better to set result to the error and break formatters here
 1785                            // but for now we try to execute the actions that we can resolve and skip the rest
 1786                            zlog::error!(
 1787                                logger =>
 1788                                "Failed to resolve code action {:?} with language server {}",
 1789                                code_action_kind,
 1790                                language_server.name()
 1791                            );
 1792                            continue;
 1793                        };
 1794                        for action in actions {
 1795                            actions_and_servers.push((action, index));
 1796                        }
 1797                    }
 1798
 1799                    if actions_and_servers.is_empty() {
 1800                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1801                        continue;
 1802                    }
 1803
 1804                    'actions: for (mut action, server_index) in actions_and_servers {
 1805                        let server = &adapters_and_servers[server_index].1;
 1806
 1807                        let describe_code_action = |action: &CodeAction| {
 1808                            format!(
 1809                                "code action '{}' with title \"{}\" on server {}",
 1810                                action
 1811                                    .lsp_action
 1812                                    .action_kind()
 1813                                    .unwrap_or("unknown".into())
 1814                                    .as_str(),
 1815                                action.lsp_action.title(),
 1816                                server.name(),
 1817                            )
 1818                        };
 1819
 1820                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1821
 1822                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1823                            zlog::error!(
 1824                                logger =>
 1825                                "Failed to resolve {}. Error: {}",
 1826                                describe_code_action(&action),
 1827                                err
 1828                            );
 1829                            continue;
 1830                        }
 1831
 1832                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1833                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1834                            // but filters out and logs warnings for code actions that require unreasonably
 1835                            // difficult handling on our part, such as:
 1836                            // - applying edits that call commands
 1837                            //   which can result in arbitrary workspace edits being sent from the server that
 1838                            //   have no way of being tied back to the command that initiated them (i.e. we
 1839                            //   can't know which edits are part of the format request, or if the server is done sending
 1840                            //   actions in response to the command)
 1841                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1842                            //   as we then would need to handle such changes correctly in the local history as well
 1843                            //   as the remote history through the ProjectTransaction
 1844                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1845                            // Supporting these actions is not impossible, but not supported as of yet.
 1846                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1847                                zlog::trace!(
 1848                                    logger =>
 1849                                    "No changes for code action. Skipping {}",
 1850                                    describe_code_action(&action),
 1851                                );
 1852                                continue;
 1853                            }
 1854
 1855                            let mut operations = Vec::new();
 1856                            if let Some(document_changes) = edit.document_changes {
 1857                                match document_changes {
 1858                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1859                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1860                                    ),
 1861                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1862                                }
 1863                            } else if let Some(changes) = edit.changes {
 1864                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1865                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1866                                        text_document:
 1867                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1868                                                uri,
 1869                                                version: None,
 1870                                            },
 1871                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1872                                    })
 1873                                }));
 1874                            }
 1875
 1876                            let mut edits = Vec::with_capacity(operations.len());
 1877
 1878                            if operations.is_empty() {
 1879                                zlog::trace!(
 1880                                    logger =>
 1881                                    "No changes for code action. Skipping {}",
 1882                                    describe_code_action(&action),
 1883                                );
 1884                                continue;
 1885                            }
 1886                            for operation in operations {
 1887                                let op = match operation {
 1888                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1889                                    lsp::DocumentChangeOperation::Op(_) => {
 1890                                        zlog::warn!(
 1891                                            logger =>
 1892                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1893                                            describe_code_action(&action),
 1894                                        );
 1895                                        continue 'actions;
 1896                                    }
 1897                                };
 1898                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1899                                    zlog::warn!(
 1900                                        logger =>
 1901                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1902                                        &op.text_document.uri,
 1903                                        describe_code_action(&action),
 1904                                    );
 1905                                    continue 'actions;
 1906                                };
 1907                                if &file_path != buffer_path_abs {
 1908                                    zlog::warn!(
 1909                                        logger =>
 1910                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1911                                        file_path,
 1912                                        buffer_path_abs,
 1913                                        describe_code_action(&action),
 1914                                    );
 1915                                    continue 'actions;
 1916                                }
 1917
 1918                                let mut lsp_edits = Vec::new();
 1919                                for edit in op.edits {
 1920                                    match edit {
 1921                                        Edit::Plain(edit) => {
 1922                                            if !lsp_edits.contains(&edit) {
 1923                                                lsp_edits.push(edit);
 1924                                            }
 1925                                        }
 1926                                        Edit::Annotated(edit) => {
 1927                                            if !lsp_edits.contains(&edit.text_edit) {
 1928                                                lsp_edits.push(edit.text_edit);
 1929                                            }
 1930                                        }
 1931                                        Edit::Snippet(_) => {
 1932                                            zlog::warn!(
 1933                                                logger =>
 1934                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1935                                                describe_code_action(&action),
 1936                                            );
 1937                                            continue 'actions;
 1938                                        }
 1939                                    }
 1940                                }
 1941                                let edits_result = lsp_store
 1942                                    .update(cx, |lsp_store, cx| {
 1943                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1944                                            &buffer.handle,
 1945                                            lsp_edits,
 1946                                            server.server_id(),
 1947                                            op.text_document.version,
 1948                                            cx,
 1949                                        )
 1950                                    })?
 1951                                    .await;
 1952                                let Ok(resolved_edits) = edits_result else {
 1953                                    zlog::warn!(
 1954                                        logger =>
 1955                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1956                                        buffer_path_abs.as_path(),
 1957                                        describe_code_action(&action),
 1958                                    );
 1959                                    continue 'actions;
 1960                                };
 1961                                edits.extend(resolved_edits);
 1962                            }
 1963
 1964                            if edits.is_empty() {
 1965                                zlog::warn!(logger => "No edits resolved from LSP");
 1966                                continue;
 1967                            }
 1968
 1969                            extend_formatting_transaction(
 1970                                buffer,
 1971                                formatting_transaction_id,
 1972                                cx,
 1973                                |buffer, cx| {
 1974                                    zlog::info!(
 1975                                        "Applying edits {edits:?}. Content: {:?}",
 1976                                        buffer.text()
 1977                                    );
 1978                                    buffer.edit(edits, None, cx);
 1979                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1980                                },
 1981                            )?;
 1982                        }
 1983
 1984                        if let Some(command) = action.lsp_action.command() {
 1985                            zlog::warn!(
 1986                                logger =>
 1987                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1988                                &command.command,
 1989                            );
 1990
 1991                            // bail early if command is invalid
 1992                            let server_capabilities = server.capabilities();
 1993                            let available_commands = server_capabilities
 1994                                .execute_command_provider
 1995                                .as_ref()
 1996                                .map(|options| options.commands.as_slice())
 1997                                .unwrap_or_default();
 1998                            if !available_commands.contains(&command.command) {
 1999                                zlog::warn!(
 2000                                    logger =>
 2001                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2002                                    command.command,
 2003                                    server.name(),
 2004                                );
 2005                                continue;
 2006                            }
 2007
 2008                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 2009                            extend_formatting_transaction(
 2010                                buffer,
 2011                                formatting_transaction_id,
 2012                                cx,
 2013                                |_, _| {},
 2014                            )?;
 2015                            zlog::info!(logger => "Executing command {}", &command.command);
 2016
 2017                            lsp_store.update(cx, |this, _| {
 2018                                this.as_local_mut()
 2019                                    .unwrap()
 2020                                    .last_workspace_edits_by_language_server
 2021                                    .remove(&server.server_id());
 2022                            })?;
 2023
 2024                            let execute_command_result = server
 2025                                .request::<lsp::request::ExecuteCommand>(
 2026                                    lsp::ExecuteCommandParams {
 2027                                        command: command.command.clone(),
 2028                                        arguments: command.arguments.clone().unwrap_or_default(),
 2029                                        ..Default::default()
 2030                                    },
 2031                                )
 2032                                .await
 2033                                .into_response();
 2034
 2035                            if execute_command_result.is_err() {
 2036                                zlog::error!(
 2037                                    logger =>
 2038                                    "Failed to execute command '{}' as part of {}",
 2039                                    &command.command,
 2040                                    describe_code_action(&action),
 2041                                );
 2042                                continue 'actions;
 2043                            }
 2044
 2045                            let mut project_transaction_command =
 2046                                lsp_store.update(cx, |this, _| {
 2047                                    this.as_local_mut()
 2048                                        .unwrap()
 2049                                        .last_workspace_edits_by_language_server
 2050                                        .remove(&server.server_id())
 2051                                        .unwrap_or_default()
 2052                                })?;
 2053
 2054                            if let Some(transaction) =
 2055                                project_transaction_command.0.remove(&buffer.handle)
 2056                            {
 2057                                zlog::trace!(
 2058                                    logger =>
 2059                                    "Successfully captured {} edits that resulted from command {}",
 2060                                    transaction.edit_ids.len(),
 2061                                    &command.command,
 2062                                );
 2063                                let transaction_id_project_transaction = transaction.id;
 2064                                buffer.handle.update(cx, |buffer, _| {
 2065                                    // it may have been removed from history if push_to_history was
 2066                                    // false in deserialize_workspace_edit. If so push it so we
 2067                                    // can merge it with the format transaction
 2068                                    // and pop the combined transaction off the history stack
 2069                                    // later if push_to_history is false
 2070                                    if buffer.get_transaction(transaction.id).is_none() {
 2071                                        buffer.push_transaction(transaction, Instant::now());
 2072                                    }
 2073                                    buffer.merge_transactions(
 2074                                        transaction_id_project_transaction,
 2075                                        formatting_transaction_id,
 2076                                    );
 2077                                });
 2078                            }
 2079
 2080                            if !project_transaction_command.0.is_empty() {
 2081                                let mut extra_buffers = String::new();
 2082                                for buffer in project_transaction_command.0.keys() {
 2083                                    buffer.read_with(cx, |b, cx| {
 2084                                        if let Some(path) = b.project_path(cx) {
 2085                                            if !extra_buffers.is_empty() {
 2086                                                extra_buffers.push_str(", ");
 2087                                            }
 2088                                            extra_buffers.push_str(path.path.as_unix_str());
 2089                                        }
 2090                                    });
 2091                                }
 2092                                zlog::warn!(
 2093                                    logger =>
 2094                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2095                                    &command.command,
 2096                                    extra_buffers,
 2097                                );
 2098                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2099                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2100                                // add it so it's included, and merge it into the format transaction when its created later
 2101                            }
 2102                        }
 2103                    }
 2104                }
 2105            }
 2106        }
 2107
 2108        Ok(())
 2109    }
 2110
 2111    pub async fn format_ranges_via_lsp(
 2112        this: &WeakEntity<LspStore>,
 2113        buffer_handle: &Entity<Buffer>,
 2114        ranges: &[Range<Anchor>],
 2115        abs_path: &Path,
 2116        language_server: &Arc<LanguageServer>,
 2117        settings: &LanguageSettings,
 2118        cx: &mut AsyncApp,
 2119    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2120        let capabilities = &language_server.capabilities();
 2121        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2122        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2123            anyhow::bail!(
 2124                "{} language server does not support range formatting",
 2125                language_server.name()
 2126            );
 2127        }
 2128
 2129        let uri = file_path_to_lsp_url(abs_path)?;
 2130        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2131
 2132        let lsp_edits = {
 2133            let mut lsp_ranges = Vec::new();
 2134            this.update(cx, |_this, cx| {
 2135                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2136                // not have been sent to the language server. This seems like a fairly systemic
 2137                // issue, though, the resolution probably is not specific to formatting.
 2138                //
 2139                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2140                // LSP.
 2141                let snapshot = buffer_handle.read(cx).snapshot();
 2142                for range in ranges {
 2143                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2144                }
 2145                anyhow::Ok(())
 2146            })??;
 2147
 2148            let mut edits = None;
 2149            for range in lsp_ranges {
 2150                if let Some(mut edit) = language_server
 2151                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2152                        text_document: text_document.clone(),
 2153                        range,
 2154                        options: lsp_command::lsp_formatting_options(settings),
 2155                        work_done_progress_params: Default::default(),
 2156                    })
 2157                    .await
 2158                    .into_response()?
 2159                {
 2160                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2161                }
 2162            }
 2163            edits
 2164        };
 2165
 2166        if let Some(lsp_edits) = lsp_edits {
 2167            this.update(cx, |this, cx| {
 2168                this.as_local_mut().unwrap().edits_from_lsp(
 2169                    buffer_handle,
 2170                    lsp_edits,
 2171                    language_server.server_id(),
 2172                    None,
 2173                    cx,
 2174                )
 2175            })?
 2176            .await
 2177        } else {
 2178            Ok(Vec::with_capacity(0))
 2179        }
 2180    }
 2181
 2182    async fn format_via_lsp(
 2183        this: &WeakEntity<LspStore>,
 2184        buffer: &Entity<Buffer>,
 2185        abs_path: &Path,
 2186        language_server: &Arc<LanguageServer>,
 2187        settings: &LanguageSettings,
 2188        cx: &mut AsyncApp,
 2189    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2190        let logger = zlog::scoped!("lsp_format");
 2191        zlog::debug!(logger => "Formatting via LSP");
 2192
 2193        let uri = file_path_to_lsp_url(abs_path)?;
 2194        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2195        let capabilities = &language_server.capabilities();
 2196
 2197        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2198        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2199
 2200        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2201            let _timer = zlog::time!(logger => "format-full");
 2202            language_server
 2203                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2204                    text_document,
 2205                    options: lsp_command::lsp_formatting_options(settings),
 2206                    work_done_progress_params: Default::default(),
 2207                })
 2208                .await
 2209                .into_response()?
 2210        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2211            let _timer = zlog::time!(logger => "format-range");
 2212            let buffer_start = lsp::Position::new(0, 0);
 2213            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2214            language_server
 2215                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2216                    text_document: text_document.clone(),
 2217                    range: lsp::Range::new(buffer_start, buffer_end),
 2218                    options: lsp_command::lsp_formatting_options(settings),
 2219                    work_done_progress_params: Default::default(),
 2220                })
 2221                .await
 2222                .into_response()?
 2223        } else {
 2224            None
 2225        };
 2226
 2227        if let Some(lsp_edits) = lsp_edits {
 2228            this.update(cx, |this, cx| {
 2229                this.as_local_mut().unwrap().edits_from_lsp(
 2230                    buffer,
 2231                    lsp_edits,
 2232                    language_server.server_id(),
 2233                    None,
 2234                    cx,
 2235                )
 2236            })?
 2237            .await
 2238        } else {
 2239            Ok(Vec::with_capacity(0))
 2240        }
 2241    }
 2242
 2243    async fn format_via_external_command(
 2244        buffer: &FormattableBuffer,
 2245        command: &str,
 2246        arguments: Option<&[String]>,
 2247        cx: &mut AsyncApp,
 2248    ) -> Result<Option<Diff>> {
 2249        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2250            let file = File::from_dyn(buffer.file())?;
 2251            let worktree = file.worktree.read(cx);
 2252            let mut worktree_path = worktree.abs_path().to_path_buf();
 2253            if worktree.root_entry()?.is_file() {
 2254                worktree_path.pop();
 2255            }
 2256            Some(worktree_path)
 2257        });
 2258
 2259        let mut child = util::command::new_smol_command(command);
 2260
 2261        if let Some(buffer_env) = buffer.env.as_ref() {
 2262            child.envs(buffer_env);
 2263        }
 2264
 2265        if let Some(working_dir_path) = working_dir_path {
 2266            child.current_dir(working_dir_path);
 2267        }
 2268
 2269        if let Some(arguments) = arguments {
 2270            child.args(arguments.iter().map(|arg| {
 2271                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2272                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2273                } else {
 2274                    arg.replace("{buffer_path}", "Untitled")
 2275                }
 2276            }));
 2277        }
 2278
 2279        let mut child = child
 2280            .stdin(smol::process::Stdio::piped())
 2281            .stdout(smol::process::Stdio::piped())
 2282            .stderr(smol::process::Stdio::piped())
 2283            .spawn()?;
 2284
 2285        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2286        let text = buffer
 2287            .handle
 2288            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2289        for chunk in text.chunks() {
 2290            stdin.write_all(chunk.as_bytes()).await?;
 2291        }
 2292        stdin.flush().await?;
 2293
 2294        let output = child.output().await?;
 2295        anyhow::ensure!(
 2296            output.status.success(),
 2297            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2298            output.status.code(),
 2299            String::from_utf8_lossy(&output.stdout),
 2300            String::from_utf8_lossy(&output.stderr),
 2301        );
 2302
 2303        let stdout = String::from_utf8(output.stdout)?;
 2304        Ok(Some(
 2305            buffer
 2306                .handle
 2307                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2308                .await,
 2309        ))
 2310    }
 2311
 2312    async fn try_resolve_code_action(
 2313        lang_server: &LanguageServer,
 2314        action: &mut CodeAction,
 2315    ) -> anyhow::Result<()> {
 2316        match &mut action.lsp_action {
 2317            LspAction::Action(lsp_action) => {
 2318                if !action.resolved
 2319                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2320                    && lsp_action.data.is_some()
 2321                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2322                {
 2323                    **lsp_action = lang_server
 2324                        .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2325                        .await
 2326                        .into_response()?;
 2327                }
 2328            }
 2329            LspAction::CodeLens(lens) => {
 2330                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2331                    *lens = lang_server
 2332                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2333                        .await
 2334                        .into_response()?;
 2335                }
 2336            }
 2337            LspAction::Command(_) => {}
 2338        }
 2339
 2340        action.resolved = true;
 2341        anyhow::Ok(())
 2342    }
 2343
 2344    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2345        let buffer = buffer_handle.read(cx);
 2346
 2347        let file = buffer.file().cloned();
 2348
 2349        let Some(file) = File::from_dyn(file.as_ref()) else {
 2350            return;
 2351        };
 2352        if !file.is_local() {
 2353            return;
 2354        }
 2355        let path = ProjectPath::from_file(file, cx);
 2356        let worktree_id = file.worktree_id(cx);
 2357        let language = buffer.language().cloned();
 2358
 2359        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2360            for (server_id, diagnostics) in
 2361                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2362            {
 2363                self.update_buffer_diagnostics(
 2364                    buffer_handle,
 2365                    server_id,
 2366                    None,
 2367                    None,
 2368                    None,
 2369                    Vec::new(),
 2370                    diagnostics,
 2371                    cx,
 2372                )
 2373                .log_err();
 2374            }
 2375        }
 2376        let Some(language) = language else {
 2377            return;
 2378        };
 2379        let Some(snapshot) = self
 2380            .worktree_store
 2381            .read(cx)
 2382            .worktree_for_id(worktree_id, cx)
 2383            .map(|worktree| worktree.read(cx).snapshot())
 2384        else {
 2385            return;
 2386        };
 2387        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2388
 2389        for server_id in
 2390            self.lsp_tree
 2391                .get(path, language.name(), language.manifest(), &delegate, cx)
 2392        {
 2393            let server = self
 2394                .language_servers
 2395                .get(&server_id)
 2396                .and_then(|server_state| {
 2397                    if let LanguageServerState::Running { server, .. } = server_state {
 2398                        Some(server.clone())
 2399                    } else {
 2400                        None
 2401                    }
 2402                });
 2403            let server = match server {
 2404                Some(server) => server,
 2405                None => continue,
 2406            };
 2407
 2408            buffer_handle.update(cx, |buffer, cx| {
 2409                buffer.set_completion_triggers(
 2410                    server.server_id(),
 2411                    server
 2412                        .capabilities()
 2413                        .completion_provider
 2414                        .as_ref()
 2415                        .and_then(|provider| {
 2416                            provider
 2417                                .trigger_characters
 2418                                .as_ref()
 2419                                .map(|characters| characters.iter().cloned().collect())
 2420                        })
 2421                        .unwrap_or_default(),
 2422                    cx,
 2423                );
 2424            });
 2425        }
 2426    }
 2427
 2428    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2429        buffer.update(cx, |buffer, cx| {
 2430            let Some(language) = buffer.language() else {
 2431                return;
 2432            };
 2433            let path = ProjectPath {
 2434                worktree_id: old_file.worktree_id(cx),
 2435                path: old_file.path.clone(),
 2436            };
 2437            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2438                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2439                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2440            }
 2441        });
 2442    }
 2443
 2444    fn update_buffer_diagnostics(
 2445        &mut self,
 2446        buffer: &Entity<Buffer>,
 2447        server_id: LanguageServerId,
 2448        registration_id: Option<Option<SharedString>>,
 2449        result_id: Option<SharedString>,
 2450        version: Option<i32>,
 2451        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2452        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2453        cx: &mut Context<LspStore>,
 2454    ) -> Result<()> {
 2455        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2456            Ordering::Equal
 2457                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2458                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2459                .then_with(|| a.severity.cmp(&b.severity))
 2460                .then_with(|| a.message.cmp(&b.message))
 2461        }
 2462
 2463        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2464        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2465        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2466
 2467        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2468            Ordering::Equal
 2469                .then_with(|| a.range.start.cmp(&b.range.start))
 2470                .then_with(|| b.range.end.cmp(&a.range.end))
 2471                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2472        });
 2473
 2474        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2475
 2476        let edits_since_save = std::cell::LazyCell::new(|| {
 2477            let saved_version = buffer.read(cx).saved_version();
 2478            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2479        });
 2480
 2481        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2482
 2483        for (new_diagnostic, entry) in diagnostics {
 2484            let start;
 2485            let end;
 2486            if new_diagnostic && entry.diagnostic.is_disk_based {
 2487                // Some diagnostics are based on files on disk instead of buffers'
 2488                // current contents. Adjust these diagnostics' ranges to reflect
 2489                // any unsaved edits.
 2490                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2491                // and were properly adjusted on reuse.
 2492                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2493                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2494            } else {
 2495                start = entry.range.start;
 2496                end = entry.range.end;
 2497            }
 2498
 2499            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2500                ..snapshot.clip_point_utf16(end, Bias::Right);
 2501
 2502            // Expand empty ranges by one codepoint
 2503            if range.start == range.end {
 2504                // This will be go to the next boundary when being clipped
 2505                range.end.column += 1;
 2506                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2507                if range.start == range.end && range.end.column > 0 {
 2508                    range.start.column -= 1;
 2509                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2510                }
 2511            }
 2512
 2513            sanitized_diagnostics.push(DiagnosticEntry {
 2514                range,
 2515                diagnostic: entry.diagnostic,
 2516            });
 2517        }
 2518        drop(edits_since_save);
 2519
 2520        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2521        buffer.update(cx, |buffer, cx| {
 2522            if let Some(registration_id) = registration_id {
 2523                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2524                    self.buffer_pull_diagnostics_result_ids
 2525                        .entry(server_id)
 2526                        .or_default()
 2527                        .entry(registration_id)
 2528                        .or_default()
 2529                        .insert(abs_path, result_id);
 2530                }
 2531            }
 2532
 2533            buffer.update_diagnostics(server_id, set, cx)
 2534        });
 2535
 2536        Ok(())
 2537    }
 2538
 2539    fn register_language_server_for_invisible_worktree(
 2540        &mut self,
 2541        worktree: &Entity<Worktree>,
 2542        language_server_id: LanguageServerId,
 2543        cx: &mut App,
 2544    ) {
 2545        let worktree = worktree.read(cx);
 2546        let worktree_id = worktree.id();
 2547        debug_assert!(!worktree.is_visible());
 2548        let Some(mut origin_seed) = self
 2549            .language_server_ids
 2550            .iter()
 2551            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2552        else {
 2553            return;
 2554        };
 2555        origin_seed.worktree_id = worktree_id;
 2556        self.language_server_ids
 2557            .entry(origin_seed)
 2558            .or_insert_with(|| UnifiedLanguageServer {
 2559                id: language_server_id,
 2560                project_roots: Default::default(),
 2561            });
 2562    }
 2563
 2564    fn register_buffer_with_language_servers(
 2565        &mut self,
 2566        buffer_handle: &Entity<Buffer>,
 2567        only_register_servers: HashSet<LanguageServerSelector>,
 2568        cx: &mut Context<LspStore>,
 2569    ) {
 2570        let buffer = buffer_handle.read(cx);
 2571        let buffer_id = buffer.remote_id();
 2572
 2573        let Some(file) = File::from_dyn(buffer.file()) else {
 2574            return;
 2575        };
 2576        if !file.is_local() {
 2577            return;
 2578        }
 2579
 2580        let abs_path = file.abs_path(cx);
 2581        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2582            return;
 2583        };
 2584        let initial_snapshot = buffer.text_snapshot();
 2585        let worktree_id = file.worktree_id(cx);
 2586
 2587        let Some(language) = buffer.language().cloned() else {
 2588            return;
 2589        };
 2590        let path: Arc<RelPath> = file
 2591            .path()
 2592            .parent()
 2593            .map(Arc::from)
 2594            .unwrap_or_else(|| file.path().clone());
 2595        let Some(worktree) = self
 2596            .worktree_store
 2597            .read(cx)
 2598            .worktree_for_id(worktree_id, cx)
 2599        else {
 2600            return;
 2601        };
 2602        let language_name = language.name();
 2603        let (reused, delegate, servers) = self
 2604            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2605            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2606            .unwrap_or_else(|| {
 2607                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2608                let delegate: Arc<dyn ManifestDelegate> =
 2609                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2610
 2611                let servers = self
 2612                    .lsp_tree
 2613                    .walk(
 2614                        ProjectPath { worktree_id, path },
 2615                        language.name(),
 2616                        language.manifest(),
 2617                        &delegate,
 2618                        cx,
 2619                    )
 2620                    .collect::<Vec<_>>();
 2621                (false, lsp_delegate, servers)
 2622            });
 2623        let servers_and_adapters = servers
 2624            .into_iter()
 2625            .filter_map(|server_node| {
 2626                if reused && server_node.server_id().is_none() {
 2627                    return None;
 2628                }
 2629                if !only_register_servers.is_empty() {
 2630                    if let Some(server_id) = server_node.server_id()
 2631                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2632                    {
 2633                        return None;
 2634                    }
 2635                    if let Some(name) = server_node.name()
 2636                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2637                    {
 2638                        return None;
 2639                    }
 2640                }
 2641
 2642                let server_id = server_node.server_id_or_init(|disposition| {
 2643                    let path = &disposition.path;
 2644
 2645                    {
 2646                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2647
 2648                        let server_id = self.get_or_insert_language_server(
 2649                            &worktree,
 2650                            delegate.clone(),
 2651                            disposition,
 2652                            &language_name,
 2653                            cx,
 2654                        );
 2655
 2656                        if let Some(state) = self.language_servers.get(&server_id)
 2657                            && let Ok(uri) = uri
 2658                        {
 2659                            state.add_workspace_folder(uri);
 2660                        };
 2661                        server_id
 2662                    }
 2663                })?;
 2664                let server_state = self.language_servers.get(&server_id)?;
 2665                if let LanguageServerState::Running {
 2666                    server, adapter, ..
 2667                } = server_state
 2668                {
 2669                    Some((server.clone(), adapter.clone()))
 2670                } else {
 2671                    None
 2672                }
 2673            })
 2674            .collect::<Vec<_>>();
 2675        for (server, adapter) in servers_and_adapters {
 2676            buffer_handle.update(cx, |buffer, cx| {
 2677                buffer.set_completion_triggers(
 2678                    server.server_id(),
 2679                    server
 2680                        .capabilities()
 2681                        .completion_provider
 2682                        .as_ref()
 2683                        .and_then(|provider| {
 2684                            provider
 2685                                .trigger_characters
 2686                                .as_ref()
 2687                                .map(|characters| characters.iter().cloned().collect())
 2688                        })
 2689                        .unwrap_or_default(),
 2690                    cx,
 2691                );
 2692            });
 2693
 2694            let snapshot = LspBufferSnapshot {
 2695                version: 0,
 2696                snapshot: initial_snapshot.clone(),
 2697            };
 2698
 2699            let mut registered = false;
 2700            self.buffer_snapshots
 2701                .entry(buffer_id)
 2702                .or_default()
 2703                .entry(server.server_id())
 2704                .or_insert_with(|| {
 2705                    registered = true;
 2706                    server.register_buffer(
 2707                        uri.clone(),
 2708                        adapter.language_id(&language.name()),
 2709                        0,
 2710                        initial_snapshot.text(),
 2711                    );
 2712
 2713                    vec![snapshot]
 2714                });
 2715
 2716            self.buffers_opened_in_servers
 2717                .entry(buffer_id)
 2718                .or_default()
 2719                .insert(server.server_id());
 2720            if registered {
 2721                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2722                    language_server_id: server.server_id(),
 2723                    name: None,
 2724                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2725                        proto::RegisteredForBuffer {
 2726                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2727                            buffer_id: buffer_id.to_proto(),
 2728                        },
 2729                    ),
 2730                });
 2731            }
 2732        }
 2733    }
 2734
 2735    fn reuse_existing_language_server<'lang_name>(
 2736        &self,
 2737        server_tree: &LanguageServerTree,
 2738        worktree: &Entity<Worktree>,
 2739        language_name: &'lang_name LanguageName,
 2740        cx: &mut App,
 2741    ) -> Option<(
 2742        Arc<LocalLspAdapterDelegate>,
 2743        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2744    )> {
 2745        if worktree.read(cx).is_visible() {
 2746            return None;
 2747        }
 2748
 2749        let worktree_store = self.worktree_store.read(cx);
 2750        let servers = server_tree
 2751            .instances
 2752            .iter()
 2753            .filter(|(worktree_id, _)| {
 2754                worktree_store
 2755                    .worktree_for_id(**worktree_id, cx)
 2756                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2757            })
 2758            .flat_map(|(worktree_id, servers)| {
 2759                servers
 2760                    .roots
 2761                    .iter()
 2762                    .flat_map(|(_, language_servers)| language_servers)
 2763                    .map(move |(_, (server_node, server_languages))| {
 2764                        (worktree_id, server_node, server_languages)
 2765                    })
 2766                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2767                    .map(|(worktree_id, server_node, _)| {
 2768                        (
 2769                            *worktree_id,
 2770                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2771                        )
 2772                    })
 2773            })
 2774            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2775                acc.entry(worktree_id)
 2776                    .or_insert_with(Vec::new)
 2777                    .push(server_node);
 2778                acc
 2779            })
 2780            .into_values()
 2781            .max_by_key(|servers| servers.len())?;
 2782
 2783        let worktree_id = worktree.read(cx).id();
 2784        let apply = move |tree: &mut LanguageServerTree| {
 2785            for server_node in &servers {
 2786                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2787            }
 2788            servers
 2789        };
 2790
 2791        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2792        Some((delegate, apply))
 2793    }
 2794
 2795    pub(crate) fn unregister_old_buffer_from_language_servers(
 2796        &mut self,
 2797        buffer: &Entity<Buffer>,
 2798        old_file: &File,
 2799        cx: &mut App,
 2800    ) {
 2801        let old_path = match old_file.as_local() {
 2802            Some(local) => local.abs_path(cx),
 2803            None => return,
 2804        };
 2805
 2806        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2807            debug_panic!("{old_path:?} is not parseable as an URI");
 2808            return;
 2809        };
 2810        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2811    }
 2812
 2813    pub(crate) fn unregister_buffer_from_language_servers(
 2814        &mut self,
 2815        buffer: &Entity<Buffer>,
 2816        file_url: &lsp::Uri,
 2817        cx: &mut App,
 2818    ) {
 2819        buffer.update(cx, |buffer, cx| {
 2820            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2821
 2822            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2823                if snapshots
 2824                    .as_mut()
 2825                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2826                {
 2827                    language_server.unregister_buffer(file_url.clone());
 2828                }
 2829            }
 2830        });
 2831    }
 2832
 2833    fn buffer_snapshot_for_lsp_version(
 2834        &mut self,
 2835        buffer: &Entity<Buffer>,
 2836        server_id: LanguageServerId,
 2837        version: Option<i32>,
 2838        cx: &App,
 2839    ) -> Result<TextBufferSnapshot> {
 2840        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2841
 2842        if let Some(version) = version {
 2843            let buffer_id = buffer.read(cx).remote_id();
 2844            let snapshots = if let Some(snapshots) = self
 2845                .buffer_snapshots
 2846                .get_mut(&buffer_id)
 2847                .and_then(|m| m.get_mut(&server_id))
 2848            {
 2849                snapshots
 2850            } else if version == 0 {
 2851                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2852                // We detect this case and treat it as if the version was `None`.
 2853                return Ok(buffer.read(cx).text_snapshot());
 2854            } else {
 2855                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2856            };
 2857
 2858            let found_snapshot = snapshots
 2859                    .binary_search_by_key(&version, |e| e.version)
 2860                    .map(|ix| snapshots[ix].snapshot.clone())
 2861                    .map_err(|_| {
 2862                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2863                    })?;
 2864
 2865            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2866            Ok(found_snapshot)
 2867        } else {
 2868            Ok((buffer.read(cx)).text_snapshot())
 2869        }
 2870    }
 2871
 2872    async fn get_server_code_actions_from_action_kinds(
 2873        lsp_store: &WeakEntity<LspStore>,
 2874        language_server_id: LanguageServerId,
 2875        code_action_kinds: Vec<lsp::CodeActionKind>,
 2876        buffer: &Entity<Buffer>,
 2877        cx: &mut AsyncApp,
 2878    ) -> Result<Vec<CodeAction>> {
 2879        let actions = lsp_store
 2880            .update(cx, move |this, cx| {
 2881                let request = GetCodeActions {
 2882                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 2883                    kinds: Some(code_action_kinds),
 2884                };
 2885                let server = LanguageServerToQuery::Other(language_server_id);
 2886                this.request_lsp(buffer.clone(), server, request, cx)
 2887            })?
 2888            .await?;
 2889        Ok(actions)
 2890    }
 2891
 2892    pub async fn execute_code_actions_on_server(
 2893        lsp_store: &WeakEntity<LspStore>,
 2894        language_server: &Arc<LanguageServer>,
 2895
 2896        actions: Vec<CodeAction>,
 2897        push_to_history: bool,
 2898        project_transaction: &mut ProjectTransaction,
 2899        cx: &mut AsyncApp,
 2900    ) -> anyhow::Result<()> {
 2901        for mut action in actions {
 2902            Self::try_resolve_code_action(language_server, &mut action)
 2903                .await
 2904                .context("resolving a formatting code action")?;
 2905
 2906            if let Some(edit) = action.lsp_action.edit() {
 2907                if edit.changes.is_none() && edit.document_changes.is_none() {
 2908                    continue;
 2909                }
 2910
 2911                let new = Self::deserialize_workspace_edit(
 2912                    lsp_store.upgrade().context("project dropped")?,
 2913                    edit.clone(),
 2914                    push_to_history,
 2915                    language_server.clone(),
 2916                    cx,
 2917                )
 2918                .await?;
 2919                project_transaction.0.extend(new.0);
 2920            }
 2921
 2922            if let Some(command) = action.lsp_action.command() {
 2923                let server_capabilities = language_server.capabilities();
 2924                let available_commands = server_capabilities
 2925                    .execute_command_provider
 2926                    .as_ref()
 2927                    .map(|options| options.commands.as_slice())
 2928                    .unwrap_or_default();
 2929                if available_commands.contains(&command.command) {
 2930                    lsp_store.update(cx, |lsp_store, _| {
 2931                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2932                            mode.last_workspace_edits_by_language_server
 2933                                .remove(&language_server.server_id());
 2934                        }
 2935                    })?;
 2936
 2937                    language_server
 2938                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2939                            command: command.command.clone(),
 2940                            arguments: command.arguments.clone().unwrap_or_default(),
 2941                            ..Default::default()
 2942                        })
 2943                        .await
 2944                        .into_response()
 2945                        .context("execute command")?;
 2946
 2947                    lsp_store.update(cx, |this, _| {
 2948                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2949                            project_transaction.0.extend(
 2950                                mode.last_workspace_edits_by_language_server
 2951                                    .remove(&language_server.server_id())
 2952                                    .unwrap_or_default()
 2953                                    .0,
 2954                            )
 2955                        }
 2956                    })?;
 2957                } else {
 2958                    log::warn!(
 2959                        "Cannot execute a command {} not listed in the language server capabilities",
 2960                        command.command
 2961                    )
 2962                }
 2963            }
 2964        }
 2965        Ok(())
 2966    }
 2967
 2968    pub async fn deserialize_text_edits(
 2969        this: Entity<LspStore>,
 2970        buffer_to_edit: Entity<Buffer>,
 2971        edits: Vec<lsp::TextEdit>,
 2972        push_to_history: bool,
 2973        _: Arc<CachedLspAdapter>,
 2974        language_server: Arc<LanguageServer>,
 2975        cx: &mut AsyncApp,
 2976    ) -> Result<Option<Transaction>> {
 2977        let edits = this
 2978            .update(cx, |this, cx| {
 2979                this.as_local_mut().unwrap().edits_from_lsp(
 2980                    &buffer_to_edit,
 2981                    edits,
 2982                    language_server.server_id(),
 2983                    None,
 2984                    cx,
 2985                )
 2986            })
 2987            .await?;
 2988
 2989        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2990            buffer.finalize_last_transaction();
 2991            buffer.start_transaction();
 2992            for (range, text) in edits {
 2993                buffer.edit([(range, text)], None, cx);
 2994            }
 2995
 2996            if buffer.end_transaction(cx).is_some() {
 2997                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2998                if !push_to_history {
 2999                    buffer.forget_transaction(transaction.id);
 3000                }
 3001                Some(transaction)
 3002            } else {
 3003                None
 3004            }
 3005        });
 3006
 3007        Ok(transaction)
 3008    }
 3009
 3010    #[allow(clippy::type_complexity)]
 3011    pub(crate) fn edits_from_lsp(
 3012        &mut self,
 3013        buffer: &Entity<Buffer>,
 3014        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3015        server_id: LanguageServerId,
 3016        version: Option<i32>,
 3017        cx: &mut Context<LspStore>,
 3018    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3019        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3020        cx.background_spawn(async move {
 3021            let snapshot = snapshot?;
 3022            let mut lsp_edits = lsp_edits
 3023                .into_iter()
 3024                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3025                .collect::<Vec<_>>();
 3026
 3027            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 3028
 3029            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3030            let mut edits = Vec::new();
 3031            while let Some((range, mut new_text)) = lsp_edits.next() {
 3032                // Clip invalid ranges provided by the language server.
 3033                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3034                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3035
 3036                // Combine any LSP edits that are adjacent.
 3037                //
 3038                // Also, combine LSP edits that are separated from each other by only
 3039                // a newline. This is important because for some code actions,
 3040                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3041                // are separated by unchanged newline characters.
 3042                //
 3043                // In order for the diffing logic below to work properly, any edits that
 3044                // cancel each other out must be combined into one.
 3045                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3046                    if next_range.start.0 > range.end {
 3047                        if next_range.start.0.row > range.end.row + 1
 3048                            || next_range.start.0.column > 0
 3049                            || snapshot.clip_point_utf16(
 3050                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3051                                Bias::Left,
 3052                            ) > range.end
 3053                        {
 3054                            break;
 3055                        }
 3056                        new_text.push('\n');
 3057                    }
 3058                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3059                    new_text.push_str(next_text);
 3060                    lsp_edits.next();
 3061                }
 3062
 3063                // For multiline edits, perform a diff of the old and new text so that
 3064                // we can identify the changes more precisely, preserving the locations
 3065                // of any anchors positioned in the unchanged regions.
 3066                if range.end.row > range.start.row {
 3067                    let offset = range.start.to_offset(&snapshot);
 3068                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3069                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3070                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3071                        (
 3072                            snapshot.anchor_after(offset + range.start)
 3073                                ..snapshot.anchor_before(offset + range.end),
 3074                            replacement,
 3075                        )
 3076                    }));
 3077                } else if range.end == range.start {
 3078                    let anchor = snapshot.anchor_after(range.start);
 3079                    edits.push((anchor..anchor, new_text.into()));
 3080                } else {
 3081                    let edit_start = snapshot.anchor_after(range.start);
 3082                    let edit_end = snapshot.anchor_before(range.end);
 3083                    edits.push((edit_start..edit_end, new_text.into()));
 3084                }
 3085            }
 3086
 3087            Ok(edits)
 3088        })
 3089    }
 3090
 3091    pub(crate) async fn deserialize_workspace_edit(
 3092        this: Entity<LspStore>,
 3093        edit: lsp::WorkspaceEdit,
 3094        push_to_history: bool,
 3095        language_server: Arc<LanguageServer>,
 3096        cx: &mut AsyncApp,
 3097    ) -> Result<ProjectTransaction> {
 3098        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3099
 3100        let mut operations = Vec::new();
 3101        if let Some(document_changes) = edit.document_changes {
 3102            match document_changes {
 3103                lsp::DocumentChanges::Edits(edits) => {
 3104                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3105                }
 3106                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3107            }
 3108        } else if let Some(changes) = edit.changes {
 3109            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3110                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3111                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3112                        uri,
 3113                        version: None,
 3114                    },
 3115                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3116                })
 3117            }));
 3118        }
 3119
 3120        let mut project_transaction = ProjectTransaction::default();
 3121        for operation in operations {
 3122            match operation {
 3123                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3124                    let abs_path = op
 3125                        .uri
 3126                        .to_file_path()
 3127                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3128
 3129                    if let Some(parent_path) = abs_path.parent() {
 3130                        fs.create_dir(parent_path).await?;
 3131                    }
 3132                    if abs_path.ends_with("/") {
 3133                        fs.create_dir(&abs_path).await?;
 3134                    } else {
 3135                        fs.create_file(
 3136                            &abs_path,
 3137                            op.options
 3138                                .map(|options| fs::CreateOptions {
 3139                                    overwrite: options.overwrite.unwrap_or(false),
 3140                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3141                                })
 3142                                .unwrap_or_default(),
 3143                        )
 3144                        .await?;
 3145                    }
 3146                }
 3147
 3148                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3149                    let source_abs_path = op
 3150                        .old_uri
 3151                        .to_file_path()
 3152                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3153                    let target_abs_path = op
 3154                        .new_uri
 3155                        .to_file_path()
 3156                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3157
 3158                    let options = fs::RenameOptions {
 3159                        overwrite: op
 3160                            .options
 3161                            .as_ref()
 3162                            .and_then(|options| options.overwrite)
 3163                            .unwrap_or(false),
 3164                        ignore_if_exists: op
 3165                            .options
 3166                            .as_ref()
 3167                            .and_then(|options| options.ignore_if_exists)
 3168                            .unwrap_or(false),
 3169                        create_parents: true,
 3170                    };
 3171
 3172                    fs.rename(&source_abs_path, &target_abs_path, options)
 3173                        .await?;
 3174                }
 3175
 3176                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3177                    let abs_path = op
 3178                        .uri
 3179                        .to_file_path()
 3180                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3181                    let options = op
 3182                        .options
 3183                        .map(|options| fs::RemoveOptions {
 3184                            recursive: options.recursive.unwrap_or(false),
 3185                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3186                        })
 3187                        .unwrap_or_default();
 3188                    if abs_path.ends_with("/") {
 3189                        fs.remove_dir(&abs_path, options).await?;
 3190                    } else {
 3191                        fs.remove_file(&abs_path, options).await?;
 3192                    }
 3193                }
 3194
 3195                lsp::DocumentChangeOperation::Edit(op) => {
 3196                    let buffer_to_edit = this
 3197                        .update(cx, |this, cx| {
 3198                            this.open_local_buffer_via_lsp(
 3199                                op.text_document.uri.clone(),
 3200                                language_server.server_id(),
 3201                                cx,
 3202                            )
 3203                        })
 3204                        .await?;
 3205
 3206                    let edits = this
 3207                        .update(cx, |this, cx| {
 3208                            let path = buffer_to_edit.read(cx).project_path(cx);
 3209                            let active_entry = this.active_entry;
 3210                            let is_active_entry = path.is_some_and(|project_path| {
 3211                                this.worktree_store
 3212                                    .read(cx)
 3213                                    .entry_for_path(&project_path, cx)
 3214                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3215                            });
 3216                            let local = this.as_local_mut().unwrap();
 3217
 3218                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3219                            for edit in op.edits {
 3220                                match edit {
 3221                                    Edit::Plain(edit) => {
 3222                                        if !edits.contains(&edit) {
 3223                                            edits.push(edit)
 3224                                        }
 3225                                    }
 3226                                    Edit::Annotated(edit) => {
 3227                                        if !edits.contains(&edit.text_edit) {
 3228                                            edits.push(edit.text_edit)
 3229                                        }
 3230                                    }
 3231                                    Edit::Snippet(edit) => {
 3232                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3233                                        else {
 3234                                            continue;
 3235                                        };
 3236
 3237                                        if is_active_entry {
 3238                                            snippet_edits.push((edit.range, snippet));
 3239                                        } else {
 3240                                            // Since this buffer is not focused, apply a normal edit.
 3241                                            let new_edit = TextEdit {
 3242                                                range: edit.range,
 3243                                                new_text: snippet.text,
 3244                                            };
 3245                                            if !edits.contains(&new_edit) {
 3246                                                edits.push(new_edit);
 3247                                            }
 3248                                        }
 3249                                    }
 3250                                }
 3251                            }
 3252                            if !snippet_edits.is_empty() {
 3253                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3254                                let version = if let Some(buffer_version) = op.text_document.version
 3255                                {
 3256                                    local
 3257                                        .buffer_snapshot_for_lsp_version(
 3258                                            &buffer_to_edit,
 3259                                            language_server.server_id(),
 3260                                            Some(buffer_version),
 3261                                            cx,
 3262                                        )
 3263                                        .ok()
 3264                                        .map(|snapshot| snapshot.version)
 3265                                } else {
 3266                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3267                                };
 3268
 3269                                let most_recent_edit =
 3270                                    version.and_then(|version| version.most_recent());
 3271                                // Check if the edit that triggered that edit has been made by this participant.
 3272
 3273                                if let Some(most_recent_edit) = most_recent_edit {
 3274                                    cx.emit(LspStoreEvent::SnippetEdit {
 3275                                        buffer_id,
 3276                                        edits: snippet_edits,
 3277                                        most_recent_edit,
 3278                                    });
 3279                                }
 3280                            }
 3281
 3282                            local.edits_from_lsp(
 3283                                &buffer_to_edit,
 3284                                edits,
 3285                                language_server.server_id(),
 3286                                op.text_document.version,
 3287                                cx,
 3288                            )
 3289                        })
 3290                        .await?;
 3291
 3292                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3293                        buffer.finalize_last_transaction();
 3294                        buffer.start_transaction();
 3295                        for (range, text) in edits {
 3296                            buffer.edit([(range, text)], None, cx);
 3297                        }
 3298
 3299                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3300                            if push_to_history {
 3301                                buffer.finalize_last_transaction();
 3302                                buffer.get_transaction(transaction_id).cloned()
 3303                            } else {
 3304                                buffer.forget_transaction(transaction_id)
 3305                            }
 3306                        })
 3307                    });
 3308                    if let Some(transaction) = transaction {
 3309                        project_transaction.0.insert(buffer_to_edit, transaction);
 3310                    }
 3311                }
 3312            }
 3313        }
 3314
 3315        Ok(project_transaction)
 3316    }
 3317
 3318    async fn on_lsp_workspace_edit(
 3319        this: WeakEntity<LspStore>,
 3320        params: lsp::ApplyWorkspaceEditParams,
 3321        server_id: LanguageServerId,
 3322        cx: &mut AsyncApp,
 3323    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3324        let this = this.upgrade().context("project project closed")?;
 3325        let language_server = this
 3326            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3327            .context("language server not found")?;
 3328        let transaction = Self::deserialize_workspace_edit(
 3329            this.clone(),
 3330            params.edit,
 3331            true,
 3332            language_server.clone(),
 3333            cx,
 3334        )
 3335        .await
 3336        .log_err();
 3337        this.update(cx, |this, cx| {
 3338            if let Some(transaction) = transaction {
 3339                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3340
 3341                this.as_local_mut()
 3342                    .unwrap()
 3343                    .last_workspace_edits_by_language_server
 3344                    .insert(server_id, transaction);
 3345            }
 3346        });
 3347        Ok(lsp::ApplyWorkspaceEditResponse {
 3348            applied: true,
 3349            failed_change: None,
 3350            failure_reason: None,
 3351        })
 3352    }
 3353
 3354    fn remove_worktree(
 3355        &mut self,
 3356        id_to_remove: WorktreeId,
 3357        cx: &mut Context<LspStore>,
 3358    ) -> Vec<LanguageServerId> {
 3359        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3360        self.diagnostics.remove(&id_to_remove);
 3361        self.prettier_store.update(cx, |prettier_store, cx| {
 3362            prettier_store.remove_worktree(id_to_remove, cx);
 3363        });
 3364
 3365        let mut servers_to_remove = BTreeSet::default();
 3366        let mut servers_to_preserve = HashSet::default();
 3367        for (seed, state) in &self.language_server_ids {
 3368            if seed.worktree_id == id_to_remove {
 3369                servers_to_remove.insert(state.id);
 3370            } else {
 3371                servers_to_preserve.insert(state.id);
 3372            }
 3373        }
 3374        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3375        self.language_server_ids
 3376            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3377        for server_id_to_remove in &servers_to_remove {
 3378            self.language_server_watched_paths
 3379                .remove(server_id_to_remove);
 3380            self.language_server_paths_watched_for_rename
 3381                .remove(server_id_to_remove);
 3382            self.last_workspace_edits_by_language_server
 3383                .remove(server_id_to_remove);
 3384            self.language_servers.remove(server_id_to_remove);
 3385            self.buffer_pull_diagnostics_result_ids
 3386                .remove(server_id_to_remove);
 3387            self.workspace_pull_diagnostics_result_ids
 3388                .remove(server_id_to_remove);
 3389            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3390                buffer_servers.remove(server_id_to_remove);
 3391            }
 3392            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3393        }
 3394        servers_to_remove.into_iter().collect()
 3395    }
 3396
 3397    fn rebuild_watched_paths_inner<'a>(
 3398        &'a self,
 3399        language_server_id: LanguageServerId,
 3400        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3401        cx: &mut Context<LspStore>,
 3402    ) -> LanguageServerWatchedPathsBuilder {
 3403        let worktrees = self
 3404            .worktree_store
 3405            .read(cx)
 3406            .worktrees()
 3407            .filter_map(|worktree| {
 3408                self.language_servers_for_worktree(worktree.read(cx).id())
 3409                    .find(|server| server.server_id() == language_server_id)
 3410                    .map(|_| worktree)
 3411            })
 3412            .collect::<Vec<_>>();
 3413
 3414        let mut worktree_globs = HashMap::default();
 3415        let mut abs_globs = HashMap::default();
 3416        log::trace!(
 3417            "Processing new watcher paths for language server with id {}",
 3418            language_server_id
 3419        );
 3420
 3421        for watcher in watchers {
 3422            if let Some((worktree, literal_prefix, pattern)) =
 3423                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3424            {
 3425                worktree.update(cx, |worktree, _| {
 3426                    if let Some((tree, glob)) =
 3427                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3428                    {
 3429                        tree.add_path_prefix_to_scan(literal_prefix);
 3430                        worktree_globs
 3431                            .entry(tree.id())
 3432                            .or_insert_with(GlobSetBuilder::new)
 3433                            .add(glob);
 3434                    }
 3435                });
 3436            } else {
 3437                let (path, pattern) = match &watcher.glob_pattern {
 3438                    lsp::GlobPattern::String(s) => {
 3439                        let watcher_path = SanitizedPath::new(s);
 3440                        let path = glob_literal_prefix(watcher_path.as_path());
 3441                        let pattern = watcher_path
 3442                            .as_path()
 3443                            .strip_prefix(&path)
 3444                            .map(|p| p.to_string_lossy().into_owned())
 3445                            .unwrap_or_else(|e| {
 3446                                debug_panic!(
 3447                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3448                                    s,
 3449                                    path.display(),
 3450                                    e
 3451                                );
 3452                                watcher_path.as_path().to_string_lossy().into_owned()
 3453                            });
 3454                        (path, pattern)
 3455                    }
 3456                    lsp::GlobPattern::Relative(rp) => {
 3457                        let Ok(mut base_uri) = match &rp.base_uri {
 3458                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3459                            lsp::OneOf::Right(base_uri) => base_uri,
 3460                        }
 3461                        .to_file_path() else {
 3462                            continue;
 3463                        };
 3464
 3465                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3466                        let pattern = Path::new(&rp.pattern)
 3467                            .strip_prefix(&path)
 3468                            .map(|p| p.to_string_lossy().into_owned())
 3469                            .unwrap_or_else(|e| {
 3470                                debug_panic!(
 3471                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3472                                    rp.pattern,
 3473                                    path.display(),
 3474                                    e
 3475                                );
 3476                                rp.pattern.clone()
 3477                            });
 3478                        base_uri.push(path);
 3479                        (base_uri, pattern)
 3480                    }
 3481                };
 3482
 3483                if let Some(glob) = Glob::new(&pattern).log_err() {
 3484                    if !path
 3485                        .components()
 3486                        .any(|c| matches!(c, path::Component::Normal(_)))
 3487                    {
 3488                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3489                        // rather than adding a new watcher for `/`.
 3490                        for worktree in &worktrees {
 3491                            worktree_globs
 3492                                .entry(worktree.read(cx).id())
 3493                                .or_insert_with(GlobSetBuilder::new)
 3494                                .add(glob.clone());
 3495                        }
 3496                    } else {
 3497                        abs_globs
 3498                            .entry(path.into())
 3499                            .or_insert_with(GlobSetBuilder::new)
 3500                            .add(glob);
 3501                    }
 3502                }
 3503            }
 3504        }
 3505
 3506        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3507        for (worktree_id, builder) in worktree_globs {
 3508            if let Ok(globset) = builder.build() {
 3509                watch_builder.watch_worktree(worktree_id, globset);
 3510            }
 3511        }
 3512        for (abs_path, builder) in abs_globs {
 3513            if let Ok(globset) = builder.build() {
 3514                watch_builder.watch_abs_path(abs_path, globset);
 3515            }
 3516        }
 3517        watch_builder
 3518    }
 3519
 3520    fn worktree_and_path_for_file_watcher(
 3521        worktrees: &[Entity<Worktree>],
 3522        watcher: &FileSystemWatcher,
 3523        cx: &App,
 3524    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3525        worktrees.iter().find_map(|worktree| {
 3526            let tree = worktree.read(cx);
 3527            let worktree_root_path = tree.abs_path();
 3528            let path_style = tree.path_style();
 3529            match &watcher.glob_pattern {
 3530                lsp::GlobPattern::String(s) => {
 3531                    let watcher_path = SanitizedPath::new(s);
 3532                    let relative = watcher_path
 3533                        .as_path()
 3534                        .strip_prefix(&worktree_root_path)
 3535                        .ok()?;
 3536                    let literal_prefix = glob_literal_prefix(relative);
 3537                    Some((
 3538                        worktree.clone(),
 3539                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3540                        relative.to_string_lossy().into_owned(),
 3541                    ))
 3542                }
 3543                lsp::GlobPattern::Relative(rp) => {
 3544                    let base_uri = match &rp.base_uri {
 3545                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3546                        lsp::OneOf::Right(base_uri) => base_uri,
 3547                    }
 3548                    .to_file_path()
 3549                    .ok()?;
 3550                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3551                    let mut literal_prefix = relative.to_owned();
 3552                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3553                    Some((
 3554                        worktree.clone(),
 3555                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3556                        rp.pattern.clone(),
 3557                    ))
 3558                }
 3559            }
 3560        })
 3561    }
 3562
 3563    fn rebuild_watched_paths(
 3564        &mut self,
 3565        language_server_id: LanguageServerId,
 3566        cx: &mut Context<LspStore>,
 3567    ) {
 3568        let Some(registrations) = self
 3569            .language_server_dynamic_registrations
 3570            .get(&language_server_id)
 3571        else {
 3572            return;
 3573        };
 3574
 3575        let watch_builder = self.rebuild_watched_paths_inner(
 3576            language_server_id,
 3577            registrations.did_change_watched_files.values().flatten(),
 3578            cx,
 3579        );
 3580        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3581        self.language_server_watched_paths
 3582            .insert(language_server_id, watcher);
 3583
 3584        cx.notify();
 3585    }
 3586
 3587    fn on_lsp_did_change_watched_files(
 3588        &mut self,
 3589        language_server_id: LanguageServerId,
 3590        registration_id: &str,
 3591        params: DidChangeWatchedFilesRegistrationOptions,
 3592        cx: &mut Context<LspStore>,
 3593    ) {
 3594        let registrations = self
 3595            .language_server_dynamic_registrations
 3596            .entry(language_server_id)
 3597            .or_default();
 3598
 3599        registrations
 3600            .did_change_watched_files
 3601            .insert(registration_id.to_string(), params.watchers);
 3602
 3603        self.rebuild_watched_paths(language_server_id, cx);
 3604    }
 3605
 3606    fn on_lsp_unregister_did_change_watched_files(
 3607        &mut self,
 3608        language_server_id: LanguageServerId,
 3609        registration_id: &str,
 3610        cx: &mut Context<LspStore>,
 3611    ) {
 3612        let registrations = self
 3613            .language_server_dynamic_registrations
 3614            .entry(language_server_id)
 3615            .or_default();
 3616
 3617        if registrations
 3618            .did_change_watched_files
 3619            .remove(registration_id)
 3620            .is_some()
 3621        {
 3622            log::info!(
 3623                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3624                language_server_id,
 3625                registration_id
 3626            );
 3627        } else {
 3628            log::warn!(
 3629                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3630                language_server_id,
 3631                registration_id
 3632            );
 3633        }
 3634
 3635        self.rebuild_watched_paths(language_server_id, cx);
 3636    }
 3637
 3638    async fn initialization_options_for_adapter(
 3639        adapter: Arc<dyn LspAdapter>,
 3640        delegate: &Arc<dyn LspAdapterDelegate>,
 3641    ) -> Result<Option<serde_json::Value>> {
 3642        let Some(mut initialization_config) =
 3643            adapter.clone().initialization_options(delegate).await?
 3644        else {
 3645            return Ok(None);
 3646        };
 3647
 3648        for other_adapter in delegate.registered_lsp_adapters() {
 3649            if other_adapter.name() == adapter.name() {
 3650                continue;
 3651            }
 3652            if let Ok(Some(target_config)) = other_adapter
 3653                .clone()
 3654                .additional_initialization_options(adapter.name(), delegate)
 3655                .await
 3656            {
 3657                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3658            }
 3659        }
 3660
 3661        Ok(Some(initialization_config))
 3662    }
 3663
 3664    async fn workspace_configuration_for_adapter(
 3665        adapter: Arc<dyn LspAdapter>,
 3666        delegate: &Arc<dyn LspAdapterDelegate>,
 3667        toolchain: Option<Toolchain>,
 3668        requested_uri: Option<Uri>,
 3669        cx: &mut AsyncApp,
 3670    ) -> Result<serde_json::Value> {
 3671        let mut workspace_config = adapter
 3672            .clone()
 3673            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3674            .await?;
 3675
 3676        for other_adapter in delegate.registered_lsp_adapters() {
 3677            if other_adapter.name() == adapter.name() {
 3678                continue;
 3679            }
 3680            if let Ok(Some(target_config)) = other_adapter
 3681                .clone()
 3682                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3683                .await
 3684            {
 3685                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3686            }
 3687        }
 3688
 3689        Ok(workspace_config)
 3690    }
 3691
 3692    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3693        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3694            Some(server.clone())
 3695        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3696            Some(Arc::clone(server))
 3697        } else {
 3698            None
 3699        }
 3700    }
 3701}
 3702
 3703fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3704    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3705        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3706            language_server_id: server.server_id(),
 3707            name: Some(server.name()),
 3708            message: proto::update_language_server::Variant::MetadataUpdated(
 3709                proto::ServerMetadataUpdated {
 3710                    capabilities: Some(capabilities),
 3711                    binary: Some(proto::LanguageServerBinaryInfo {
 3712                        path: server.binary().path.to_string_lossy().into_owned(),
 3713                        arguments: server
 3714                            .binary()
 3715                            .arguments
 3716                            .iter()
 3717                            .map(|arg| arg.to_string_lossy().into_owned())
 3718                            .collect(),
 3719                    }),
 3720                    configuration: serde_json::to_string(server.configuration()).ok(),
 3721                    workspace_folders: server
 3722                        .workspace_folders()
 3723                        .iter()
 3724                        .map(|uri| uri.to_string())
 3725                        .collect(),
 3726                },
 3727            ),
 3728        });
 3729    }
 3730}
 3731
 3732#[derive(Debug)]
 3733pub struct FormattableBuffer {
 3734    handle: Entity<Buffer>,
 3735    abs_path: Option<PathBuf>,
 3736    env: Option<HashMap<String, String>>,
 3737    ranges: Option<Vec<Range<Anchor>>>,
 3738}
 3739
 3740pub struct RemoteLspStore {
 3741    upstream_client: Option<AnyProtoClient>,
 3742    upstream_project_id: u64,
 3743}
 3744
 3745pub(crate) enum LspStoreMode {
 3746    Local(LocalLspStore),   // ssh host and collab host
 3747    Remote(RemoteLspStore), // collab guest
 3748}
 3749
 3750impl LspStoreMode {
 3751    fn is_local(&self) -> bool {
 3752        matches!(self, LspStoreMode::Local(_))
 3753    }
 3754}
 3755
 3756pub struct LspStore {
 3757    mode: LspStoreMode,
 3758    last_formatting_failure: Option<String>,
 3759    downstream_client: Option<(AnyProtoClient, u64)>,
 3760    nonce: u128,
 3761    buffer_store: Entity<BufferStore>,
 3762    worktree_store: Entity<WorktreeStore>,
 3763    pub languages: Arc<LanguageRegistry>,
 3764    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3765    active_entry: Option<ProjectEntryId>,
 3766    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3767    _maintain_buffer_languages: Task<()>,
 3768    diagnostic_summaries:
 3769        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3770    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3771    lsp_data: HashMap<BufferId, BufferLspData>,
 3772    next_hint_id: Arc<AtomicUsize>,
 3773}
 3774
 3775#[derive(Debug)]
 3776pub struct BufferLspData {
 3777    buffer_version: Global,
 3778    document_colors: Option<DocumentColorData>,
 3779    code_lens: Option<CodeLensData>,
 3780    inlay_hints: BufferInlayHints,
 3781    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3782    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3783}
 3784
 3785#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3786struct LspKey {
 3787    request_type: TypeId,
 3788    server_queried: Option<LanguageServerId>,
 3789}
 3790
 3791impl BufferLspData {
 3792    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3793        Self {
 3794            buffer_version: buffer.read(cx).version(),
 3795            document_colors: None,
 3796            code_lens: None,
 3797            inlay_hints: BufferInlayHints::new(buffer, cx),
 3798            lsp_requests: HashMap::default(),
 3799            chunk_lsp_requests: HashMap::default(),
 3800        }
 3801    }
 3802
 3803    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3804        if let Some(document_colors) = &mut self.document_colors {
 3805            document_colors.colors.remove(&for_server);
 3806            document_colors.cache_version += 1;
 3807        }
 3808
 3809        if let Some(code_lens) = &mut self.code_lens {
 3810            code_lens.lens.remove(&for_server);
 3811        }
 3812
 3813        self.inlay_hints.remove_server_data(for_server);
 3814    }
 3815
 3816    #[cfg(any(test, feature = "test-support"))]
 3817    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3818        &self.inlay_hints
 3819    }
 3820}
 3821
 3822#[derive(Debug, Default, Clone)]
 3823pub struct DocumentColors {
 3824    pub colors: HashSet<DocumentColor>,
 3825    pub cache_version: Option<usize>,
 3826}
 3827
 3828type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3829type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3830
 3831#[derive(Debug, Default)]
 3832struct DocumentColorData {
 3833    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3834    cache_version: usize,
 3835    colors_update: Option<(Global, DocumentColorTask)>,
 3836}
 3837
 3838#[derive(Debug, Default)]
 3839struct CodeLensData {
 3840    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3841    update: Option<(Global, CodeLensTask)>,
 3842}
 3843
 3844#[derive(Debug)]
 3845pub enum LspStoreEvent {
 3846    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3847    LanguageServerRemoved(LanguageServerId),
 3848    LanguageServerUpdate {
 3849        language_server_id: LanguageServerId,
 3850        name: Option<LanguageServerName>,
 3851        message: proto::update_language_server::Variant,
 3852    },
 3853    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3854    LanguageServerPrompt(LanguageServerPromptRequest),
 3855    LanguageDetected {
 3856        buffer: Entity<Buffer>,
 3857        new_language: Option<Arc<Language>>,
 3858    },
 3859    Notification(String),
 3860    RefreshInlayHints {
 3861        server_id: LanguageServerId,
 3862        request_id: Option<usize>,
 3863    },
 3864    RefreshCodeLens,
 3865    DiagnosticsUpdated {
 3866        server_id: LanguageServerId,
 3867        paths: Vec<ProjectPath>,
 3868    },
 3869    DiskBasedDiagnosticsStarted {
 3870        language_server_id: LanguageServerId,
 3871    },
 3872    DiskBasedDiagnosticsFinished {
 3873        language_server_id: LanguageServerId,
 3874    },
 3875    SnippetEdit {
 3876        buffer_id: BufferId,
 3877        edits: Vec<(lsp::Range, Snippet)>,
 3878        most_recent_edit: clock::Lamport,
 3879    },
 3880    WorkspaceEditApplied(ProjectTransaction),
 3881}
 3882
 3883#[derive(Clone, Debug, Serialize)]
 3884pub struct LanguageServerStatus {
 3885    pub name: LanguageServerName,
 3886    pub server_version: Option<SharedString>,
 3887    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3888    pub has_pending_diagnostic_updates: bool,
 3889    pub progress_tokens: HashSet<ProgressToken>,
 3890    pub worktree: Option<WorktreeId>,
 3891    pub binary: Option<LanguageServerBinary>,
 3892    pub configuration: Option<Value>,
 3893    pub workspace_folders: BTreeSet<Uri>,
 3894}
 3895
 3896#[derive(Clone, Debug)]
 3897struct CoreSymbol {
 3898    pub language_server_name: LanguageServerName,
 3899    pub source_worktree_id: WorktreeId,
 3900    pub source_language_server_id: LanguageServerId,
 3901    pub path: SymbolLocation,
 3902    pub name: String,
 3903    pub kind: lsp::SymbolKind,
 3904    pub range: Range<Unclipped<PointUtf16>>,
 3905}
 3906
 3907#[derive(Clone, Debug, PartialEq, Eq)]
 3908pub enum SymbolLocation {
 3909    InProject(ProjectPath),
 3910    OutsideProject {
 3911        abs_path: Arc<Path>,
 3912        signature: [u8; 32],
 3913    },
 3914}
 3915
 3916impl SymbolLocation {
 3917    fn file_name(&self) -> Option<&str> {
 3918        match self {
 3919            Self::InProject(path) => path.path.file_name(),
 3920            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3921        }
 3922    }
 3923}
 3924
 3925impl LspStore {
 3926    pub fn init(client: &AnyProtoClient) {
 3927        client.add_entity_request_handler(Self::handle_lsp_query);
 3928        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3929        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3930        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3931        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3932        client.add_entity_message_handler(Self::handle_start_language_server);
 3933        client.add_entity_message_handler(Self::handle_update_language_server);
 3934        client.add_entity_message_handler(Self::handle_language_server_log);
 3935        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3936        client.add_entity_request_handler(Self::handle_format_buffers);
 3937        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3938        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3939        client.add_entity_request_handler(Self::handle_apply_code_action);
 3940        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3941        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3942        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3943        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3944        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3945        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3946        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3947        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3948        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3949        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3950        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3951        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3952        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3953        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3954        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3955        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3956        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3957
 3958        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3959        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3960        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3961        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3962        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3963        client.add_entity_request_handler(
 3964            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3965        );
 3966        client.add_entity_request_handler(
 3967            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3968        );
 3969        client.add_entity_request_handler(
 3970            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3971        );
 3972    }
 3973
 3974    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3975        match &self.mode {
 3976            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3977            _ => None,
 3978        }
 3979    }
 3980
 3981    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3982        match &self.mode {
 3983            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3984            _ => None,
 3985        }
 3986    }
 3987
 3988    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3989        match &mut self.mode {
 3990            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3991            _ => None,
 3992        }
 3993    }
 3994
 3995    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3996        match &self.mode {
 3997            LspStoreMode::Remote(RemoteLspStore {
 3998                upstream_client: Some(upstream_client),
 3999                upstream_project_id,
 4000                ..
 4001            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4002
 4003            LspStoreMode::Remote(RemoteLspStore {
 4004                upstream_client: None,
 4005                ..
 4006            }) => None,
 4007            LspStoreMode::Local(_) => None,
 4008        }
 4009    }
 4010
 4011    pub fn new_local(
 4012        buffer_store: Entity<BufferStore>,
 4013        worktree_store: Entity<WorktreeStore>,
 4014        prettier_store: Entity<PrettierStore>,
 4015        toolchain_store: Entity<LocalToolchainStore>,
 4016        environment: Entity<ProjectEnvironment>,
 4017        manifest_tree: Entity<ManifestTree>,
 4018        languages: Arc<LanguageRegistry>,
 4019        http_client: Arc<dyn HttpClient>,
 4020        fs: Arc<dyn Fs>,
 4021        cx: &mut Context<Self>,
 4022    ) -> Self {
 4023        let yarn = YarnPathStore::new(fs.clone(), cx);
 4024        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4025            .detach();
 4026        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4027            .detach();
 4028        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4029            .detach();
 4030        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4031            .detach();
 4032        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4033            .detach();
 4034        subscribe_to_binary_statuses(&languages, cx).detach();
 4035
 4036        let _maintain_workspace_config = {
 4037            let (sender, receiver) = watch::channel();
 4038            (Self::maintain_workspace_config(receiver, cx), sender)
 4039        };
 4040
 4041        Self {
 4042            mode: LspStoreMode::Local(LocalLspStore {
 4043                weak: cx.weak_entity(),
 4044                worktree_store: worktree_store.clone(),
 4045
 4046                supplementary_language_servers: Default::default(),
 4047                languages: languages.clone(),
 4048                language_server_ids: Default::default(),
 4049                language_servers: Default::default(),
 4050                last_workspace_edits_by_language_server: Default::default(),
 4051                language_server_watched_paths: Default::default(),
 4052                language_server_paths_watched_for_rename: Default::default(),
 4053                language_server_dynamic_registrations: Default::default(),
 4054                buffers_being_formatted: Default::default(),
 4055                buffer_snapshots: Default::default(),
 4056                prettier_store,
 4057                environment,
 4058                http_client,
 4059                fs,
 4060                yarn,
 4061                next_diagnostic_group_id: Default::default(),
 4062                diagnostics: Default::default(),
 4063                _subscription: cx.on_app_quit(|this, cx| {
 4064                    this.as_local_mut()
 4065                        .unwrap()
 4066                        .shutdown_language_servers_on_quit(cx)
 4067                }),
 4068                lsp_tree: LanguageServerTree::new(
 4069                    manifest_tree,
 4070                    languages.clone(),
 4071                    toolchain_store.clone(),
 4072                ),
 4073                toolchain_store,
 4074                registered_buffers: HashMap::default(),
 4075                buffers_opened_in_servers: HashMap::default(),
 4076                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4077                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4078                restricted_worktrees_tasks: HashMap::default(),
 4079                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4080                    .manifest_file_names(),
 4081            }),
 4082            last_formatting_failure: None,
 4083            downstream_client: None,
 4084            buffer_store,
 4085            worktree_store,
 4086            languages: languages.clone(),
 4087            language_server_statuses: Default::default(),
 4088            nonce: StdRng::from_os_rng().random(),
 4089            diagnostic_summaries: HashMap::default(),
 4090            lsp_server_capabilities: HashMap::default(),
 4091            lsp_data: HashMap::default(),
 4092            next_hint_id: Arc::default(),
 4093            active_entry: None,
 4094            _maintain_workspace_config,
 4095            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4096        }
 4097    }
 4098
 4099    fn send_lsp_proto_request<R: LspCommand>(
 4100        &self,
 4101        buffer: Entity<Buffer>,
 4102        client: AnyProtoClient,
 4103        upstream_project_id: u64,
 4104        request: R,
 4105        cx: &mut Context<LspStore>,
 4106    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4107        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4108            return Task::ready(Ok(R::Response::default()));
 4109        }
 4110        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4111        cx.spawn(async move |this, cx| {
 4112            let response = client.request(message).await?;
 4113            let this = this.upgrade().context("project dropped")?;
 4114            request
 4115                .response_from_proto(response, this, buffer, cx.clone())
 4116                .await
 4117        })
 4118    }
 4119
 4120    pub(super) fn new_remote(
 4121        buffer_store: Entity<BufferStore>,
 4122        worktree_store: Entity<WorktreeStore>,
 4123        languages: Arc<LanguageRegistry>,
 4124        upstream_client: AnyProtoClient,
 4125        project_id: u64,
 4126        cx: &mut Context<Self>,
 4127    ) -> Self {
 4128        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4129            .detach();
 4130        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4131            .detach();
 4132        subscribe_to_binary_statuses(&languages, cx).detach();
 4133        let _maintain_workspace_config = {
 4134            let (sender, receiver) = watch::channel();
 4135            (Self::maintain_workspace_config(receiver, cx), sender)
 4136        };
 4137        Self {
 4138            mode: LspStoreMode::Remote(RemoteLspStore {
 4139                upstream_client: Some(upstream_client),
 4140                upstream_project_id: project_id,
 4141            }),
 4142            downstream_client: None,
 4143            last_formatting_failure: None,
 4144            buffer_store,
 4145            worktree_store,
 4146            languages: languages.clone(),
 4147            language_server_statuses: Default::default(),
 4148            nonce: StdRng::from_os_rng().random(),
 4149            diagnostic_summaries: HashMap::default(),
 4150            lsp_server_capabilities: HashMap::default(),
 4151            next_hint_id: Arc::default(),
 4152            lsp_data: HashMap::default(),
 4153            active_entry: None,
 4154
 4155            _maintain_workspace_config,
 4156            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4157        }
 4158    }
 4159
 4160    fn on_buffer_store_event(
 4161        &mut self,
 4162        _: Entity<BufferStore>,
 4163        event: &BufferStoreEvent,
 4164        cx: &mut Context<Self>,
 4165    ) {
 4166        match event {
 4167            BufferStoreEvent::BufferAdded(buffer) => {
 4168                self.on_buffer_added(buffer, cx).log_err();
 4169            }
 4170            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4171                let buffer_id = buffer.read(cx).remote_id();
 4172                if let Some(local) = self.as_local_mut()
 4173                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4174                {
 4175                    local.reset_buffer(buffer, old_file, cx);
 4176
 4177                    if local.registered_buffers.contains_key(&buffer_id) {
 4178                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4179                    }
 4180                }
 4181
 4182                self.detect_language_for_buffer(buffer, cx);
 4183                if let Some(local) = self.as_local_mut() {
 4184                    local.initialize_buffer(buffer, cx);
 4185                    if local.registered_buffers.contains_key(&buffer_id) {
 4186                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4187                    }
 4188                }
 4189            }
 4190            _ => {}
 4191        }
 4192    }
 4193
 4194    fn on_worktree_store_event(
 4195        &mut self,
 4196        _: Entity<WorktreeStore>,
 4197        event: &WorktreeStoreEvent,
 4198        cx: &mut Context<Self>,
 4199    ) {
 4200        match event {
 4201            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4202                if !worktree.read(cx).is_local() {
 4203                    return;
 4204                }
 4205                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4206                    worktree::Event::UpdatedEntries(changes) => {
 4207                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4208                    }
 4209                    worktree::Event::UpdatedGitRepositories(_)
 4210                    | worktree::Event::DeletedEntry(_) => {}
 4211                })
 4212                .detach()
 4213            }
 4214            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4215            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4216                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4217            }
 4218            WorktreeStoreEvent::WorktreeReleased(..)
 4219            | WorktreeStoreEvent::WorktreeOrderChanged
 4220            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4221            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4222            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4223        }
 4224    }
 4225
 4226    fn on_prettier_store_event(
 4227        &mut self,
 4228        _: Entity<PrettierStore>,
 4229        event: &PrettierStoreEvent,
 4230        cx: &mut Context<Self>,
 4231    ) {
 4232        match event {
 4233            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4234                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4235            }
 4236            PrettierStoreEvent::LanguageServerAdded {
 4237                new_server_id,
 4238                name,
 4239                prettier_server,
 4240            } => {
 4241                self.register_supplementary_language_server(
 4242                    *new_server_id,
 4243                    name.clone(),
 4244                    prettier_server.clone(),
 4245                    cx,
 4246                );
 4247            }
 4248        }
 4249    }
 4250
 4251    fn on_toolchain_store_event(
 4252        &mut self,
 4253        _: Entity<LocalToolchainStore>,
 4254        event: &ToolchainStoreEvent,
 4255        _: &mut Context<Self>,
 4256    ) {
 4257        if let ToolchainStoreEvent::ToolchainActivated = event {
 4258            self.request_workspace_config_refresh()
 4259        }
 4260    }
 4261
 4262    fn request_workspace_config_refresh(&mut self) {
 4263        *self._maintain_workspace_config.1.borrow_mut() = ();
 4264    }
 4265
 4266    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4267        self.as_local().map(|local| local.prettier_store.clone())
 4268    }
 4269
 4270    fn on_buffer_event(
 4271        &mut self,
 4272        buffer: Entity<Buffer>,
 4273        event: &language::BufferEvent,
 4274        cx: &mut Context<Self>,
 4275    ) {
 4276        match event {
 4277            language::BufferEvent::Edited => {
 4278                self.on_buffer_edited(buffer, cx);
 4279            }
 4280
 4281            language::BufferEvent::Saved => {
 4282                self.on_buffer_saved(buffer, cx);
 4283            }
 4284
 4285            _ => {}
 4286        }
 4287    }
 4288
 4289    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4290        buffer
 4291            .read(cx)
 4292            .set_language_registry(self.languages.clone());
 4293
 4294        cx.subscribe(buffer, |this, buffer, event, cx| {
 4295            this.on_buffer_event(buffer, event, cx);
 4296        })
 4297        .detach();
 4298
 4299        self.detect_language_for_buffer(buffer, cx);
 4300        if let Some(local) = self.as_local_mut() {
 4301            local.initialize_buffer(buffer, cx);
 4302        }
 4303
 4304        Ok(())
 4305    }
 4306
 4307    pub(crate) fn register_buffer_with_language_servers(
 4308        &mut self,
 4309        buffer: &Entity<Buffer>,
 4310        only_register_servers: HashSet<LanguageServerSelector>,
 4311        ignore_refcounts: bool,
 4312        cx: &mut Context<Self>,
 4313    ) -> OpenLspBufferHandle {
 4314        let buffer_id = buffer.read(cx).remote_id();
 4315        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4316        if let Some(local) = self.as_local_mut() {
 4317            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4318            if !ignore_refcounts {
 4319                *refcount += 1;
 4320            }
 4321
 4322            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4323            // 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
 4324            // 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
 4325            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4326            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4327                return handle;
 4328            };
 4329            if !file.is_local() {
 4330                return handle;
 4331            }
 4332
 4333            if ignore_refcounts || *refcount == 1 {
 4334                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4335            }
 4336            if !ignore_refcounts {
 4337                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4338                    let refcount = {
 4339                        let local = lsp_store.as_local_mut().unwrap();
 4340                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4341                            debug_panic!("bad refcounting");
 4342                            return;
 4343                        };
 4344
 4345                        *refcount -= 1;
 4346                        *refcount
 4347                    };
 4348                    if refcount == 0 {
 4349                        lsp_store.lsp_data.remove(&buffer_id);
 4350                        let local = lsp_store.as_local_mut().unwrap();
 4351                        local.registered_buffers.remove(&buffer_id);
 4352
 4353                        local.buffers_opened_in_servers.remove(&buffer_id);
 4354                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4355                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4356
 4357                            let buffer_abs_path = file.abs_path(cx);
 4358                            for (_, buffer_pull_diagnostics_result_ids) in
 4359                                &mut local.buffer_pull_diagnostics_result_ids
 4360                            {
 4361                                buffer_pull_diagnostics_result_ids.retain(
 4362                                    |_, buffer_result_ids| {
 4363                                        buffer_result_ids.remove(&buffer_abs_path);
 4364                                        !buffer_result_ids.is_empty()
 4365                                    },
 4366                                );
 4367                            }
 4368
 4369                            let diagnostic_updates = local
 4370                                .language_servers
 4371                                .keys()
 4372                                .cloned()
 4373                                .map(|server_id| DocumentDiagnosticsUpdate {
 4374                                    diagnostics: DocumentDiagnostics {
 4375                                        document_abs_path: buffer_abs_path.clone(),
 4376                                        version: None,
 4377                                        diagnostics: Vec::new(),
 4378                                    },
 4379                                    result_id: None,
 4380                                    registration_id: None,
 4381                                    server_id: server_id,
 4382                                    disk_based_sources: Cow::Borrowed(&[]),
 4383                                })
 4384                                .collect::<Vec<_>>();
 4385
 4386                            lsp_store
 4387                                .merge_diagnostic_entries(
 4388                                    diagnostic_updates,
 4389                                    |_, diagnostic, _| {
 4390                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4391                                    },
 4392                                    cx,
 4393                                )
 4394                                .context("Clearing diagnostics for the closed buffer")
 4395                                .log_err();
 4396                        }
 4397                    }
 4398                })
 4399                .detach();
 4400            }
 4401        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4402            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4403            cx.background_spawn(async move {
 4404                upstream_client
 4405                    .request(proto::RegisterBufferWithLanguageServers {
 4406                        project_id: upstream_project_id,
 4407                        buffer_id,
 4408                        only_servers: only_register_servers
 4409                            .into_iter()
 4410                            .map(|selector| {
 4411                                let selector = match selector {
 4412                                    LanguageServerSelector::Id(language_server_id) => {
 4413                                        proto::language_server_selector::Selector::ServerId(
 4414                                            language_server_id.to_proto(),
 4415                                        )
 4416                                    }
 4417                                    LanguageServerSelector::Name(language_server_name) => {
 4418                                        proto::language_server_selector::Selector::Name(
 4419                                            language_server_name.to_string(),
 4420                                        )
 4421                                    }
 4422                                };
 4423                                proto::LanguageServerSelector {
 4424                                    selector: Some(selector),
 4425                                }
 4426                            })
 4427                            .collect(),
 4428                    })
 4429                    .await
 4430            })
 4431            .detach();
 4432        } else {
 4433            // Our remote connection got closed
 4434        }
 4435        handle
 4436    }
 4437
 4438    fn maintain_buffer_languages(
 4439        languages: Arc<LanguageRegistry>,
 4440        cx: &mut Context<Self>,
 4441    ) -> Task<()> {
 4442        let mut subscription = languages.subscribe();
 4443        let mut prev_reload_count = languages.reload_count();
 4444        cx.spawn(async move |this, cx| {
 4445            while let Some(()) = subscription.next().await {
 4446                if let Some(this) = this.upgrade() {
 4447                    // If the language registry has been reloaded, then remove and
 4448                    // re-assign the languages on all open buffers.
 4449                    let reload_count = languages.reload_count();
 4450                    if reload_count > prev_reload_count {
 4451                        prev_reload_count = reload_count;
 4452                        this.update(cx, |this, cx| {
 4453                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4454                                for buffer in buffer_store.buffers() {
 4455                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4456                                    {
 4457                                        buffer.update(cx, |buffer, cx| {
 4458                                            buffer.set_language_async(None, cx)
 4459                                        });
 4460                                        if let Some(local) = this.as_local_mut() {
 4461                                            local.reset_buffer(&buffer, &f, cx);
 4462
 4463                                            if local
 4464                                                .registered_buffers
 4465                                                .contains_key(&buffer.read(cx).remote_id())
 4466                                                && let Some(file_url) =
 4467                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4468                                            {
 4469                                                local.unregister_buffer_from_language_servers(
 4470                                                    &buffer, &file_url, cx,
 4471                                                );
 4472                                            }
 4473                                        }
 4474                                    }
 4475                                }
 4476                            });
 4477                        });
 4478                    }
 4479
 4480                    this.update(cx, |this, cx| {
 4481                        let mut plain_text_buffers = Vec::new();
 4482                        let mut buffers_with_unknown_injections = Vec::new();
 4483                        for handle in this.buffer_store.read(cx).buffers() {
 4484                            let buffer = handle.read(cx);
 4485                            if buffer.language().is_none()
 4486                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4487                            {
 4488                                plain_text_buffers.push(handle);
 4489                            } else if buffer.contains_unknown_injections() {
 4490                                buffers_with_unknown_injections.push(handle);
 4491                            }
 4492                        }
 4493
 4494                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4495                        // and reused later in the invisible worktrees.
 4496                        plain_text_buffers.sort_by_key(|buffer| {
 4497                            Reverse(
 4498                                File::from_dyn(buffer.read(cx).file())
 4499                                    .map(|file| file.worktree.read(cx).is_visible()),
 4500                            )
 4501                        });
 4502
 4503                        for buffer in plain_text_buffers {
 4504                            this.detect_language_for_buffer(&buffer, cx);
 4505                            if let Some(local) = this.as_local_mut() {
 4506                                local.initialize_buffer(&buffer, cx);
 4507                                if local
 4508                                    .registered_buffers
 4509                                    .contains_key(&buffer.read(cx).remote_id())
 4510                                {
 4511                                    local.register_buffer_with_language_servers(
 4512                                        &buffer,
 4513                                        HashSet::default(),
 4514                                        cx,
 4515                                    );
 4516                                }
 4517                            }
 4518                        }
 4519
 4520                        for buffer in buffers_with_unknown_injections {
 4521                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4522                        }
 4523                    });
 4524                }
 4525            }
 4526        })
 4527    }
 4528
 4529    fn detect_language_for_buffer(
 4530        &mut self,
 4531        buffer_handle: &Entity<Buffer>,
 4532        cx: &mut Context<Self>,
 4533    ) -> Option<language::AvailableLanguage> {
 4534        // If the buffer has a language, set it and start the language server if we haven't already.
 4535        let buffer = buffer_handle.read(cx);
 4536        let file = buffer.file()?;
 4537
 4538        let content = buffer.as_rope();
 4539        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4540        if let Some(available_language) = &available_language {
 4541            if let Some(Ok(Ok(new_language))) = self
 4542                .languages
 4543                .load_language(available_language)
 4544                .now_or_never()
 4545            {
 4546                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4547            }
 4548        } else {
 4549            cx.emit(LspStoreEvent::LanguageDetected {
 4550                buffer: buffer_handle.clone(),
 4551                new_language: None,
 4552            });
 4553        }
 4554
 4555        available_language
 4556    }
 4557
 4558    pub(crate) fn set_language_for_buffer(
 4559        &mut self,
 4560        buffer_entity: &Entity<Buffer>,
 4561        new_language: Arc<Language>,
 4562        cx: &mut Context<Self>,
 4563    ) {
 4564        let buffer = buffer_entity.read(cx);
 4565        let buffer_file = buffer.file().cloned();
 4566        let buffer_id = buffer.remote_id();
 4567        if let Some(local_store) = self.as_local_mut()
 4568            && local_store.registered_buffers.contains_key(&buffer_id)
 4569            && let Some(abs_path) =
 4570                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4571            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4572        {
 4573            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4574        }
 4575        buffer_entity.update(cx, |buffer, cx| {
 4576            if buffer
 4577                .language()
 4578                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4579            {
 4580                buffer.set_language_async(Some(new_language.clone()), cx);
 4581            }
 4582        });
 4583
 4584        let settings =
 4585            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4586        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4587
 4588        let worktree_id = if let Some(file) = buffer_file {
 4589            let worktree = file.worktree.clone();
 4590
 4591            if let Some(local) = self.as_local_mut()
 4592                && local.registered_buffers.contains_key(&buffer_id)
 4593            {
 4594                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4595            }
 4596            Some(worktree.read(cx).id())
 4597        } else {
 4598            None
 4599        };
 4600
 4601        if settings.prettier.allowed
 4602            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4603        {
 4604            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4605            if let Some(prettier_store) = prettier_store {
 4606                prettier_store.update(cx, |prettier_store, cx| {
 4607                    prettier_store.install_default_prettier(
 4608                        worktree_id,
 4609                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4610                        cx,
 4611                    )
 4612                })
 4613            }
 4614        }
 4615
 4616        cx.emit(LspStoreEvent::LanguageDetected {
 4617            buffer: buffer_entity.clone(),
 4618            new_language: Some(new_language),
 4619        })
 4620    }
 4621
 4622    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4623        self.buffer_store.clone()
 4624    }
 4625
 4626    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4627        self.active_entry = active_entry;
 4628    }
 4629
 4630    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4631        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4632            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4633        {
 4634            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4635                summaries
 4636                    .iter()
 4637                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4638            });
 4639            if let Some(summary) = summaries.next() {
 4640                client
 4641                    .send(proto::UpdateDiagnosticSummary {
 4642                        project_id: downstream_project_id,
 4643                        worktree_id: worktree.id().to_proto(),
 4644                        summary: Some(summary),
 4645                        more_summaries: summaries.collect(),
 4646                    })
 4647                    .log_err();
 4648            }
 4649        }
 4650    }
 4651
 4652    fn is_capable_for_proto_request<R>(
 4653        &self,
 4654        buffer: &Entity<Buffer>,
 4655        request: &R,
 4656        cx: &App,
 4657    ) -> bool
 4658    where
 4659        R: LspCommand,
 4660    {
 4661        self.check_if_capable_for_proto_request(
 4662            buffer,
 4663            |capabilities| {
 4664                request.check_capabilities(AdapterServerCapabilities {
 4665                    server_capabilities: capabilities.clone(),
 4666                    code_action_kinds: None,
 4667                })
 4668            },
 4669            cx,
 4670        )
 4671    }
 4672
 4673    fn check_if_capable_for_proto_request<F>(
 4674        &self,
 4675        buffer: &Entity<Buffer>,
 4676        check: F,
 4677        cx: &App,
 4678    ) -> bool
 4679    where
 4680        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4681    {
 4682        let Some(language) = buffer.read(cx).language().cloned() else {
 4683            return false;
 4684        };
 4685        let registered_language_servers = self
 4686            .languages
 4687            .lsp_adapters(&language.name())
 4688            .into_iter()
 4689            .map(|lsp_adapter| lsp_adapter.name())
 4690            .collect::<HashSet<_>>();
 4691        self.language_server_statuses
 4692            .iter()
 4693            .filter_map(|(server_id, server_status)| {
 4694                // Include servers that are either registered for this language OR
 4695                // available to be loaded (for SSH remote mode where adapters like
 4696                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4697                // but only loaded on the server side)
 4698                let is_relevant = registered_language_servers.contains(&server_status.name)
 4699                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4700                is_relevant.then_some(server_id)
 4701            })
 4702            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4703            .any(check)
 4704    }
 4705
 4706    fn all_capable_for_proto_request<F>(
 4707        &self,
 4708        buffer: &Entity<Buffer>,
 4709        mut check: F,
 4710        cx: &App,
 4711    ) -> Vec<lsp::LanguageServerId>
 4712    where
 4713        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4714    {
 4715        let Some(language) = buffer.read(cx).language().cloned() else {
 4716            return Vec::default();
 4717        };
 4718        let registered_language_servers = self
 4719            .languages
 4720            .lsp_adapters(&language.name())
 4721            .into_iter()
 4722            .map(|lsp_adapter| lsp_adapter.name())
 4723            .collect::<HashSet<_>>();
 4724        self.language_server_statuses
 4725            .iter()
 4726            .filter_map(|(server_id, server_status)| {
 4727                // Include servers that are either registered for this language OR
 4728                // available to be loaded (for SSH remote mode where adapters like
 4729                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4730                // but only loaded on the server side)
 4731                let is_relevant = registered_language_servers.contains(&server_status.name)
 4732                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4733                is_relevant.then_some((server_id, &server_status.name))
 4734            })
 4735            .filter_map(|(server_id, server_name)| {
 4736                self.lsp_server_capabilities
 4737                    .get(server_id)
 4738                    .map(|c| (server_id, server_name, c))
 4739            })
 4740            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4741            .map(|(server_id, _, _)| *server_id)
 4742            .collect()
 4743    }
 4744
 4745    pub fn request_lsp<R>(
 4746        &mut self,
 4747        buffer: Entity<Buffer>,
 4748        server: LanguageServerToQuery,
 4749        request: R,
 4750        cx: &mut Context<Self>,
 4751    ) -> Task<Result<R::Response>>
 4752    where
 4753        R: LspCommand,
 4754        <R::LspRequest as lsp::request::Request>::Result: Send,
 4755        <R::LspRequest as lsp::request::Request>::Params: Send,
 4756    {
 4757        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4758            return self.send_lsp_proto_request(
 4759                buffer,
 4760                upstream_client,
 4761                upstream_project_id,
 4762                request,
 4763                cx,
 4764            );
 4765        }
 4766
 4767        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4768            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4769                local
 4770                    .language_servers_for_buffer(buffer, cx)
 4771                    .find(|(_, server)| {
 4772                        request.check_capabilities(server.adapter_server_capabilities())
 4773                    })
 4774                    .map(|(_, server)| server.clone())
 4775            }),
 4776            LanguageServerToQuery::Other(id) => self
 4777                .language_server_for_local_buffer(buffer, id, cx)
 4778                .and_then(|(_, server)| {
 4779                    request
 4780                        .check_capabilities(server.adapter_server_capabilities())
 4781                        .then(|| Arc::clone(server))
 4782                }),
 4783        }) else {
 4784            return Task::ready(Ok(Default::default()));
 4785        };
 4786
 4787        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4788
 4789        let Some(file) = file else {
 4790            return Task::ready(Ok(Default::default()));
 4791        };
 4792
 4793        let lsp_params = match request.to_lsp_params_or_response(
 4794            &file.abs_path(cx),
 4795            buffer.read(cx),
 4796            &language_server,
 4797            cx,
 4798        ) {
 4799            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4800            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4801            Err(err) => {
 4802                let message = format!(
 4803                    "{} via {} failed: {}",
 4804                    request.display_name(),
 4805                    language_server.name(),
 4806                    err
 4807                );
 4808                // rust-analyzer likes to error with this when its still loading up
 4809                if !message.ends_with("content modified") {
 4810                    log::warn!("{message}");
 4811                }
 4812                return Task::ready(Err(anyhow!(message)));
 4813            }
 4814        };
 4815
 4816        let status = request.status();
 4817        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4818            return Task::ready(Ok(Default::default()));
 4819        }
 4820        cx.spawn(async move |this, cx| {
 4821            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4822
 4823            let id = lsp_request.id();
 4824            let _cleanup = if status.is_some() {
 4825                cx.update(|cx| {
 4826                    this.update(cx, |this, cx| {
 4827                        this.on_lsp_work_start(
 4828                            language_server.server_id(),
 4829                            ProgressToken::Number(id),
 4830                            LanguageServerProgress {
 4831                                is_disk_based_diagnostics_progress: false,
 4832                                is_cancellable: false,
 4833                                title: None,
 4834                                message: status.clone(),
 4835                                percentage: None,
 4836                                last_update_at: cx.background_executor().now(),
 4837                            },
 4838                            cx,
 4839                        );
 4840                    })
 4841                })
 4842                .log_err();
 4843
 4844                Some(defer(|| {
 4845                    cx.update(|cx| {
 4846                        this.update(cx, |this, cx| {
 4847                            this.on_lsp_work_end(
 4848                                language_server.server_id(),
 4849                                ProgressToken::Number(id),
 4850                                cx,
 4851                            );
 4852                        })
 4853                    })
 4854                    .log_err();
 4855                }))
 4856            } else {
 4857                None
 4858            };
 4859
 4860            let result = lsp_request.await.into_response();
 4861
 4862            let response = result.map_err(|err| {
 4863                let message = format!(
 4864                    "{} via {} failed: {}",
 4865                    request.display_name(),
 4866                    language_server.name(),
 4867                    err
 4868                );
 4869                // rust-analyzer likes to error with this when its still loading up
 4870                if !message.ends_with("content modified") {
 4871                    log::warn!("{message}");
 4872                }
 4873                anyhow::anyhow!(message)
 4874            })?;
 4875
 4876            request
 4877                .response_from_lsp(
 4878                    response,
 4879                    this.upgrade().context("no app context")?,
 4880                    buffer,
 4881                    language_server.server_id(),
 4882                    cx.clone(),
 4883                )
 4884                .await
 4885        })
 4886    }
 4887
 4888    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4889        let mut language_formatters_to_check = Vec::new();
 4890        for buffer in self.buffer_store.read(cx).buffers() {
 4891            let buffer = buffer.read(cx);
 4892            let buffer_file = File::from_dyn(buffer.file());
 4893            let buffer_language = buffer.language();
 4894            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4895            if buffer_language.is_some() {
 4896                language_formatters_to_check.push((
 4897                    buffer_file.map(|f| f.worktree_id(cx)),
 4898                    settings.into_owned(),
 4899                ));
 4900            }
 4901        }
 4902
 4903        self.request_workspace_config_refresh();
 4904
 4905        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4906            prettier_store.update(cx, |prettier_store, cx| {
 4907                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4908            })
 4909        }
 4910
 4911        cx.notify();
 4912    }
 4913
 4914    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4915        let buffer_store = self.buffer_store.clone();
 4916        let Some(local) = self.as_local_mut() else {
 4917            return;
 4918        };
 4919        let mut adapters = BTreeMap::default();
 4920        let get_adapter = {
 4921            let languages = local.languages.clone();
 4922            let environment = local.environment.clone();
 4923            let weak = local.weak.clone();
 4924            let worktree_store = local.worktree_store.clone();
 4925            let http_client = local.http_client.clone();
 4926            let fs = local.fs.clone();
 4927            move |worktree_id, cx: &mut App| {
 4928                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4929                Some(LocalLspAdapterDelegate::new(
 4930                    languages.clone(),
 4931                    &environment,
 4932                    weak.clone(),
 4933                    &worktree,
 4934                    http_client.clone(),
 4935                    fs.clone(),
 4936                    cx,
 4937                ))
 4938            }
 4939        };
 4940
 4941        let mut messages_to_report = Vec::new();
 4942        let (new_tree, to_stop) = {
 4943            let mut rebase = local.lsp_tree.rebase();
 4944            let buffers = buffer_store
 4945                .read(cx)
 4946                .buffers()
 4947                .filter_map(|buffer| {
 4948                    let raw_buffer = buffer.read(cx);
 4949                    if !local
 4950                        .registered_buffers
 4951                        .contains_key(&raw_buffer.remote_id())
 4952                    {
 4953                        return None;
 4954                    }
 4955                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4956                    let language = raw_buffer.language().cloned()?;
 4957                    Some((file, language, raw_buffer.remote_id()))
 4958                })
 4959                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4960            for (file, language, buffer_id) in buffers {
 4961                let worktree_id = file.worktree_id(cx);
 4962                let Some(worktree) = local
 4963                    .worktree_store
 4964                    .read(cx)
 4965                    .worktree_for_id(worktree_id, cx)
 4966                else {
 4967                    continue;
 4968                };
 4969
 4970                if let Some((_, apply)) = local.reuse_existing_language_server(
 4971                    rebase.server_tree(),
 4972                    &worktree,
 4973                    &language.name(),
 4974                    cx,
 4975                ) {
 4976                    (apply)(rebase.server_tree());
 4977                } else if let Some(lsp_delegate) = adapters
 4978                    .entry(worktree_id)
 4979                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4980                    .clone()
 4981                {
 4982                    let delegate =
 4983                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4984                    let path = file
 4985                        .path()
 4986                        .parent()
 4987                        .map(Arc::from)
 4988                        .unwrap_or_else(|| file.path().clone());
 4989                    let worktree_path = ProjectPath { worktree_id, path };
 4990                    let abs_path = file.abs_path(cx);
 4991                    let nodes = rebase
 4992                        .walk(
 4993                            worktree_path,
 4994                            language.name(),
 4995                            language.manifest(),
 4996                            delegate.clone(),
 4997                            cx,
 4998                        )
 4999                        .collect::<Vec<_>>();
 5000                    for node in nodes {
 5001                        let server_id = node.server_id_or_init(|disposition| {
 5002                            let path = &disposition.path;
 5003                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5004                            let key = LanguageServerSeed {
 5005                                worktree_id,
 5006                                name: disposition.server_name.clone(),
 5007                                settings: disposition.settings.clone(),
 5008                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5009                                    path.worktree_id,
 5010                                    &path.path,
 5011                                    language.name(),
 5012                                ),
 5013                            };
 5014                            local.language_server_ids.remove(&key);
 5015
 5016                            let server_id = local.get_or_insert_language_server(
 5017                                &worktree,
 5018                                lsp_delegate.clone(),
 5019                                disposition,
 5020                                &language.name(),
 5021                                cx,
 5022                            );
 5023                            if let Some(state) = local.language_servers.get(&server_id)
 5024                                && let Ok(uri) = uri
 5025                            {
 5026                                state.add_workspace_folder(uri);
 5027                            };
 5028                            server_id
 5029                        });
 5030
 5031                        if let Some(language_server_id) = server_id {
 5032                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5033                                language_server_id,
 5034                                name: node.name(),
 5035                                message:
 5036                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5037                                        proto::RegisteredForBuffer {
 5038                                            buffer_abs_path: abs_path
 5039                                                .to_string_lossy()
 5040                                                .into_owned(),
 5041                                            buffer_id: buffer_id.to_proto(),
 5042                                        },
 5043                                    ),
 5044                            });
 5045                        }
 5046                    }
 5047                } else {
 5048                    continue;
 5049                }
 5050            }
 5051            rebase.finish()
 5052        };
 5053        for message in messages_to_report {
 5054            cx.emit(message);
 5055        }
 5056        local.lsp_tree = new_tree;
 5057        for (id, _) in to_stop {
 5058            self.stop_local_language_server(id, cx).detach();
 5059        }
 5060    }
 5061
 5062    pub fn apply_code_action(
 5063        &self,
 5064        buffer_handle: Entity<Buffer>,
 5065        mut action: CodeAction,
 5066        push_to_history: bool,
 5067        cx: &mut Context<Self>,
 5068    ) -> Task<Result<ProjectTransaction>> {
 5069        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5070            let request = proto::ApplyCodeAction {
 5071                project_id,
 5072                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5073                action: Some(Self::serialize_code_action(&action)),
 5074            };
 5075            let buffer_store = self.buffer_store();
 5076            cx.spawn(async move |_, cx| {
 5077                let response = upstream_client
 5078                    .request(request)
 5079                    .await?
 5080                    .transaction
 5081                    .context("missing transaction")?;
 5082
 5083                buffer_store
 5084                    .update(cx, |buffer_store, cx| {
 5085                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5086                    })
 5087                    .await
 5088            })
 5089        } else if self.mode.is_local() {
 5090            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 5091                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5092                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 5093            }) else {
 5094                return Task::ready(Ok(ProjectTransaction::default()));
 5095            };
 5096            cx.spawn(async move |this,  cx| {
 5097                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 5098                    .await
 5099                    .context("resolving a code action")?;
 5100                if let Some(edit) = action.lsp_action.edit()
 5101                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5102                        return LocalLspStore::deserialize_workspace_edit(
 5103                            this.upgrade().context("no app present")?,
 5104                            edit.clone(),
 5105                            push_to_history,
 5106
 5107                            lang_server.clone(),
 5108                            cx,
 5109                        )
 5110                        .await;
 5111                    }
 5112
 5113                if let Some(command) = action.lsp_action.command() {
 5114                    let server_capabilities = lang_server.capabilities();
 5115                    let available_commands = server_capabilities
 5116                        .execute_command_provider
 5117                        .as_ref()
 5118                        .map(|options| options.commands.as_slice())
 5119                        .unwrap_or_default();
 5120                    if available_commands.contains(&command.command) {
 5121                        this.update(cx, |this, _| {
 5122                            this.as_local_mut()
 5123                                .unwrap()
 5124                                .last_workspace_edits_by_language_server
 5125                                .remove(&lang_server.server_id());
 5126                        })?;
 5127
 5128                        let _result = lang_server
 5129                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5130                                command: command.command.clone(),
 5131                                arguments: command.arguments.clone().unwrap_or_default(),
 5132                                ..lsp::ExecuteCommandParams::default()
 5133                            })
 5134                            .await.into_response()
 5135                            .context("execute command")?;
 5136
 5137                        return this.update(cx, |this, _| {
 5138                            this.as_local_mut()
 5139                                .unwrap()
 5140                                .last_workspace_edits_by_language_server
 5141                                .remove(&lang_server.server_id())
 5142                                .unwrap_or_default()
 5143                        });
 5144                    } else {
 5145                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5146                    }
 5147                }
 5148
 5149                Ok(ProjectTransaction::default())
 5150            })
 5151        } else {
 5152            Task::ready(Err(anyhow!("no upstream client and not local")))
 5153        }
 5154    }
 5155
 5156    pub fn apply_code_action_kind(
 5157        &mut self,
 5158        buffers: HashSet<Entity<Buffer>>,
 5159        kind: CodeActionKind,
 5160        push_to_history: bool,
 5161        cx: &mut Context<Self>,
 5162    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5163        if self.as_local().is_some() {
 5164            cx.spawn(async move |lsp_store, cx| {
 5165                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5166                let result = LocalLspStore::execute_code_action_kind_locally(
 5167                    lsp_store.clone(),
 5168                    buffers,
 5169                    kind,
 5170                    push_to_history,
 5171                    cx,
 5172                )
 5173                .await;
 5174                lsp_store.update(cx, |lsp_store, _| {
 5175                    lsp_store.update_last_formatting_failure(&result);
 5176                })?;
 5177                result
 5178            })
 5179        } else if let Some((client, project_id)) = self.upstream_client() {
 5180            let buffer_store = self.buffer_store();
 5181            cx.spawn(async move |lsp_store, cx| {
 5182                let result = client
 5183                    .request(proto::ApplyCodeActionKind {
 5184                        project_id,
 5185                        kind: kind.as_str().to_owned(),
 5186                        buffer_ids: buffers
 5187                            .iter()
 5188                            .map(|buffer| {
 5189                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5190                            })
 5191                            .collect(),
 5192                    })
 5193                    .await
 5194                    .and_then(|result| result.transaction.context("missing transaction"));
 5195                lsp_store.update(cx, |lsp_store, _| {
 5196                    lsp_store.update_last_formatting_failure(&result);
 5197                })?;
 5198
 5199                let transaction_response = result?;
 5200                buffer_store
 5201                    .update(cx, |buffer_store, cx| {
 5202                        buffer_store.deserialize_project_transaction(
 5203                            transaction_response,
 5204                            push_to_history,
 5205                            cx,
 5206                        )
 5207                    })
 5208                    .await
 5209            })
 5210        } else {
 5211            Task::ready(Ok(ProjectTransaction::default()))
 5212        }
 5213    }
 5214
 5215    pub fn resolved_hint(
 5216        &mut self,
 5217        buffer_id: BufferId,
 5218        id: InlayId,
 5219        cx: &mut Context<Self>,
 5220    ) -> Option<ResolvedHint> {
 5221        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5222
 5223        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5224        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5225        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5226        let (server_id, resolve_data) = match &hint.resolve_state {
 5227            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5228            ResolveState::Resolving => {
 5229                return Some(ResolvedHint::Resolving(
 5230                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5231                ));
 5232            }
 5233            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5234        };
 5235
 5236        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5237        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5238        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5239            id,
 5240            cx.spawn(async move |lsp_store, cx| {
 5241                let resolved_hint = resolve_task.await;
 5242                lsp_store
 5243                    .update(cx, |lsp_store, _| {
 5244                        if let Some(old_inlay_hint) = lsp_store
 5245                            .lsp_data
 5246                            .get_mut(&buffer_id)
 5247                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5248                        {
 5249                            match resolved_hint {
 5250                                Ok(resolved_hint) => {
 5251                                    *old_inlay_hint = resolved_hint;
 5252                                }
 5253                                Err(e) => {
 5254                                    old_inlay_hint.resolve_state =
 5255                                        ResolveState::CanResolve(server_id, resolve_data);
 5256                                    log::error!("Inlay hint resolve failed: {e:#}");
 5257                                }
 5258                            }
 5259                        }
 5260                    })
 5261                    .ok();
 5262            })
 5263            .shared(),
 5264        );
 5265        debug_assert!(
 5266            previous_task.is_none(),
 5267            "Did not change hint's resolve state after spawning its resolve"
 5268        );
 5269        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5270        None
 5271    }
 5272
 5273    fn resolve_inlay_hint(
 5274        &self,
 5275        mut hint: InlayHint,
 5276        buffer: Entity<Buffer>,
 5277        server_id: LanguageServerId,
 5278        cx: &mut Context<Self>,
 5279    ) -> Task<anyhow::Result<InlayHint>> {
 5280        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5281            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5282            {
 5283                hint.resolve_state = ResolveState::Resolved;
 5284                return Task::ready(Ok(hint));
 5285            }
 5286            let request = proto::ResolveInlayHint {
 5287                project_id,
 5288                buffer_id: buffer.read(cx).remote_id().into(),
 5289                language_server_id: server_id.0 as u64,
 5290                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5291            };
 5292            cx.background_spawn(async move {
 5293                let response = upstream_client
 5294                    .request(request)
 5295                    .await
 5296                    .context("inlay hints proto request")?;
 5297                match response.hint {
 5298                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5299                        .context("inlay hints proto resolve response conversion"),
 5300                    None => Ok(hint),
 5301                }
 5302            })
 5303        } else {
 5304            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5305                self.language_server_for_local_buffer(buffer, server_id, cx)
 5306                    .map(|(_, server)| server.clone())
 5307            }) else {
 5308                return Task::ready(Ok(hint));
 5309            };
 5310            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5311                return Task::ready(Ok(hint));
 5312            }
 5313            let buffer_snapshot = buffer.read(cx).snapshot();
 5314            cx.spawn(async move |_, cx| {
 5315                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5316                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5317                );
 5318                let resolved_hint = resolve_task
 5319                    .await
 5320                    .into_response()
 5321                    .context("inlay hint resolve LSP request")?;
 5322                let resolved_hint = InlayHints::lsp_to_project_hint(
 5323                    resolved_hint,
 5324                    &buffer,
 5325                    server_id,
 5326                    ResolveState::Resolved,
 5327                    false,
 5328                    cx,
 5329                )
 5330                .await?;
 5331                Ok(resolved_hint)
 5332            })
 5333        }
 5334    }
 5335
 5336    pub fn resolve_color_presentation(
 5337        &mut self,
 5338        mut color: DocumentColor,
 5339        buffer: Entity<Buffer>,
 5340        server_id: LanguageServerId,
 5341        cx: &mut Context<Self>,
 5342    ) -> Task<Result<DocumentColor>> {
 5343        if color.resolved {
 5344            return Task::ready(Ok(color));
 5345        }
 5346
 5347        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5348            let start = color.lsp_range.start;
 5349            let end = color.lsp_range.end;
 5350            let request = proto::GetColorPresentation {
 5351                project_id,
 5352                server_id: server_id.to_proto(),
 5353                buffer_id: buffer.read(cx).remote_id().into(),
 5354                color: Some(proto::ColorInformation {
 5355                    red: color.color.red,
 5356                    green: color.color.green,
 5357                    blue: color.color.blue,
 5358                    alpha: color.color.alpha,
 5359                    lsp_range_start: Some(proto::PointUtf16 {
 5360                        row: start.line,
 5361                        column: start.character,
 5362                    }),
 5363                    lsp_range_end: Some(proto::PointUtf16 {
 5364                        row: end.line,
 5365                        column: end.character,
 5366                    }),
 5367                }),
 5368            };
 5369            cx.background_spawn(async move {
 5370                let response = upstream_client
 5371                    .request(request)
 5372                    .await
 5373                    .context("color presentation proto request")?;
 5374                color.resolved = true;
 5375                color.color_presentations = response
 5376                    .presentations
 5377                    .into_iter()
 5378                    .map(|presentation| ColorPresentation {
 5379                        label: SharedString::from(presentation.label),
 5380                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5381                        additional_text_edits: presentation
 5382                            .additional_text_edits
 5383                            .into_iter()
 5384                            .filter_map(deserialize_lsp_edit)
 5385                            .collect(),
 5386                    })
 5387                    .collect();
 5388                Ok(color)
 5389            })
 5390        } else {
 5391            let path = match buffer
 5392                .update(cx, |buffer, cx| {
 5393                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5394                })
 5395                .context("buffer with the missing path")
 5396            {
 5397                Ok(path) => path,
 5398                Err(e) => return Task::ready(Err(e)),
 5399            };
 5400            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5401                self.language_server_for_local_buffer(buffer, server_id, cx)
 5402                    .map(|(_, server)| server.clone())
 5403            }) else {
 5404                return Task::ready(Ok(color));
 5405            };
 5406            cx.background_spawn(async move {
 5407                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5408                    lsp::ColorPresentationParams {
 5409                        text_document: make_text_document_identifier(&path)?,
 5410                        color: color.color,
 5411                        range: color.lsp_range,
 5412                        work_done_progress_params: Default::default(),
 5413                        partial_result_params: Default::default(),
 5414                    },
 5415                );
 5416                color.color_presentations = resolve_task
 5417                    .await
 5418                    .into_response()
 5419                    .context("color presentation resolve LSP request")?
 5420                    .into_iter()
 5421                    .map(|presentation| ColorPresentation {
 5422                        label: SharedString::from(presentation.label),
 5423                        text_edit: presentation.text_edit,
 5424                        additional_text_edits: presentation
 5425                            .additional_text_edits
 5426                            .unwrap_or_default(),
 5427                    })
 5428                    .collect();
 5429                color.resolved = true;
 5430                Ok(color)
 5431            })
 5432        }
 5433    }
 5434
 5435    pub(crate) fn linked_edits(
 5436        &mut self,
 5437        buffer: &Entity<Buffer>,
 5438        position: Anchor,
 5439        cx: &mut Context<Self>,
 5440    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5441        let snapshot = buffer.read(cx).snapshot();
 5442        let scope = snapshot.language_scope_at(position);
 5443        let Some(server_id) = self
 5444            .as_local()
 5445            .and_then(|local| {
 5446                buffer.update(cx, |buffer, cx| {
 5447                    local
 5448                        .language_servers_for_buffer(buffer, cx)
 5449                        .filter(|(_, server)| {
 5450                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5451                        })
 5452                        .filter(|(adapter, _)| {
 5453                            scope
 5454                                .as_ref()
 5455                                .map(|scope| scope.language_allowed(&adapter.name))
 5456                                .unwrap_or(true)
 5457                        })
 5458                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5459                        .next()
 5460                })
 5461            })
 5462            .or_else(|| {
 5463                self.upstream_client()
 5464                    .is_some()
 5465                    .then_some(LanguageServerToQuery::FirstCapable)
 5466            })
 5467            .filter(|_| {
 5468                maybe!({
 5469                    let language = buffer.read(cx).language_at(position)?;
 5470                    Some(
 5471                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5472                            .linked_edits,
 5473                    )
 5474                }) == Some(true)
 5475            })
 5476        else {
 5477            return Task::ready(Ok(Vec::new()));
 5478        };
 5479
 5480        self.request_lsp(
 5481            buffer.clone(),
 5482            server_id,
 5483            LinkedEditingRange { position },
 5484            cx,
 5485        )
 5486    }
 5487
 5488    fn apply_on_type_formatting(
 5489        &mut self,
 5490        buffer: Entity<Buffer>,
 5491        position: Anchor,
 5492        trigger: String,
 5493        cx: &mut Context<Self>,
 5494    ) -> Task<Result<Option<Transaction>>> {
 5495        if let Some((client, project_id)) = self.upstream_client() {
 5496            if !self.check_if_capable_for_proto_request(
 5497                &buffer,
 5498                |capabilities| {
 5499                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5500                },
 5501                cx,
 5502            ) {
 5503                return Task::ready(Ok(None));
 5504            }
 5505            let request = proto::OnTypeFormatting {
 5506                project_id,
 5507                buffer_id: buffer.read(cx).remote_id().into(),
 5508                position: Some(serialize_anchor(&position)),
 5509                trigger,
 5510                version: serialize_version(&buffer.read(cx).version()),
 5511            };
 5512            cx.background_spawn(async move {
 5513                client
 5514                    .request(request)
 5515                    .await?
 5516                    .transaction
 5517                    .map(language::proto::deserialize_transaction)
 5518                    .transpose()
 5519            })
 5520        } else if let Some(local) = self.as_local_mut() {
 5521            let buffer_id = buffer.read(cx).remote_id();
 5522            local.buffers_being_formatted.insert(buffer_id);
 5523            cx.spawn(async move |this, cx| {
 5524                let _cleanup = defer({
 5525                    let this = this.clone();
 5526                    let mut cx = cx.clone();
 5527                    move || {
 5528                        this.update(&mut cx, |this, _| {
 5529                            if let Some(local) = this.as_local_mut() {
 5530                                local.buffers_being_formatted.remove(&buffer_id);
 5531                            }
 5532                        })
 5533                        .ok();
 5534                    }
 5535                });
 5536
 5537                buffer
 5538                    .update(cx, |buffer, _| {
 5539                        buffer.wait_for_edits(Some(position.timestamp))
 5540                    })
 5541                    .await?;
 5542                this.update(cx, |this, cx| {
 5543                    let position = position.to_point_utf16(buffer.read(cx));
 5544                    this.on_type_format(buffer, position, trigger, false, cx)
 5545                })?
 5546                .await
 5547            })
 5548        } else {
 5549            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5550        }
 5551    }
 5552
 5553    pub fn on_type_format<T: ToPointUtf16>(
 5554        &mut self,
 5555        buffer: Entity<Buffer>,
 5556        position: T,
 5557        trigger: String,
 5558        push_to_history: bool,
 5559        cx: &mut Context<Self>,
 5560    ) -> Task<Result<Option<Transaction>>> {
 5561        let position = position.to_point_utf16(buffer.read(cx));
 5562        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5563    }
 5564
 5565    fn on_type_format_impl(
 5566        &mut self,
 5567        buffer: Entity<Buffer>,
 5568        position: PointUtf16,
 5569        trigger: String,
 5570        push_to_history: bool,
 5571        cx: &mut Context<Self>,
 5572    ) -> Task<Result<Option<Transaction>>> {
 5573        let options = buffer.update(cx, |buffer, cx| {
 5574            lsp_command::lsp_formatting_options(
 5575                language_settings(
 5576                    buffer.language_at(position).map(|l| l.name()),
 5577                    buffer.file(),
 5578                    cx,
 5579                )
 5580                .as_ref(),
 5581            )
 5582        });
 5583
 5584        cx.spawn(async move |this, cx| {
 5585            if let Some(waiter) =
 5586                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5587            {
 5588                waiter.await?;
 5589            }
 5590            cx.update(|cx| {
 5591                this.update(cx, |this, cx| {
 5592                    this.request_lsp(
 5593                        buffer.clone(),
 5594                        LanguageServerToQuery::FirstCapable,
 5595                        OnTypeFormatting {
 5596                            position,
 5597                            trigger,
 5598                            options,
 5599                            push_to_history,
 5600                        },
 5601                        cx,
 5602                    )
 5603                })
 5604            })?
 5605            .await
 5606        })
 5607    }
 5608
 5609    pub fn definitions(
 5610        &mut self,
 5611        buffer: &Entity<Buffer>,
 5612        position: PointUtf16,
 5613        cx: &mut Context<Self>,
 5614    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5615        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5616            let request = GetDefinitions { position };
 5617            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5618                return Task::ready(Ok(None));
 5619            }
 5620            let request_task = upstream_client.request_lsp(
 5621                project_id,
 5622                None,
 5623                LSP_REQUEST_TIMEOUT,
 5624                cx.background_executor().clone(),
 5625                request.to_proto(project_id, buffer.read(cx)),
 5626            );
 5627            let buffer = buffer.clone();
 5628            cx.spawn(async move |weak_lsp_store, cx| {
 5629                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5630                    return Ok(None);
 5631                };
 5632                let Some(responses) = request_task.await? else {
 5633                    return Ok(None);
 5634                };
 5635                let actions = join_all(responses.payload.into_iter().map(|response| {
 5636                    GetDefinitions { position }.response_from_proto(
 5637                        response.response,
 5638                        lsp_store.clone(),
 5639                        buffer.clone(),
 5640                        cx.clone(),
 5641                    )
 5642                }))
 5643                .await;
 5644
 5645                Ok(Some(
 5646                    actions
 5647                        .into_iter()
 5648                        .collect::<Result<Vec<Vec<_>>>>()?
 5649                        .into_iter()
 5650                        .flatten()
 5651                        .dedup()
 5652                        .collect(),
 5653                ))
 5654            })
 5655        } else {
 5656            let definitions_task = self.request_multiple_lsp_locally(
 5657                buffer,
 5658                Some(position),
 5659                GetDefinitions { position },
 5660                cx,
 5661            );
 5662            cx.background_spawn(async move {
 5663                Ok(Some(
 5664                    definitions_task
 5665                        .await
 5666                        .into_iter()
 5667                        .flat_map(|(_, definitions)| definitions)
 5668                        .dedup()
 5669                        .collect(),
 5670                ))
 5671            })
 5672        }
 5673    }
 5674
 5675    pub fn declarations(
 5676        &mut self,
 5677        buffer: &Entity<Buffer>,
 5678        position: PointUtf16,
 5679        cx: &mut Context<Self>,
 5680    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5681        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5682            let request = GetDeclarations { position };
 5683            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5684                return Task::ready(Ok(None));
 5685            }
 5686            let request_task = upstream_client.request_lsp(
 5687                project_id,
 5688                None,
 5689                LSP_REQUEST_TIMEOUT,
 5690                cx.background_executor().clone(),
 5691                request.to_proto(project_id, buffer.read(cx)),
 5692            );
 5693            let buffer = buffer.clone();
 5694            cx.spawn(async move |weak_lsp_store, cx| {
 5695                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5696                    return Ok(None);
 5697                };
 5698                let Some(responses) = request_task.await? else {
 5699                    return Ok(None);
 5700                };
 5701                let actions = join_all(responses.payload.into_iter().map(|response| {
 5702                    GetDeclarations { position }.response_from_proto(
 5703                        response.response,
 5704                        lsp_store.clone(),
 5705                        buffer.clone(),
 5706                        cx.clone(),
 5707                    )
 5708                }))
 5709                .await;
 5710
 5711                Ok(Some(
 5712                    actions
 5713                        .into_iter()
 5714                        .collect::<Result<Vec<Vec<_>>>>()?
 5715                        .into_iter()
 5716                        .flatten()
 5717                        .dedup()
 5718                        .collect(),
 5719                ))
 5720            })
 5721        } else {
 5722            let declarations_task = self.request_multiple_lsp_locally(
 5723                buffer,
 5724                Some(position),
 5725                GetDeclarations { position },
 5726                cx,
 5727            );
 5728            cx.background_spawn(async move {
 5729                Ok(Some(
 5730                    declarations_task
 5731                        .await
 5732                        .into_iter()
 5733                        .flat_map(|(_, declarations)| declarations)
 5734                        .dedup()
 5735                        .collect(),
 5736                ))
 5737            })
 5738        }
 5739    }
 5740
 5741    pub fn type_definitions(
 5742        &mut self,
 5743        buffer: &Entity<Buffer>,
 5744        position: PointUtf16,
 5745        cx: &mut Context<Self>,
 5746    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5747        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5748            let request = GetTypeDefinitions { position };
 5749            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5750                return Task::ready(Ok(None));
 5751            }
 5752            let request_task = upstream_client.request_lsp(
 5753                project_id,
 5754                None,
 5755                LSP_REQUEST_TIMEOUT,
 5756                cx.background_executor().clone(),
 5757                request.to_proto(project_id, buffer.read(cx)),
 5758            );
 5759            let buffer = buffer.clone();
 5760            cx.spawn(async move |weak_lsp_store, cx| {
 5761                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5762                    return Ok(None);
 5763                };
 5764                let Some(responses) = request_task.await? else {
 5765                    return Ok(None);
 5766                };
 5767                let actions = join_all(responses.payload.into_iter().map(|response| {
 5768                    GetTypeDefinitions { position }.response_from_proto(
 5769                        response.response,
 5770                        lsp_store.clone(),
 5771                        buffer.clone(),
 5772                        cx.clone(),
 5773                    )
 5774                }))
 5775                .await;
 5776
 5777                Ok(Some(
 5778                    actions
 5779                        .into_iter()
 5780                        .collect::<Result<Vec<Vec<_>>>>()?
 5781                        .into_iter()
 5782                        .flatten()
 5783                        .dedup()
 5784                        .collect(),
 5785                ))
 5786            })
 5787        } else {
 5788            let type_definitions_task = self.request_multiple_lsp_locally(
 5789                buffer,
 5790                Some(position),
 5791                GetTypeDefinitions { position },
 5792                cx,
 5793            );
 5794            cx.background_spawn(async move {
 5795                Ok(Some(
 5796                    type_definitions_task
 5797                        .await
 5798                        .into_iter()
 5799                        .flat_map(|(_, type_definitions)| type_definitions)
 5800                        .dedup()
 5801                        .collect(),
 5802                ))
 5803            })
 5804        }
 5805    }
 5806
 5807    pub fn implementations(
 5808        &mut self,
 5809        buffer: &Entity<Buffer>,
 5810        position: PointUtf16,
 5811        cx: &mut Context<Self>,
 5812    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5813        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5814            let request = GetImplementations { position };
 5815            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5816                return Task::ready(Ok(None));
 5817            }
 5818            let request_task = upstream_client.request_lsp(
 5819                project_id,
 5820                None,
 5821                LSP_REQUEST_TIMEOUT,
 5822                cx.background_executor().clone(),
 5823                request.to_proto(project_id, buffer.read(cx)),
 5824            );
 5825            let buffer = buffer.clone();
 5826            cx.spawn(async move |weak_lsp_store, cx| {
 5827                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5828                    return Ok(None);
 5829                };
 5830                let Some(responses) = request_task.await? else {
 5831                    return Ok(None);
 5832                };
 5833                let actions = join_all(responses.payload.into_iter().map(|response| {
 5834                    GetImplementations { position }.response_from_proto(
 5835                        response.response,
 5836                        lsp_store.clone(),
 5837                        buffer.clone(),
 5838                        cx.clone(),
 5839                    )
 5840                }))
 5841                .await;
 5842
 5843                Ok(Some(
 5844                    actions
 5845                        .into_iter()
 5846                        .collect::<Result<Vec<Vec<_>>>>()?
 5847                        .into_iter()
 5848                        .flatten()
 5849                        .dedup()
 5850                        .collect(),
 5851                ))
 5852            })
 5853        } else {
 5854            let implementations_task = self.request_multiple_lsp_locally(
 5855                buffer,
 5856                Some(position),
 5857                GetImplementations { position },
 5858                cx,
 5859            );
 5860            cx.background_spawn(async move {
 5861                Ok(Some(
 5862                    implementations_task
 5863                        .await
 5864                        .into_iter()
 5865                        .flat_map(|(_, implementations)| implementations)
 5866                        .dedup()
 5867                        .collect(),
 5868                ))
 5869            })
 5870        }
 5871    }
 5872
 5873    pub fn references(
 5874        &mut self,
 5875        buffer: &Entity<Buffer>,
 5876        position: PointUtf16,
 5877        cx: &mut Context<Self>,
 5878    ) -> Task<Result<Option<Vec<Location>>>> {
 5879        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5880            let request = GetReferences { position };
 5881            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5882                return Task::ready(Ok(None));
 5883            }
 5884
 5885            let request_task = upstream_client.request_lsp(
 5886                project_id,
 5887                None,
 5888                LSP_REQUEST_TIMEOUT,
 5889                cx.background_executor().clone(),
 5890                request.to_proto(project_id, buffer.read(cx)),
 5891            );
 5892            let buffer = buffer.clone();
 5893            cx.spawn(async move |weak_lsp_store, cx| {
 5894                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5895                    return Ok(None);
 5896                };
 5897                let Some(responses) = request_task.await? else {
 5898                    return Ok(None);
 5899                };
 5900
 5901                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5902                    GetReferences { position }.response_from_proto(
 5903                        lsp_response.response,
 5904                        lsp_store.clone(),
 5905                        buffer.clone(),
 5906                        cx.clone(),
 5907                    )
 5908                }))
 5909                .await
 5910                .into_iter()
 5911                .collect::<Result<Vec<Vec<_>>>>()?
 5912                .into_iter()
 5913                .flatten()
 5914                .dedup()
 5915                .collect();
 5916                Ok(Some(locations))
 5917            })
 5918        } else {
 5919            let references_task = self.request_multiple_lsp_locally(
 5920                buffer,
 5921                Some(position),
 5922                GetReferences { position },
 5923                cx,
 5924            );
 5925            cx.background_spawn(async move {
 5926                Ok(Some(
 5927                    references_task
 5928                        .await
 5929                        .into_iter()
 5930                        .flat_map(|(_, references)| references)
 5931                        .dedup()
 5932                        .collect(),
 5933                ))
 5934            })
 5935        }
 5936    }
 5937
 5938    pub fn code_actions(
 5939        &mut self,
 5940        buffer: &Entity<Buffer>,
 5941        range: Range<Anchor>,
 5942        kinds: Option<Vec<CodeActionKind>>,
 5943        cx: &mut Context<Self>,
 5944    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5945        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5946            let request = GetCodeActions {
 5947                range: range.clone(),
 5948                kinds: kinds.clone(),
 5949            };
 5950            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5951                return Task::ready(Ok(None));
 5952            }
 5953            let request_task = upstream_client.request_lsp(
 5954                project_id,
 5955                None,
 5956                LSP_REQUEST_TIMEOUT,
 5957                cx.background_executor().clone(),
 5958                request.to_proto(project_id, buffer.read(cx)),
 5959            );
 5960            let buffer = buffer.clone();
 5961            cx.spawn(async move |weak_lsp_store, cx| {
 5962                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5963                    return Ok(None);
 5964                };
 5965                let Some(responses) = request_task.await? else {
 5966                    return Ok(None);
 5967                };
 5968                let actions = join_all(responses.payload.into_iter().map(|response| {
 5969                    GetCodeActions {
 5970                        range: range.clone(),
 5971                        kinds: kinds.clone(),
 5972                    }
 5973                    .response_from_proto(
 5974                        response.response,
 5975                        lsp_store.clone(),
 5976                        buffer.clone(),
 5977                        cx.clone(),
 5978                    )
 5979                }))
 5980                .await;
 5981
 5982                Ok(Some(
 5983                    actions
 5984                        .into_iter()
 5985                        .collect::<Result<Vec<Vec<_>>>>()?
 5986                        .into_iter()
 5987                        .flatten()
 5988                        .collect(),
 5989                ))
 5990            })
 5991        } else {
 5992            let all_actions_task = self.request_multiple_lsp_locally(
 5993                buffer,
 5994                Some(range.start),
 5995                GetCodeActions { range, kinds },
 5996                cx,
 5997            );
 5998            cx.background_spawn(async move {
 5999                Ok(Some(
 6000                    all_actions_task
 6001                        .await
 6002                        .into_iter()
 6003                        .flat_map(|(_, actions)| actions)
 6004                        .collect(),
 6005                ))
 6006            })
 6007        }
 6008    }
 6009
 6010    pub fn code_lens_actions(
 6011        &mut self,
 6012        buffer: &Entity<Buffer>,
 6013        cx: &mut Context<Self>,
 6014    ) -> CodeLensTask {
 6015        let version_queried_for = buffer.read(cx).version();
 6016        let buffer_id = buffer.read(cx).remote_id();
 6017        let existing_servers = self.as_local().map(|local| {
 6018            local
 6019                .buffers_opened_in_servers
 6020                .get(&buffer_id)
 6021                .cloned()
 6022                .unwrap_or_default()
 6023        });
 6024
 6025        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 6026            if let Some(cached_lens) = &lsp_data.code_lens {
 6027                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 6028                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 6029                        existing_servers != cached_lens.lens.keys().copied().collect()
 6030                    });
 6031                    if !has_different_servers {
 6032                        return Task::ready(Ok(Some(
 6033                            cached_lens.lens.values().flatten().cloned().collect(),
 6034                        )))
 6035                        .shared();
 6036                    }
 6037                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 6038                    if !version_queried_for.changed_since(updating_for) {
 6039                        return running_update.clone();
 6040                    }
 6041                }
 6042            }
 6043        }
 6044
 6045        let lens_lsp_data = self
 6046            .latest_lsp_data(buffer, cx)
 6047            .code_lens
 6048            .get_or_insert_default();
 6049        let buffer = buffer.clone();
 6050        let query_version_queried_for = version_queried_for.clone();
 6051        let new_task = cx
 6052            .spawn(async move |lsp_store, cx| {
 6053                cx.background_executor()
 6054                    .timer(Duration::from_millis(30))
 6055                    .await;
 6056                let fetched_lens = lsp_store
 6057                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 6058                    .map_err(Arc::new)?
 6059                    .await
 6060                    .context("fetching code lens")
 6061                    .map_err(Arc::new);
 6062                let fetched_lens = match fetched_lens {
 6063                    Ok(fetched_lens) => fetched_lens,
 6064                    Err(e) => {
 6065                        lsp_store
 6066                            .update(cx, |lsp_store, _| {
 6067                                if let Some(lens_lsp_data) = lsp_store
 6068                                    .lsp_data
 6069                                    .get_mut(&buffer_id)
 6070                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 6071                                {
 6072                                    lens_lsp_data.update = None;
 6073                                }
 6074                            })
 6075                            .ok();
 6076                        return Err(e);
 6077                    }
 6078                };
 6079
 6080                lsp_store
 6081                    .update(cx, |lsp_store, _| {
 6082                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 6083                        let code_lens = lsp_data.code_lens.as_mut()?;
 6084                        if let Some(fetched_lens) = fetched_lens {
 6085                            if lsp_data.buffer_version == query_version_queried_for {
 6086                                code_lens.lens.extend(fetched_lens);
 6087                            } else if !lsp_data
 6088                                .buffer_version
 6089                                .changed_since(&query_version_queried_for)
 6090                            {
 6091                                lsp_data.buffer_version = query_version_queried_for;
 6092                                code_lens.lens = fetched_lens;
 6093                            }
 6094                        }
 6095                        code_lens.update = None;
 6096                        Some(code_lens.lens.values().flatten().cloned().collect())
 6097                    })
 6098                    .map_err(Arc::new)
 6099            })
 6100            .shared();
 6101        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 6102        new_task
 6103    }
 6104
 6105    fn fetch_code_lens(
 6106        &mut self,
 6107        buffer: &Entity<Buffer>,
 6108        cx: &mut Context<Self>,
 6109    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 6110        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6111            let request = GetCodeLens;
 6112            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6113                return Task::ready(Ok(None));
 6114            }
 6115            let request_task = upstream_client.request_lsp(
 6116                project_id,
 6117                None,
 6118                LSP_REQUEST_TIMEOUT,
 6119                cx.background_executor().clone(),
 6120                request.to_proto(project_id, buffer.read(cx)),
 6121            );
 6122            let buffer = buffer.clone();
 6123            cx.spawn(async move |weak_lsp_store, cx| {
 6124                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6125                    return Ok(None);
 6126                };
 6127                let Some(responses) = request_task.await? else {
 6128                    return Ok(None);
 6129                };
 6130
 6131                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 6132                    let lsp_store = lsp_store.clone();
 6133                    let buffer = buffer.clone();
 6134                    let cx = cx.clone();
 6135                    async move {
 6136                        (
 6137                            LanguageServerId::from_proto(response.server_id),
 6138                            GetCodeLens
 6139                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6140                                .await,
 6141                        )
 6142                    }
 6143                }))
 6144                .await;
 6145
 6146                let mut has_errors = false;
 6147                let code_lens_actions = code_lens_actions
 6148                    .into_iter()
 6149                    .filter_map(|(server_id, code_lens)| match code_lens {
 6150                        Ok(code_lens) => Some((server_id, code_lens)),
 6151                        Err(e) => {
 6152                            has_errors = true;
 6153                            log::error!("{e:#}");
 6154                            None
 6155                        }
 6156                    })
 6157                    .collect::<HashMap<_, _>>();
 6158                anyhow::ensure!(
 6159                    !has_errors || !code_lens_actions.is_empty(),
 6160                    "Failed to fetch code lens"
 6161                );
 6162                Ok(Some(code_lens_actions))
 6163            })
 6164        } else {
 6165            let code_lens_actions_task =
 6166                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 6167            cx.background_spawn(async move {
 6168                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 6169            })
 6170        }
 6171    }
 6172
 6173    #[inline(never)]
 6174    pub fn completions(
 6175        &self,
 6176        buffer: &Entity<Buffer>,
 6177        position: PointUtf16,
 6178        context: CompletionContext,
 6179        cx: &mut Context<Self>,
 6180    ) -> Task<Result<Vec<CompletionResponse>>> {
 6181        let language_registry = self.languages.clone();
 6182
 6183        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6184            let snapshot = buffer.read(cx).snapshot();
 6185            let offset = position.to_offset(&snapshot);
 6186            let scope = snapshot.language_scope_at(offset);
 6187            let capable_lsps = self.all_capable_for_proto_request(
 6188                buffer,
 6189                |server_name, capabilities| {
 6190                    capabilities.completion_provider.is_some()
 6191                        && scope
 6192                            .as_ref()
 6193                            .map(|scope| scope.language_allowed(server_name))
 6194                            .unwrap_or(true)
 6195                },
 6196                cx,
 6197            );
 6198            if capable_lsps.is_empty() {
 6199                return Task::ready(Ok(Vec::new()));
 6200            }
 6201
 6202            let language = buffer.read(cx).language().cloned();
 6203
 6204            // In the future, we should provide project guests with the names of LSP adapters,
 6205            // so that they can use the correct LSP adapter when computing labels. For now,
 6206            // guests just use the first LSP adapter associated with the buffer's language.
 6207            let lsp_adapter = language.as_ref().and_then(|language| {
 6208                language_registry
 6209                    .lsp_adapters(&language.name())
 6210                    .first()
 6211                    .cloned()
 6212            });
 6213
 6214            let buffer = buffer.clone();
 6215
 6216            cx.spawn(async move |this, cx| {
 6217                let requests = join_all(
 6218                    capable_lsps
 6219                        .into_iter()
 6220                        .map(|id| {
 6221                            let request = GetCompletions {
 6222                                position,
 6223                                context: context.clone(),
 6224                                server_id: Some(id),
 6225                            };
 6226                            let buffer = buffer.clone();
 6227                            let language = language.clone();
 6228                            let lsp_adapter = lsp_adapter.clone();
 6229                            let upstream_client = upstream_client.clone();
 6230                            let response = this
 6231                                .update(cx, |this, cx| {
 6232                                    this.send_lsp_proto_request(
 6233                                        buffer,
 6234                                        upstream_client,
 6235                                        project_id,
 6236                                        request,
 6237                                        cx,
 6238                                    )
 6239                                })
 6240                                .log_err();
 6241                            async move {
 6242                                let response = response?.await.log_err()?;
 6243
 6244                                let completions = populate_labels_for_completions(
 6245                                    response.completions,
 6246                                    language,
 6247                                    lsp_adapter,
 6248                                )
 6249                                .await;
 6250
 6251                                Some(CompletionResponse {
 6252                                    completions,
 6253                                    display_options: CompletionDisplayOptions::default(),
 6254                                    is_incomplete: response.is_incomplete,
 6255                                })
 6256                            }
 6257                        })
 6258                        .collect::<Vec<_>>(),
 6259                );
 6260                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6261            })
 6262        } else if let Some(local) = self.as_local() {
 6263            let snapshot = buffer.read(cx).snapshot();
 6264            let offset = position.to_offset(&snapshot);
 6265            let scope = snapshot.language_scope_at(offset);
 6266            let language = snapshot.language().cloned();
 6267            let completion_settings = language_settings(
 6268                language.as_ref().map(|language| language.name()),
 6269                buffer.read(cx).file(),
 6270                cx,
 6271            )
 6272            .completions
 6273            .clone();
 6274            if !completion_settings.lsp {
 6275                return Task::ready(Ok(Vec::new()));
 6276            }
 6277
 6278            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6279                local
 6280                    .language_servers_for_buffer(buffer, cx)
 6281                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6282                    .filter(|(adapter, _)| {
 6283                        scope
 6284                            .as_ref()
 6285                            .map(|scope| scope.language_allowed(&adapter.name))
 6286                            .unwrap_or(true)
 6287                    })
 6288                    .map(|(_, server)| server.server_id())
 6289                    .collect()
 6290            });
 6291
 6292            let buffer = buffer.clone();
 6293            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6294            let lsp_timeout = if lsp_timeout > 0 {
 6295                Some(Duration::from_millis(lsp_timeout))
 6296            } else {
 6297                None
 6298            };
 6299            cx.spawn(async move |this,  cx| {
 6300                let mut tasks = Vec::with_capacity(server_ids.len());
 6301                this.update(cx, |lsp_store, cx| {
 6302                    for server_id in server_ids {
 6303                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6304                        let lsp_timeout = lsp_timeout
 6305                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6306                        let mut timeout = cx.background_spawn(async move {
 6307                            match lsp_timeout {
 6308                                Some(lsp_timeout) => {
 6309                                    lsp_timeout.await;
 6310                                    true
 6311                                },
 6312                                None => false,
 6313                            }
 6314                        }).fuse();
 6315                        let mut lsp_request = lsp_store.request_lsp(
 6316                            buffer.clone(),
 6317                            LanguageServerToQuery::Other(server_id),
 6318                            GetCompletions {
 6319                                position,
 6320                                context: context.clone(),
 6321                                server_id: Some(server_id),
 6322                            },
 6323                            cx,
 6324                        ).fuse();
 6325                        let new_task = cx.background_spawn(async move {
 6326                            select_biased! {
 6327                                response = lsp_request => anyhow::Ok(Some(response?)),
 6328                                timeout_happened = timeout => {
 6329                                    if timeout_happened {
 6330                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6331                                        Ok(None)
 6332                                    } else {
 6333                                        let completions = lsp_request.await?;
 6334                                        Ok(Some(completions))
 6335                                    }
 6336                                },
 6337                            }
 6338                        });
 6339                        tasks.push((lsp_adapter, new_task));
 6340                    }
 6341                })?;
 6342
 6343                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6344                    let completion_response = task.await.ok()??;
 6345                    let completions = populate_labels_for_completions(
 6346                            completion_response.completions,
 6347                            language.clone(),
 6348                            lsp_adapter,
 6349                        )
 6350                        .await;
 6351                    Some(CompletionResponse {
 6352                        completions,
 6353                        display_options: CompletionDisplayOptions::default(),
 6354                        is_incomplete: completion_response.is_incomplete,
 6355                    })
 6356                });
 6357
 6358                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6359
 6360                Ok(responses.into_iter().flatten().collect())
 6361            })
 6362        } else {
 6363            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6364        }
 6365    }
 6366
 6367    pub fn resolve_completions(
 6368        &self,
 6369        buffer: Entity<Buffer>,
 6370        completion_indices: Vec<usize>,
 6371        completions: Rc<RefCell<Box<[Completion]>>>,
 6372        cx: &mut Context<Self>,
 6373    ) -> Task<Result<bool>> {
 6374        let client = self.upstream_client();
 6375        let buffer_id = buffer.read(cx).remote_id();
 6376        let buffer_snapshot = buffer.read(cx).snapshot();
 6377
 6378        if !self.check_if_capable_for_proto_request(
 6379            &buffer,
 6380            GetCompletions::can_resolve_completions,
 6381            cx,
 6382        ) {
 6383            return Task::ready(Ok(false));
 6384        }
 6385        cx.spawn(async move |lsp_store, cx| {
 6386            let mut did_resolve = false;
 6387            if let Some((client, project_id)) = client {
 6388                for completion_index in completion_indices {
 6389                    let server_id = {
 6390                        let completion = &completions.borrow()[completion_index];
 6391                        completion.source.server_id()
 6392                    };
 6393                    if let Some(server_id) = server_id {
 6394                        if Self::resolve_completion_remote(
 6395                            project_id,
 6396                            server_id,
 6397                            buffer_id,
 6398                            completions.clone(),
 6399                            completion_index,
 6400                            client.clone(),
 6401                        )
 6402                        .await
 6403                        .log_err()
 6404                        .is_some()
 6405                        {
 6406                            did_resolve = true;
 6407                        }
 6408                    } else {
 6409                        resolve_word_completion(
 6410                            &buffer_snapshot,
 6411                            &mut completions.borrow_mut()[completion_index],
 6412                        );
 6413                    }
 6414                }
 6415            } else {
 6416                for completion_index in completion_indices {
 6417                    let server_id = {
 6418                        let completion = &completions.borrow()[completion_index];
 6419                        completion.source.server_id()
 6420                    };
 6421                    if let Some(server_id) = server_id {
 6422                        let server_and_adapter = lsp_store
 6423                            .read_with(cx, |lsp_store, _| {
 6424                                let server = lsp_store.language_server_for_id(server_id)?;
 6425                                let adapter =
 6426                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6427                                Some((server, adapter))
 6428                            })
 6429                            .ok()
 6430                            .flatten();
 6431                        let Some((server, adapter)) = server_and_adapter else {
 6432                            continue;
 6433                        };
 6434
 6435                        let resolved = Self::resolve_completion_local(
 6436                            server,
 6437                            completions.clone(),
 6438                            completion_index,
 6439                        )
 6440                        .await
 6441                        .log_err()
 6442                        .is_some();
 6443                        if resolved {
 6444                            Self::regenerate_completion_labels(
 6445                                adapter,
 6446                                &buffer_snapshot,
 6447                                completions.clone(),
 6448                                completion_index,
 6449                            )
 6450                            .await
 6451                            .log_err();
 6452                            did_resolve = true;
 6453                        }
 6454                    } else {
 6455                        resolve_word_completion(
 6456                            &buffer_snapshot,
 6457                            &mut completions.borrow_mut()[completion_index],
 6458                        );
 6459                    }
 6460                }
 6461            }
 6462
 6463            Ok(did_resolve)
 6464        })
 6465    }
 6466
 6467    async fn resolve_completion_local(
 6468        server: Arc<lsp::LanguageServer>,
 6469        completions: Rc<RefCell<Box<[Completion]>>>,
 6470        completion_index: usize,
 6471    ) -> Result<()> {
 6472        let server_id = server.server_id();
 6473        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6474            return Ok(());
 6475        }
 6476
 6477        let request = {
 6478            let completion = &completions.borrow()[completion_index];
 6479            match &completion.source {
 6480                CompletionSource::Lsp {
 6481                    lsp_completion,
 6482                    resolved,
 6483                    server_id: completion_server_id,
 6484                    ..
 6485                } => {
 6486                    if *resolved {
 6487                        return Ok(());
 6488                    }
 6489                    anyhow::ensure!(
 6490                        server_id == *completion_server_id,
 6491                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6492                    );
 6493                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6494                }
 6495                CompletionSource::BufferWord { .. }
 6496                | CompletionSource::Dap { .. }
 6497                | CompletionSource::Custom => {
 6498                    return Ok(());
 6499                }
 6500            }
 6501        };
 6502        let resolved_completion = request
 6503            .await
 6504            .into_response()
 6505            .context("resolve completion")?;
 6506
 6507        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6508        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6509
 6510        let mut completions = completions.borrow_mut();
 6511        let completion = &mut completions[completion_index];
 6512        if let CompletionSource::Lsp {
 6513            lsp_completion,
 6514            resolved,
 6515            server_id: completion_server_id,
 6516            ..
 6517        } = &mut completion.source
 6518        {
 6519            if *resolved {
 6520                return Ok(());
 6521            }
 6522            anyhow::ensure!(
 6523                server_id == *completion_server_id,
 6524                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6525            );
 6526            **lsp_completion = resolved_completion;
 6527            *resolved = true;
 6528        }
 6529        Ok(())
 6530    }
 6531
 6532    async fn regenerate_completion_labels(
 6533        adapter: Arc<CachedLspAdapter>,
 6534        snapshot: &BufferSnapshot,
 6535        completions: Rc<RefCell<Box<[Completion]>>>,
 6536        completion_index: usize,
 6537    ) -> Result<()> {
 6538        let completion_item = completions.borrow()[completion_index]
 6539            .source
 6540            .lsp_completion(true)
 6541            .map(Cow::into_owned);
 6542        if let Some(lsp_documentation) = completion_item
 6543            .as_ref()
 6544            .and_then(|completion_item| completion_item.documentation.clone())
 6545        {
 6546            let mut completions = completions.borrow_mut();
 6547            let completion = &mut completions[completion_index];
 6548            completion.documentation = Some(lsp_documentation.into());
 6549        } else {
 6550            let mut completions = completions.borrow_mut();
 6551            let completion = &mut completions[completion_index];
 6552            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6553        }
 6554
 6555        let mut new_label = match completion_item {
 6556            Some(completion_item) => {
 6557                // Some language servers always return `detail` lazily via resolve, regardless of
 6558                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6559                // See: https://github.com/yioneko/vtsls/issues/213
 6560                let language = snapshot.language();
 6561                match language {
 6562                    Some(language) => {
 6563                        adapter
 6564                            .labels_for_completions(
 6565                                std::slice::from_ref(&completion_item),
 6566                                language,
 6567                            )
 6568                            .await?
 6569                    }
 6570                    None => Vec::new(),
 6571                }
 6572                .pop()
 6573                .flatten()
 6574                .unwrap_or_else(|| {
 6575                    CodeLabel::fallback_for_completion(
 6576                        &completion_item,
 6577                        language.map(|language| language.as_ref()),
 6578                    )
 6579                })
 6580            }
 6581            None => CodeLabel::plain(
 6582                completions.borrow()[completion_index].new_text.clone(),
 6583                None,
 6584            ),
 6585        };
 6586        ensure_uniform_list_compatible_label(&mut new_label);
 6587
 6588        let mut completions = completions.borrow_mut();
 6589        let completion = &mut completions[completion_index];
 6590        if completion.label.filter_text() == new_label.filter_text() {
 6591            completion.label = new_label;
 6592        } else {
 6593            log::error!(
 6594                "Resolved completion changed display label from {} to {}. \
 6595                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6596                completion.label.text(),
 6597                new_label.text(),
 6598                completion.label.filter_text(),
 6599                new_label.filter_text()
 6600            );
 6601        }
 6602
 6603        Ok(())
 6604    }
 6605
 6606    async fn resolve_completion_remote(
 6607        project_id: u64,
 6608        server_id: LanguageServerId,
 6609        buffer_id: BufferId,
 6610        completions: Rc<RefCell<Box<[Completion]>>>,
 6611        completion_index: usize,
 6612        client: AnyProtoClient,
 6613    ) -> Result<()> {
 6614        let lsp_completion = {
 6615            let completion = &completions.borrow()[completion_index];
 6616            match &completion.source {
 6617                CompletionSource::Lsp {
 6618                    lsp_completion,
 6619                    resolved,
 6620                    server_id: completion_server_id,
 6621                    ..
 6622                } => {
 6623                    anyhow::ensure!(
 6624                        server_id == *completion_server_id,
 6625                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6626                    );
 6627                    if *resolved {
 6628                        return Ok(());
 6629                    }
 6630                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6631                }
 6632                CompletionSource::Custom
 6633                | CompletionSource::Dap { .. }
 6634                | CompletionSource::BufferWord { .. } => {
 6635                    return Ok(());
 6636                }
 6637            }
 6638        };
 6639        let request = proto::ResolveCompletionDocumentation {
 6640            project_id,
 6641            language_server_id: server_id.0 as u64,
 6642            lsp_completion,
 6643            buffer_id: buffer_id.into(),
 6644        };
 6645
 6646        let response = client
 6647            .request(request)
 6648            .await
 6649            .context("completion documentation resolve proto request")?;
 6650        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6651
 6652        let documentation = if response.documentation.is_empty() {
 6653            CompletionDocumentation::Undocumented
 6654        } else if response.documentation_is_markdown {
 6655            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6656        } else if response.documentation.lines().count() <= 1 {
 6657            CompletionDocumentation::SingleLine(response.documentation.into())
 6658        } else {
 6659            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6660        };
 6661
 6662        let mut completions = completions.borrow_mut();
 6663        let completion = &mut completions[completion_index];
 6664        completion.documentation = Some(documentation);
 6665        if let CompletionSource::Lsp {
 6666            insert_range,
 6667            lsp_completion,
 6668            resolved,
 6669            server_id: completion_server_id,
 6670            lsp_defaults: _,
 6671        } = &mut completion.source
 6672        {
 6673            let completion_insert_range = response
 6674                .old_insert_start
 6675                .and_then(deserialize_anchor)
 6676                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6677            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6678
 6679            if *resolved {
 6680                return Ok(());
 6681            }
 6682            anyhow::ensure!(
 6683                server_id == *completion_server_id,
 6684                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6685            );
 6686            **lsp_completion = resolved_lsp_completion;
 6687            *resolved = true;
 6688        }
 6689
 6690        let replace_range = response
 6691            .old_replace_start
 6692            .and_then(deserialize_anchor)
 6693            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6694        if let Some((old_replace_start, old_replace_end)) = replace_range
 6695            && !response.new_text.is_empty()
 6696        {
 6697            completion.new_text = response.new_text;
 6698            completion.replace_range = old_replace_start..old_replace_end;
 6699        }
 6700
 6701        Ok(())
 6702    }
 6703
 6704    pub fn apply_additional_edits_for_completion(
 6705        &self,
 6706        buffer_handle: Entity<Buffer>,
 6707        completions: Rc<RefCell<Box<[Completion]>>>,
 6708        completion_index: usize,
 6709        push_to_history: bool,
 6710        cx: &mut Context<Self>,
 6711    ) -> Task<Result<Option<Transaction>>> {
 6712        if let Some((client, project_id)) = self.upstream_client() {
 6713            let buffer = buffer_handle.read(cx);
 6714            let buffer_id = buffer.remote_id();
 6715            cx.spawn(async move |_, cx| {
 6716                let request = {
 6717                    let completion = completions.borrow()[completion_index].clone();
 6718                    proto::ApplyCompletionAdditionalEdits {
 6719                        project_id,
 6720                        buffer_id: buffer_id.into(),
 6721                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6722                            replace_range: completion.replace_range,
 6723                            new_text: completion.new_text,
 6724                            source: completion.source,
 6725                        })),
 6726                    }
 6727                };
 6728
 6729                if let Some(transaction) = client.request(request).await?.transaction {
 6730                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6731                    buffer_handle
 6732                        .update(cx, |buffer, _| {
 6733                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6734                        })
 6735                        .await?;
 6736                    if push_to_history {
 6737                        buffer_handle.update(cx, |buffer, _| {
 6738                            buffer.push_transaction(transaction.clone(), Instant::now());
 6739                            buffer.finalize_last_transaction();
 6740                        });
 6741                    }
 6742                    Ok(Some(transaction))
 6743                } else {
 6744                    Ok(None)
 6745                }
 6746            })
 6747        } else {
 6748            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6749                let completion = &completions.borrow()[completion_index];
 6750                let server_id = completion.source.server_id()?;
 6751                Some(
 6752                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6753                        .1
 6754                        .clone(),
 6755                )
 6756            }) else {
 6757                return Task::ready(Ok(None));
 6758            };
 6759
 6760            cx.spawn(async move |this, cx| {
 6761                Self::resolve_completion_local(
 6762                    server.clone(),
 6763                    completions.clone(),
 6764                    completion_index,
 6765                )
 6766                .await
 6767                .context("resolving completion")?;
 6768                let completion = completions.borrow()[completion_index].clone();
 6769                let additional_text_edits = completion
 6770                    .source
 6771                    .lsp_completion(true)
 6772                    .as_ref()
 6773                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6774                if let Some(edits) = additional_text_edits {
 6775                    let edits = this
 6776                        .update(cx, |this, cx| {
 6777                            this.as_local_mut().unwrap().edits_from_lsp(
 6778                                &buffer_handle,
 6779                                edits,
 6780                                server.server_id(),
 6781                                None,
 6782                                cx,
 6783                            )
 6784                        })?
 6785                        .await?;
 6786
 6787                    buffer_handle.update(cx, |buffer, cx| {
 6788                        buffer.finalize_last_transaction();
 6789                        buffer.start_transaction();
 6790
 6791                        for (range, text) in edits {
 6792                            let primary = &completion.replace_range;
 6793
 6794                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6795                            // and the primary completion is just an insertion (empty range), then this is likely
 6796                            // an auto-import scenario and should not be considered overlapping
 6797                            // https://github.com/zed-industries/zed/issues/26136
 6798                            let is_file_start_auto_import = {
 6799                                let snapshot = buffer.snapshot();
 6800                                let primary_start_point = primary.start.to_point(&snapshot);
 6801                                let range_start_point = range.start.to_point(&snapshot);
 6802
 6803                                let result = primary_start_point.row == 0
 6804                                    && primary_start_point.column == 0
 6805                                    && range_start_point.row == 0
 6806                                    && range_start_point.column == 0;
 6807
 6808                                result
 6809                            };
 6810
 6811                            let has_overlap = if is_file_start_auto_import {
 6812                                false
 6813                            } else {
 6814                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6815                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6816                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6817                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6818                                let result = start_within || end_within;
 6819                                result
 6820                            };
 6821
 6822                            //Skip additional edits which overlap with the primary completion edit
 6823                            //https://github.com/zed-industries/zed/pull/1871
 6824                            if !has_overlap {
 6825                                buffer.edit([(range, text)], None, cx);
 6826                            }
 6827                        }
 6828
 6829                        let transaction = if buffer.end_transaction(cx).is_some() {
 6830                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6831                            if !push_to_history {
 6832                                buffer.forget_transaction(transaction.id);
 6833                            }
 6834                            Some(transaction)
 6835                        } else {
 6836                            None
 6837                        };
 6838                        Ok(transaction)
 6839                    })
 6840                } else {
 6841                    Ok(None)
 6842                }
 6843            })
 6844        }
 6845    }
 6846
 6847    pub fn pull_diagnostics(
 6848        &mut self,
 6849        buffer: Entity<Buffer>,
 6850        cx: &mut Context<Self>,
 6851    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6852        let buffer_id = buffer.read(cx).remote_id();
 6853
 6854        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6855            let mut suitable_capabilities = None;
 6856            // Are we capable for proto request?
 6857            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6858                &buffer,
 6859                |capabilities| {
 6860                    if let Some(caps) = &capabilities.diagnostic_provider {
 6861                        suitable_capabilities = Some(caps.clone());
 6862                        true
 6863                    } else {
 6864                        false
 6865                    }
 6866                },
 6867                cx,
 6868            );
 6869            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6870            let Some(dynamic_caps) = suitable_capabilities else {
 6871                return Task::ready(Ok(None));
 6872            };
 6873            assert!(any_server_has_diagnostics_provider);
 6874
 6875            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6876            let request = GetDocumentDiagnostics {
 6877                previous_result_id: None,
 6878                identifier,
 6879                registration_id: None,
 6880            };
 6881            let request_task = client.request_lsp(
 6882                upstream_project_id,
 6883                None,
 6884                LSP_REQUEST_TIMEOUT,
 6885                cx.background_executor().clone(),
 6886                request.to_proto(upstream_project_id, buffer.read(cx)),
 6887            );
 6888            cx.background_spawn(async move {
 6889                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6890                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6891                // Do not attempt to further process the dummy responses here.
 6892                let _response = request_task.await?;
 6893                Ok(None)
 6894            })
 6895        } else {
 6896            let servers = buffer.update(cx, |buffer, cx| {
 6897                self.running_language_servers_for_local_buffer(buffer, cx)
 6898                    .map(|(_, server)| server.clone())
 6899                    .collect::<Vec<_>>()
 6900            });
 6901
 6902            let pull_diagnostics = servers
 6903                .into_iter()
 6904                .flat_map(|server| {
 6905                    let result = maybe!({
 6906                        let local = self.as_local()?;
 6907                        let server_id = server.server_id();
 6908                        let providers_with_identifiers = local
 6909                            .language_server_dynamic_registrations
 6910                            .get(&server_id)
 6911                            .into_iter()
 6912                            .flat_map(|registrations| registrations.diagnostics.clone())
 6913                            .collect::<Vec<_>>();
 6914                        Some(
 6915                            providers_with_identifiers
 6916                                .into_iter()
 6917                                .map(|(registration_id, dynamic_caps)| {
 6918                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6919                                    let registration_id = registration_id.map(SharedString::from);
 6920                                    let result_id = self.result_id_for_buffer_pull(
 6921                                        server_id,
 6922                                        buffer_id,
 6923                                        &registration_id,
 6924                                        cx,
 6925                                    );
 6926                                    self.request_lsp(
 6927                                        buffer.clone(),
 6928                                        LanguageServerToQuery::Other(server_id),
 6929                                        GetDocumentDiagnostics {
 6930                                            previous_result_id: result_id,
 6931                                            registration_id,
 6932                                            identifier,
 6933                                        },
 6934                                        cx,
 6935                                    )
 6936                                })
 6937                                .collect::<Vec<_>>(),
 6938                        )
 6939                    });
 6940
 6941                    result.unwrap_or_default()
 6942                })
 6943                .collect::<Vec<_>>();
 6944
 6945            cx.background_spawn(async move {
 6946                let mut responses = Vec::new();
 6947                for diagnostics in join_all(pull_diagnostics).await {
 6948                    responses.extend(diagnostics?);
 6949                }
 6950                Ok(Some(responses))
 6951            })
 6952        }
 6953    }
 6954
 6955    pub fn applicable_inlay_chunks(
 6956        &mut self,
 6957        buffer: &Entity<Buffer>,
 6958        ranges: &[Range<text::Anchor>],
 6959        cx: &mut Context<Self>,
 6960    ) -> Vec<Range<BufferRow>> {
 6961        let buffer_snapshot = buffer.read(cx).snapshot();
 6962        let ranges = ranges
 6963            .iter()
 6964            .map(|range| range.to_point(&buffer_snapshot))
 6965            .collect::<Vec<_>>();
 6966
 6967        self.latest_lsp_data(buffer, cx)
 6968            .inlay_hints
 6969            .applicable_chunks(ranges.as_slice())
 6970            .map(|chunk| chunk.row_range())
 6971            .collect()
 6972    }
 6973
 6974    pub fn invalidate_inlay_hints<'a>(
 6975        &'a mut self,
 6976        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6977    ) {
 6978        for buffer_id in for_buffers {
 6979            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6980                lsp_data.inlay_hints.clear();
 6981            }
 6982        }
 6983    }
 6984
 6985    pub fn inlay_hints(
 6986        &mut self,
 6987        invalidate: InvalidationStrategy,
 6988        buffer: Entity<Buffer>,
 6989        ranges: Vec<Range<text::Anchor>>,
 6990        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6991        cx: &mut Context<Self>,
 6992    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6993        let next_hint_id = self.next_hint_id.clone();
 6994        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6995        let query_version = lsp_data.buffer_version.clone();
 6996        let mut lsp_refresh_requested = false;
 6997        let for_server = if let InvalidationStrategy::RefreshRequested {
 6998            server_id,
 6999            request_id,
 7000        } = invalidate
 7001        {
 7002            let invalidated = lsp_data
 7003                .inlay_hints
 7004                .invalidate_for_server_refresh(server_id, request_id);
 7005            lsp_refresh_requested = invalidated;
 7006            Some(server_id)
 7007        } else {
 7008            None
 7009        };
 7010        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 7011        let known_chunks = known_chunks
 7012            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 7013            .map(|(_, known_chunks)| known_chunks)
 7014            .unwrap_or_default();
 7015
 7016        let buffer_snapshot = buffer.read(cx).snapshot();
 7017        let ranges = ranges
 7018            .iter()
 7019            .map(|range| range.to_point(&buffer_snapshot))
 7020            .collect::<Vec<_>>();
 7021
 7022        let mut hint_fetch_tasks = Vec::new();
 7023        let mut cached_inlay_hints = None;
 7024        let mut ranges_to_query = None;
 7025        let applicable_chunks = existing_inlay_hints
 7026            .applicable_chunks(ranges.as_slice())
 7027            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7028            .collect::<Vec<_>>();
 7029        if applicable_chunks.is_empty() {
 7030            return HashMap::default();
 7031        }
 7032
 7033        for row_chunk in applicable_chunks {
 7034            match (
 7035                existing_inlay_hints
 7036                    .cached_hints(&row_chunk)
 7037                    .filter(|_| !lsp_refresh_requested)
 7038                    .cloned(),
 7039                existing_inlay_hints
 7040                    .fetched_hints(&row_chunk)
 7041                    .as_ref()
 7042                    .filter(|_| !lsp_refresh_requested)
 7043                    .cloned(),
 7044            ) {
 7045                (None, None) => {
 7046                    let chunk_range = row_chunk.anchor_range();
 7047                    ranges_to_query
 7048                        .get_or_insert_with(Vec::new)
 7049                        .push((row_chunk, chunk_range));
 7050                }
 7051                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7052                (Some(cached_hints), None) => {
 7053                    for (server_id, cached_hints) in cached_hints {
 7054                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7055                            cached_inlay_hints
 7056                                .get_or_insert_with(HashMap::default)
 7057                                .entry(row_chunk.row_range())
 7058                                .or_insert_with(HashMap::default)
 7059                                .entry(server_id)
 7060                                .or_insert_with(Vec::new)
 7061                                .extend(cached_hints);
 7062                        }
 7063                    }
 7064                }
 7065                (Some(cached_hints), Some(fetched_hints)) => {
 7066                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7067                    for (server_id, cached_hints) in cached_hints {
 7068                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7069                            cached_inlay_hints
 7070                                .get_or_insert_with(HashMap::default)
 7071                                .entry(row_chunk.row_range())
 7072                                .or_insert_with(HashMap::default)
 7073                                .entry(server_id)
 7074                                .or_insert_with(Vec::new)
 7075                                .extend(cached_hints);
 7076                        }
 7077                    }
 7078                }
 7079            }
 7080        }
 7081
 7082        if hint_fetch_tasks.is_empty()
 7083            && ranges_to_query
 7084                .as_ref()
 7085                .is_none_or(|ranges| ranges.is_empty())
 7086            && let Some(cached_inlay_hints) = cached_inlay_hints
 7087        {
 7088            cached_inlay_hints
 7089                .into_iter()
 7090                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7091                .collect()
 7092        } else {
 7093            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7094                let next_hint_id = next_hint_id.clone();
 7095                let buffer = buffer.clone();
 7096                let query_version = query_version.clone();
 7097                let new_inlay_hints = cx
 7098                    .spawn(async move |lsp_store, cx| {
 7099                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7100                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7101                        })?;
 7102                        new_fetch_task
 7103                            .await
 7104                            .and_then(|new_hints_by_server| {
 7105                                lsp_store.update(cx, |lsp_store, cx| {
 7106                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7107                                    let update_cache = lsp_data.buffer_version == query_version;
 7108                                    if new_hints_by_server.is_empty() {
 7109                                        if update_cache {
 7110                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7111                                        }
 7112                                        HashMap::default()
 7113                                    } else {
 7114                                        new_hints_by_server
 7115                                            .into_iter()
 7116                                            .map(|(server_id, new_hints)| {
 7117                                                let new_hints = new_hints
 7118                                                    .into_iter()
 7119                                                    .map(|new_hint| {
 7120                                                        (
 7121                                                            InlayId::Hint(next_hint_id.fetch_add(
 7122                                                                1,
 7123                                                                atomic::Ordering::AcqRel,
 7124                                                            )),
 7125                                                            new_hint,
 7126                                                        )
 7127                                                    })
 7128                                                    .collect::<Vec<_>>();
 7129                                                if update_cache {
 7130                                                    lsp_data.inlay_hints.insert_new_hints(
 7131                                                        chunk,
 7132                                                        server_id,
 7133                                                        new_hints.clone(),
 7134                                                    );
 7135                                                }
 7136                                                (server_id, new_hints)
 7137                                            })
 7138                                            .collect()
 7139                                    }
 7140                                })
 7141                            })
 7142                            .map_err(Arc::new)
 7143                    })
 7144                    .shared();
 7145
 7146                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7147                *fetch_task = Some(new_inlay_hints.clone());
 7148                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7149            }
 7150
 7151            cached_inlay_hints
 7152                .unwrap_or_default()
 7153                .into_iter()
 7154                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7155                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7156                    (
 7157                        chunk.row_range(),
 7158                        cx.spawn(async move |_, _| {
 7159                            hints_fetch.await.map_err(|e| {
 7160                                if e.error_code() != ErrorCode::Internal {
 7161                                    anyhow!(e.error_code())
 7162                                } else {
 7163                                    anyhow!("{e:#}")
 7164                                }
 7165                            })
 7166                        }),
 7167                    )
 7168                }))
 7169                .collect()
 7170        }
 7171    }
 7172
 7173    fn fetch_inlay_hints(
 7174        &mut self,
 7175        for_server: Option<LanguageServerId>,
 7176        buffer: &Entity<Buffer>,
 7177        range: Range<Anchor>,
 7178        cx: &mut Context<Self>,
 7179    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7180        let request = InlayHints {
 7181            range: range.clone(),
 7182        };
 7183        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7184            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7185                return Task::ready(Ok(HashMap::default()));
 7186            }
 7187            let request_task = upstream_client.request_lsp(
 7188                project_id,
 7189                for_server.map(|id| id.to_proto()),
 7190                LSP_REQUEST_TIMEOUT,
 7191                cx.background_executor().clone(),
 7192                request.to_proto(project_id, buffer.read(cx)),
 7193            );
 7194            let buffer = buffer.clone();
 7195            cx.spawn(async move |weak_lsp_store, cx| {
 7196                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7197                    return Ok(HashMap::default());
 7198                };
 7199                let Some(responses) = request_task.await? else {
 7200                    return Ok(HashMap::default());
 7201                };
 7202
 7203                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7204                    let lsp_store = lsp_store.clone();
 7205                    let buffer = buffer.clone();
 7206                    let cx = cx.clone();
 7207                    let request = request.clone();
 7208                    async move {
 7209                        (
 7210                            LanguageServerId::from_proto(response.server_id),
 7211                            request
 7212                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7213                                .await,
 7214                        )
 7215                    }
 7216                }))
 7217                .await;
 7218
 7219                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7220                let mut has_errors = false;
 7221                let inlay_hints = inlay_hints
 7222                    .into_iter()
 7223                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7224                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7225                        Err(e) => {
 7226                            has_errors = true;
 7227                            log::error!("{e:#}");
 7228                            None
 7229                        }
 7230                    })
 7231                    .map(|(server_id, mut new_hints)| {
 7232                        new_hints.retain(|hint| {
 7233                            hint.position.is_valid(&buffer_snapshot)
 7234                                && range.start.is_valid(&buffer_snapshot)
 7235                                && range.end.is_valid(&buffer_snapshot)
 7236                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7237                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7238                        });
 7239                        (server_id, new_hints)
 7240                    })
 7241                    .collect::<HashMap<_, _>>();
 7242                anyhow::ensure!(
 7243                    !has_errors || !inlay_hints.is_empty(),
 7244                    "Failed to fetch inlay hints"
 7245                );
 7246                Ok(inlay_hints)
 7247            })
 7248        } else {
 7249            let inlay_hints_task = match for_server {
 7250                Some(server_id) => {
 7251                    let server_task = self.request_lsp(
 7252                        buffer.clone(),
 7253                        LanguageServerToQuery::Other(server_id),
 7254                        request,
 7255                        cx,
 7256                    );
 7257                    cx.background_spawn(async move {
 7258                        let mut responses = Vec::new();
 7259                        match server_task.await {
 7260                            Ok(response) => responses.push((server_id, response)),
 7261                            // rust-analyzer likes to error with this when its still loading up
 7262                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7263                            Err(e) => log::error!(
 7264                                "Error handling response for inlay hints request: {e:#}"
 7265                            ),
 7266                        }
 7267                        responses
 7268                    })
 7269                }
 7270                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7271            };
 7272            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7273            cx.background_spawn(async move {
 7274                Ok(inlay_hints_task
 7275                    .await
 7276                    .into_iter()
 7277                    .map(|(server_id, mut new_hints)| {
 7278                        new_hints.retain(|hint| {
 7279                            hint.position.is_valid(&buffer_snapshot)
 7280                                && range.start.is_valid(&buffer_snapshot)
 7281                                && range.end.is_valid(&buffer_snapshot)
 7282                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7283                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7284                        });
 7285                        (server_id, new_hints)
 7286                    })
 7287                    .collect())
 7288            })
 7289        }
 7290    }
 7291
 7292    fn diagnostic_registration_exists(
 7293        &self,
 7294        server_id: LanguageServerId,
 7295        registration_id: &Option<SharedString>,
 7296    ) -> bool {
 7297        let Some(local) = self.as_local() else {
 7298            return false;
 7299        };
 7300        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7301        else {
 7302            return false;
 7303        };
 7304        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7305        registrations.diagnostics.contains_key(&registration_key)
 7306    }
 7307
 7308    pub fn pull_diagnostics_for_buffer(
 7309        &mut self,
 7310        buffer: Entity<Buffer>,
 7311        cx: &mut Context<Self>,
 7312    ) -> Task<anyhow::Result<()>> {
 7313        let diagnostics = self.pull_diagnostics(buffer, cx);
 7314        cx.spawn(async move |lsp_store, cx| {
 7315            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7316                return Ok(());
 7317            };
 7318            lsp_store.update(cx, |lsp_store, cx| {
 7319                if lsp_store.as_local().is_none() {
 7320                    return;
 7321                }
 7322
 7323                let mut unchanged_buffers = HashMap::default();
 7324                let server_diagnostics_updates = diagnostics
 7325                    .into_iter()
 7326                    .filter_map(|diagnostics_set| match diagnostics_set {
 7327                        LspPullDiagnostics::Response {
 7328                            server_id,
 7329                            uri,
 7330                            diagnostics,
 7331                            registration_id,
 7332                        } => Some((server_id, uri, diagnostics, registration_id)),
 7333                        LspPullDiagnostics::Default => None,
 7334                    })
 7335                    .filter(|(server_id, _, _, registration_id)| {
 7336                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7337                    })
 7338                    .fold(
 7339                        HashMap::default(),
 7340                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7341                            let (result_id, diagnostics) = match diagnostics {
 7342                                PulledDiagnostics::Unchanged { result_id } => {
 7343                                    unchanged_buffers
 7344                                        .entry(new_registration_id.clone())
 7345                                        .or_insert_with(HashSet::default)
 7346                                        .insert(uri.clone());
 7347                                    (Some(result_id), Vec::new())
 7348                                }
 7349                                PulledDiagnostics::Changed {
 7350                                    result_id,
 7351                                    diagnostics,
 7352                                } => (result_id, diagnostics),
 7353                            };
 7354                            let disk_based_sources = Cow::Owned(
 7355                                lsp_store
 7356                                    .language_server_adapter_for_id(server_id)
 7357                                    .as_ref()
 7358                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7359                                    .unwrap_or(&[])
 7360                                    .to_vec(),
 7361                            );
 7362                            acc.entry(server_id)
 7363                                .or_insert_with(HashMap::default)
 7364                                .entry(new_registration_id.clone())
 7365                                .or_insert_with(Vec::new)
 7366                                .push(DocumentDiagnosticsUpdate {
 7367                                    server_id,
 7368                                    diagnostics: lsp::PublishDiagnosticsParams {
 7369                                        uri,
 7370                                        diagnostics,
 7371                                        version: None,
 7372                                    },
 7373                                    result_id,
 7374                                    disk_based_sources,
 7375                                    registration_id: new_registration_id,
 7376                                });
 7377                            acc
 7378                        },
 7379                    );
 7380
 7381                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7382                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7383                        lsp_store
 7384                            .merge_lsp_diagnostics(
 7385                                DiagnosticSourceKind::Pulled,
 7386                                diagnostic_updates,
 7387                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7388                                    DiagnosticSourceKind::Pulled => {
 7389                                        old_diagnostic.registration_id != registration_id
 7390                                            || unchanged_buffers
 7391                                                .get(&old_diagnostic.registration_id)
 7392                                                .is_some_and(|unchanged_buffers| {
 7393                                                    unchanged_buffers.contains(&document_uri)
 7394                                                })
 7395                                    }
 7396                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7397                                        true
 7398                                    }
 7399                                },
 7400                                cx,
 7401                            )
 7402                            .log_err();
 7403                    }
 7404                }
 7405            })
 7406        })
 7407    }
 7408
 7409    pub fn document_colors(
 7410        &mut self,
 7411        known_cache_version: Option<usize>,
 7412        buffer: Entity<Buffer>,
 7413        cx: &mut Context<Self>,
 7414    ) -> Option<DocumentColorTask> {
 7415        let version_queried_for = buffer.read(cx).version();
 7416        let buffer_id = buffer.read(cx).remote_id();
 7417
 7418        let current_language_servers = self.as_local().map(|local| {
 7419            local
 7420                .buffers_opened_in_servers
 7421                .get(&buffer_id)
 7422                .cloned()
 7423                .unwrap_or_default()
 7424        });
 7425
 7426        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7427            if let Some(cached_colors) = &lsp_data.document_colors {
 7428                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7429                    let has_different_servers =
 7430                        current_language_servers.is_some_and(|current_language_servers| {
 7431                            current_language_servers
 7432                                != cached_colors.colors.keys().copied().collect()
 7433                        });
 7434                    if !has_different_servers {
 7435                        let cache_version = cached_colors.cache_version;
 7436                        if Some(cache_version) == known_cache_version {
 7437                            return None;
 7438                        } else {
 7439                            return Some(
 7440                                Task::ready(Ok(DocumentColors {
 7441                                    colors: cached_colors
 7442                                        .colors
 7443                                        .values()
 7444                                        .flatten()
 7445                                        .cloned()
 7446                                        .collect(),
 7447                                    cache_version: Some(cache_version),
 7448                                }))
 7449                                .shared(),
 7450                            );
 7451                        }
 7452                    }
 7453                }
 7454            }
 7455        }
 7456
 7457        let color_lsp_data = self
 7458            .latest_lsp_data(&buffer, cx)
 7459            .document_colors
 7460            .get_or_insert_default();
 7461        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7462            && !version_queried_for.changed_since(updating_for)
 7463        {
 7464            return Some(running_update.clone());
 7465        }
 7466        let buffer_version_queried_for = version_queried_for.clone();
 7467        let new_task = cx
 7468            .spawn(async move |lsp_store, cx| {
 7469                cx.background_executor()
 7470                    .timer(Duration::from_millis(30))
 7471                    .await;
 7472                let fetched_colors = lsp_store
 7473                    .update(cx, |lsp_store, cx| {
 7474                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7475                    })?
 7476                    .await
 7477                    .context("fetching document colors")
 7478                    .map_err(Arc::new);
 7479                let fetched_colors = match fetched_colors {
 7480                    Ok(fetched_colors) => {
 7481                        if buffer.update(cx, |buffer, _| {
 7482                            buffer.version() != buffer_version_queried_for
 7483                        }) {
 7484                            return Ok(DocumentColors::default());
 7485                        }
 7486                        fetched_colors
 7487                    }
 7488                    Err(e) => {
 7489                        lsp_store
 7490                            .update(cx, |lsp_store, _| {
 7491                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7492                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7493                                        document_colors.colors_update = None;
 7494                                    }
 7495                                }
 7496                            })
 7497                            .ok();
 7498                        return Err(e);
 7499                    }
 7500                };
 7501
 7502                lsp_store
 7503                    .update(cx, |lsp_store, cx| {
 7504                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7505                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7506
 7507                        if let Some(fetched_colors) = fetched_colors {
 7508                            if lsp_data.buffer_version == buffer_version_queried_for {
 7509                                lsp_colors.colors.extend(fetched_colors);
 7510                                lsp_colors.cache_version += 1;
 7511                            } else if !lsp_data
 7512                                .buffer_version
 7513                                .changed_since(&buffer_version_queried_for)
 7514                            {
 7515                                lsp_data.buffer_version = buffer_version_queried_for;
 7516                                lsp_colors.colors = fetched_colors;
 7517                                lsp_colors.cache_version += 1;
 7518                            }
 7519                        }
 7520                        lsp_colors.colors_update = None;
 7521                        let colors = lsp_colors
 7522                            .colors
 7523                            .values()
 7524                            .flatten()
 7525                            .cloned()
 7526                            .collect::<HashSet<_>>();
 7527                        DocumentColors {
 7528                            colors,
 7529                            cache_version: Some(lsp_colors.cache_version),
 7530                        }
 7531                    })
 7532                    .map_err(Arc::new)
 7533            })
 7534            .shared();
 7535        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7536        Some(new_task)
 7537    }
 7538
 7539    fn fetch_document_colors_for_buffer(
 7540        &mut self,
 7541        buffer: &Entity<Buffer>,
 7542        cx: &mut Context<Self>,
 7543    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7544        if let Some((client, project_id)) = self.upstream_client() {
 7545            let request = GetDocumentColor {};
 7546            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7547                return Task::ready(Ok(None));
 7548            }
 7549
 7550            let request_task = client.request_lsp(
 7551                project_id,
 7552                None,
 7553                LSP_REQUEST_TIMEOUT,
 7554                cx.background_executor().clone(),
 7555                request.to_proto(project_id, buffer.read(cx)),
 7556            );
 7557            let buffer = buffer.clone();
 7558            cx.spawn(async move |lsp_store, cx| {
 7559                let Some(lsp_store) = lsp_store.upgrade() else {
 7560                    return Ok(None);
 7561                };
 7562                let colors = join_all(
 7563                    request_task
 7564                        .await
 7565                        .log_err()
 7566                        .flatten()
 7567                        .map(|response| response.payload)
 7568                        .unwrap_or_default()
 7569                        .into_iter()
 7570                        .map(|color_response| {
 7571                            let response = request.response_from_proto(
 7572                                color_response.response,
 7573                                lsp_store.clone(),
 7574                                buffer.clone(),
 7575                                cx.clone(),
 7576                            );
 7577                            async move {
 7578                                (
 7579                                    LanguageServerId::from_proto(color_response.server_id),
 7580                                    response.await.log_err().unwrap_or_default(),
 7581                                )
 7582                            }
 7583                        }),
 7584                )
 7585                .await
 7586                .into_iter()
 7587                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7588                    acc.entry(server_id)
 7589                        .or_insert_with(HashSet::default)
 7590                        .extend(colors);
 7591                    acc
 7592                });
 7593                Ok(Some(colors))
 7594            })
 7595        } else {
 7596            let document_colors_task =
 7597                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7598            cx.background_spawn(async move {
 7599                Ok(Some(
 7600                    document_colors_task
 7601                        .await
 7602                        .into_iter()
 7603                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7604                            acc.entry(server_id)
 7605                                .or_insert_with(HashSet::default)
 7606                                .extend(colors);
 7607                            acc
 7608                        })
 7609                        .into_iter()
 7610                        .collect(),
 7611                ))
 7612            })
 7613        }
 7614    }
 7615
 7616    pub fn signature_help<T: ToPointUtf16>(
 7617        &mut self,
 7618        buffer: &Entity<Buffer>,
 7619        position: T,
 7620        cx: &mut Context<Self>,
 7621    ) -> Task<Option<Vec<SignatureHelp>>> {
 7622        let position = position.to_point_utf16(buffer.read(cx));
 7623
 7624        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7625            let request = GetSignatureHelp { position };
 7626            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7627                return Task::ready(None);
 7628            }
 7629            let request_task = client.request_lsp(
 7630                upstream_project_id,
 7631                None,
 7632                LSP_REQUEST_TIMEOUT,
 7633                cx.background_executor().clone(),
 7634                request.to_proto(upstream_project_id, buffer.read(cx)),
 7635            );
 7636            let buffer = buffer.clone();
 7637            cx.spawn(async move |weak_lsp_store, cx| {
 7638                let lsp_store = weak_lsp_store.upgrade()?;
 7639                let signatures = join_all(
 7640                    request_task
 7641                        .await
 7642                        .log_err()
 7643                        .flatten()
 7644                        .map(|response| response.payload)
 7645                        .unwrap_or_default()
 7646                        .into_iter()
 7647                        .map(|response| {
 7648                            let response = GetSignatureHelp { position }.response_from_proto(
 7649                                response.response,
 7650                                lsp_store.clone(),
 7651                                buffer.clone(),
 7652                                cx.clone(),
 7653                            );
 7654                            async move { response.await.log_err().flatten() }
 7655                        }),
 7656                )
 7657                .await
 7658                .into_iter()
 7659                .flatten()
 7660                .collect();
 7661                Some(signatures)
 7662            })
 7663        } else {
 7664            let all_actions_task = self.request_multiple_lsp_locally(
 7665                buffer,
 7666                Some(position),
 7667                GetSignatureHelp { position },
 7668                cx,
 7669            );
 7670            cx.background_spawn(async move {
 7671                Some(
 7672                    all_actions_task
 7673                        .await
 7674                        .into_iter()
 7675                        .flat_map(|(_, actions)| actions)
 7676                        .collect::<Vec<_>>(),
 7677                )
 7678            })
 7679        }
 7680    }
 7681
 7682    pub fn hover(
 7683        &mut self,
 7684        buffer: &Entity<Buffer>,
 7685        position: PointUtf16,
 7686        cx: &mut Context<Self>,
 7687    ) -> Task<Option<Vec<Hover>>> {
 7688        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7689            let request = GetHover { position };
 7690            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7691                return Task::ready(None);
 7692            }
 7693            let request_task = client.request_lsp(
 7694                upstream_project_id,
 7695                None,
 7696                LSP_REQUEST_TIMEOUT,
 7697                cx.background_executor().clone(),
 7698                request.to_proto(upstream_project_id, buffer.read(cx)),
 7699            );
 7700            let buffer = buffer.clone();
 7701            cx.spawn(async move |weak_lsp_store, cx| {
 7702                let lsp_store = weak_lsp_store.upgrade()?;
 7703                let hovers = join_all(
 7704                    request_task
 7705                        .await
 7706                        .log_err()
 7707                        .flatten()
 7708                        .map(|response| response.payload)
 7709                        .unwrap_or_default()
 7710                        .into_iter()
 7711                        .map(|response| {
 7712                            let response = GetHover { position }.response_from_proto(
 7713                                response.response,
 7714                                lsp_store.clone(),
 7715                                buffer.clone(),
 7716                                cx.clone(),
 7717                            );
 7718                            async move {
 7719                                response
 7720                                    .await
 7721                                    .log_err()
 7722                                    .flatten()
 7723                                    .and_then(remove_empty_hover_blocks)
 7724                            }
 7725                        }),
 7726                )
 7727                .await
 7728                .into_iter()
 7729                .flatten()
 7730                .collect();
 7731                Some(hovers)
 7732            })
 7733        } else {
 7734            let all_actions_task = self.request_multiple_lsp_locally(
 7735                buffer,
 7736                Some(position),
 7737                GetHover { position },
 7738                cx,
 7739            );
 7740            cx.background_spawn(async move {
 7741                Some(
 7742                    all_actions_task
 7743                        .await
 7744                        .into_iter()
 7745                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7746                        .collect::<Vec<Hover>>(),
 7747                )
 7748            })
 7749        }
 7750    }
 7751
 7752    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7753        let language_registry = self.languages.clone();
 7754
 7755        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7756            let request = upstream_client.request(proto::GetProjectSymbols {
 7757                project_id: *project_id,
 7758                query: query.to_string(),
 7759            });
 7760            cx.foreground_executor().spawn(async move {
 7761                let response = request.await?;
 7762                let mut symbols = Vec::new();
 7763                let core_symbols = response
 7764                    .symbols
 7765                    .into_iter()
 7766                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7767                    .collect::<Vec<_>>();
 7768                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7769                    .await;
 7770                Ok(symbols)
 7771            })
 7772        } else if let Some(local) = self.as_local() {
 7773            struct WorkspaceSymbolsResult {
 7774                server_id: LanguageServerId,
 7775                lsp_adapter: Arc<CachedLspAdapter>,
 7776                worktree: WeakEntity<Worktree>,
 7777                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7778            }
 7779
 7780            let mut requests = Vec::new();
 7781            let mut requested_servers = BTreeSet::new();
 7782            for (seed, state) in local.language_server_ids.iter() {
 7783                let Some(worktree_handle) = self
 7784                    .worktree_store
 7785                    .read(cx)
 7786                    .worktree_for_id(seed.worktree_id, cx)
 7787                else {
 7788                    continue;
 7789                };
 7790                let worktree = worktree_handle.read(cx);
 7791                if !worktree.is_visible() {
 7792                    continue;
 7793                }
 7794
 7795                if !requested_servers.insert(state.id) {
 7796                    continue;
 7797                }
 7798
 7799                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7800                    Some(LanguageServerState::Running {
 7801                        adapter, server, ..
 7802                    }) => (adapter.clone(), server),
 7803
 7804                    _ => continue,
 7805                };
 7806                let supports_workspace_symbol_request =
 7807                    match server.capabilities().workspace_symbol_provider {
 7808                        Some(OneOf::Left(supported)) => supported,
 7809                        Some(OneOf::Right(_)) => true,
 7810                        None => false,
 7811                    };
 7812                if !supports_workspace_symbol_request {
 7813                    continue;
 7814                }
 7815                let worktree_handle = worktree_handle.clone();
 7816                let server_id = server.server_id();
 7817                requests.push(
 7818                    server
 7819                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7820                            lsp::WorkspaceSymbolParams {
 7821                                query: query.to_string(),
 7822                                ..Default::default()
 7823                            },
 7824                        )
 7825                        .map(move |response| {
 7826                            let lsp_symbols = response
 7827                                .into_response()
 7828                                .context("workspace symbols request")
 7829                                .log_err()
 7830                                .flatten()
 7831                                .map(|symbol_response| match symbol_response {
 7832                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7833                                        flat_responses
 7834                                            .into_iter()
 7835                                            .map(|lsp_symbol| {
 7836                                                (
 7837                                                    lsp_symbol.name,
 7838                                                    lsp_symbol.kind,
 7839                                                    lsp_symbol.location,
 7840                                                )
 7841                                            })
 7842                                            .collect::<Vec<_>>()
 7843                                    }
 7844                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7845                                        nested_responses
 7846                                            .into_iter()
 7847                                            .filter_map(|lsp_symbol| {
 7848                                                let location = match lsp_symbol.location {
 7849                                                    OneOf::Left(location) => location,
 7850                                                    OneOf::Right(_) => {
 7851                                                        log::error!(
 7852                                                            "Unexpected: client capabilities \
 7853                                                            forbid symbol resolutions in \
 7854                                                            workspace.symbol.resolveSupport"
 7855                                                        );
 7856                                                        return None;
 7857                                                    }
 7858                                                };
 7859                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7860                                            })
 7861                                            .collect::<Vec<_>>()
 7862                                    }
 7863                                })
 7864                                .unwrap_or_default();
 7865
 7866                            WorkspaceSymbolsResult {
 7867                                server_id,
 7868                                lsp_adapter,
 7869                                worktree: worktree_handle.downgrade(),
 7870                                lsp_symbols,
 7871                            }
 7872                        }),
 7873                );
 7874            }
 7875
 7876            cx.spawn(async move |this, cx| {
 7877                let responses = futures::future::join_all(requests).await;
 7878                let this = match this.upgrade() {
 7879                    Some(this) => this,
 7880                    None => return Ok(Vec::new()),
 7881                };
 7882
 7883                let mut symbols = Vec::new();
 7884                for result in responses {
 7885                    let core_symbols = this.update(cx, |this, cx| {
 7886                        result
 7887                            .lsp_symbols
 7888                            .into_iter()
 7889                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7890                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7891                                let source_worktree = result.worktree.upgrade()?;
 7892                                let source_worktree_id = source_worktree.read(cx).id();
 7893
 7894                                let path = if let Some((tree, rel_path)) =
 7895                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7896                                {
 7897                                    let worktree_id = tree.read(cx).id();
 7898                                    SymbolLocation::InProject(ProjectPath {
 7899                                        worktree_id,
 7900                                        path: rel_path,
 7901                                    })
 7902                                } else {
 7903                                    SymbolLocation::OutsideProject {
 7904                                        signature: this.symbol_signature(&abs_path),
 7905                                        abs_path: abs_path.into(),
 7906                                    }
 7907                                };
 7908
 7909                                Some(CoreSymbol {
 7910                                    source_language_server_id: result.server_id,
 7911                                    language_server_name: result.lsp_adapter.name.clone(),
 7912                                    source_worktree_id,
 7913                                    path,
 7914                                    kind: symbol_kind,
 7915                                    name: symbol_name,
 7916                                    range: range_from_lsp(symbol_location.range),
 7917                                })
 7918                            })
 7919                            .collect::<Vec<_>>()
 7920                    });
 7921
 7922                    populate_labels_for_symbols(
 7923                        core_symbols,
 7924                        &language_registry,
 7925                        Some(result.lsp_adapter),
 7926                        &mut symbols,
 7927                    )
 7928                    .await;
 7929                }
 7930
 7931                Ok(symbols)
 7932            })
 7933        } else {
 7934            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7935        }
 7936    }
 7937
 7938    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7939        let mut summary = DiagnosticSummary::default();
 7940        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7941            summary.error_count += path_summary.error_count;
 7942            summary.warning_count += path_summary.warning_count;
 7943        }
 7944        summary
 7945    }
 7946
 7947    /// Returns the diagnostic summary for a specific project path.
 7948    pub fn diagnostic_summary_for_path(
 7949        &self,
 7950        project_path: &ProjectPath,
 7951        _: &App,
 7952    ) -> DiagnosticSummary {
 7953        if let Some(summaries) = self
 7954            .diagnostic_summaries
 7955            .get(&project_path.worktree_id)
 7956            .and_then(|map| map.get(&project_path.path))
 7957        {
 7958            let (error_count, warning_count) = summaries.iter().fold(
 7959                (0, 0),
 7960                |(error_count, warning_count), (_language_server_id, summary)| {
 7961                    (
 7962                        error_count + summary.error_count,
 7963                        warning_count + summary.warning_count,
 7964                    )
 7965                },
 7966            );
 7967
 7968            DiagnosticSummary {
 7969                error_count,
 7970                warning_count,
 7971            }
 7972        } else {
 7973            DiagnosticSummary::default()
 7974        }
 7975    }
 7976
 7977    pub fn diagnostic_summaries<'a>(
 7978        &'a self,
 7979        include_ignored: bool,
 7980        cx: &'a App,
 7981    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7982        self.worktree_store
 7983            .read(cx)
 7984            .visible_worktrees(cx)
 7985            .filter_map(|worktree| {
 7986                let worktree = worktree.read(cx);
 7987                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7988            })
 7989            .flat_map(move |(worktree, summaries)| {
 7990                let worktree_id = worktree.id();
 7991                summaries
 7992                    .iter()
 7993                    .filter(move |(path, _)| {
 7994                        include_ignored
 7995                            || worktree
 7996                                .entry_for_path(path.as_ref())
 7997                                .is_some_and(|entry| !entry.is_ignored)
 7998                    })
 7999                    .flat_map(move |(path, summaries)| {
 8000                        summaries.iter().map(move |(server_id, summary)| {
 8001                            (
 8002                                ProjectPath {
 8003                                    worktree_id,
 8004                                    path: path.clone(),
 8005                                },
 8006                                *server_id,
 8007                                *summary,
 8008                            )
 8009                        })
 8010                    })
 8011            })
 8012    }
 8013
 8014    pub fn on_buffer_edited(
 8015        &mut self,
 8016        buffer: Entity<Buffer>,
 8017        cx: &mut Context<Self>,
 8018    ) -> Option<()> {
 8019        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 8020            Some(
 8021                self.as_local()?
 8022                    .language_servers_for_buffer(buffer, cx)
 8023                    .map(|i| i.1.clone())
 8024                    .collect(),
 8025            )
 8026        })?;
 8027
 8028        let buffer = buffer.read(cx);
 8029        let file = File::from_dyn(buffer.file())?;
 8030        let abs_path = file.as_local()?.abs_path(cx);
 8031        let uri = lsp::Uri::from_file_path(&abs_path)
 8032            .ok()
 8033            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 8034            .log_err()?;
 8035        let next_snapshot = buffer.text_snapshot();
 8036        for language_server in language_servers {
 8037            let language_server = language_server.clone();
 8038
 8039            let buffer_snapshots = self
 8040                .as_local_mut()?
 8041                .buffer_snapshots
 8042                .get_mut(&buffer.remote_id())
 8043                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 8044            let previous_snapshot = buffer_snapshots.last()?;
 8045
 8046            let build_incremental_change = || {
 8047                buffer
 8048                    .edits_since::<Dimensions<PointUtf16, usize>>(
 8049                        previous_snapshot.snapshot.version(),
 8050                    )
 8051                    .map(|edit| {
 8052                        let edit_start = edit.new.start.0;
 8053                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 8054                        let new_text = next_snapshot
 8055                            .text_for_range(edit.new.start.1..edit.new.end.1)
 8056                            .collect();
 8057                        lsp::TextDocumentContentChangeEvent {
 8058                            range: Some(lsp::Range::new(
 8059                                point_to_lsp(edit_start),
 8060                                point_to_lsp(edit_end),
 8061                            )),
 8062                            range_length: None,
 8063                            text: new_text,
 8064                        }
 8065                    })
 8066                    .collect()
 8067            };
 8068
 8069            let document_sync_kind = language_server
 8070                .capabilities()
 8071                .text_document_sync
 8072                .as_ref()
 8073                .and_then(|sync| match sync {
 8074                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 8075                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 8076                });
 8077
 8078            let content_changes: Vec<_> = match document_sync_kind {
 8079                Some(lsp::TextDocumentSyncKind::FULL) => {
 8080                    vec![lsp::TextDocumentContentChangeEvent {
 8081                        range: None,
 8082                        range_length: None,
 8083                        text: next_snapshot.text(),
 8084                    }]
 8085                }
 8086                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8087                _ => {
 8088                    #[cfg(any(test, feature = "test-support"))]
 8089                    {
 8090                        build_incremental_change()
 8091                    }
 8092
 8093                    #[cfg(not(any(test, feature = "test-support")))]
 8094                    {
 8095                        continue;
 8096                    }
 8097                }
 8098            };
 8099
 8100            let next_version = previous_snapshot.version + 1;
 8101            buffer_snapshots.push(LspBufferSnapshot {
 8102                version: next_version,
 8103                snapshot: next_snapshot.clone(),
 8104            });
 8105
 8106            language_server
 8107                .notify::<lsp::notification::DidChangeTextDocument>(
 8108                    lsp::DidChangeTextDocumentParams {
 8109                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8110                            uri.clone(),
 8111                            next_version,
 8112                        ),
 8113                        content_changes,
 8114                    },
 8115                )
 8116                .ok();
 8117            self.pull_workspace_diagnostics(language_server.server_id());
 8118        }
 8119
 8120        None
 8121    }
 8122
 8123    pub fn on_buffer_saved(
 8124        &mut self,
 8125        buffer: Entity<Buffer>,
 8126        cx: &mut Context<Self>,
 8127    ) -> Option<()> {
 8128        let file = File::from_dyn(buffer.read(cx).file())?;
 8129        let worktree_id = file.worktree_id(cx);
 8130        let abs_path = file.as_local()?.abs_path(cx);
 8131        let text_document = lsp::TextDocumentIdentifier {
 8132            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8133        };
 8134        let local = self.as_local()?;
 8135
 8136        for server in local.language_servers_for_worktree(worktree_id) {
 8137            if let Some(include_text) = include_text(server.as_ref()) {
 8138                let text = if include_text {
 8139                    Some(buffer.read(cx).text())
 8140                } else {
 8141                    None
 8142                };
 8143                server
 8144                    .notify::<lsp::notification::DidSaveTextDocument>(
 8145                        lsp::DidSaveTextDocumentParams {
 8146                            text_document: text_document.clone(),
 8147                            text,
 8148                        },
 8149                    )
 8150                    .ok();
 8151            }
 8152        }
 8153
 8154        let language_servers = buffer.update(cx, |buffer, cx| {
 8155            local.language_server_ids_for_buffer(buffer, cx)
 8156        });
 8157        for language_server_id in language_servers {
 8158            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8159        }
 8160
 8161        None
 8162    }
 8163
 8164    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8165        maybe!(async move {
 8166            let mut refreshed_servers = HashSet::default();
 8167            let servers = lsp_store
 8168                .update(cx, |lsp_store, cx| {
 8169                    let local = lsp_store.as_local()?;
 8170
 8171                    let servers = local
 8172                        .language_server_ids
 8173                        .iter()
 8174                        .filter_map(|(seed, state)| {
 8175                            let worktree = lsp_store
 8176                                .worktree_store
 8177                                .read(cx)
 8178                                .worktree_for_id(seed.worktree_id, cx);
 8179                            let delegate: Arc<dyn LspAdapterDelegate> =
 8180                                worktree.map(|worktree| {
 8181                                    LocalLspAdapterDelegate::new(
 8182                                        local.languages.clone(),
 8183                                        &local.environment,
 8184                                        cx.weak_entity(),
 8185                                        &worktree,
 8186                                        local.http_client.clone(),
 8187                                        local.fs.clone(),
 8188                                        cx,
 8189                                    )
 8190                                })?;
 8191                            let server_id = state.id;
 8192
 8193                            let states = local.language_servers.get(&server_id)?;
 8194
 8195                            match states {
 8196                                LanguageServerState::Starting { .. } => None,
 8197                                LanguageServerState::Running {
 8198                                    adapter, server, ..
 8199                                } => {
 8200                                    let adapter = adapter.clone();
 8201                                    let server = server.clone();
 8202                                    refreshed_servers.insert(server.name());
 8203                                    let toolchain = seed.toolchain.clone();
 8204                                    Some(cx.spawn(async move |_, cx| {
 8205                                        let settings =
 8206                                            LocalLspStore::workspace_configuration_for_adapter(
 8207                                                adapter.adapter.clone(),
 8208                                                &delegate,
 8209                                                toolchain,
 8210                                                None,
 8211                                                cx,
 8212                                            )
 8213                                            .await
 8214                                            .ok()?;
 8215                                        server
 8216                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8217                                                lsp::DidChangeConfigurationParams { settings },
 8218                                            )
 8219                                            .ok()?;
 8220                                        Some(())
 8221                                    }))
 8222                                }
 8223                            }
 8224                        })
 8225                        .collect::<Vec<_>>();
 8226
 8227                    Some(servers)
 8228                })
 8229                .ok()
 8230                .flatten()?;
 8231
 8232            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8233            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8234            // to stop and unregister its language server wrapper.
 8235            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8236            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8237            let _: Vec<Option<()>> = join_all(servers).await;
 8238
 8239            Some(())
 8240        })
 8241        .await;
 8242    }
 8243
 8244    fn maintain_workspace_config(
 8245        external_refresh_requests: watch::Receiver<()>,
 8246        cx: &mut Context<Self>,
 8247    ) -> Task<Result<()>> {
 8248        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8249        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8250
 8251        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8252            *settings_changed_tx.borrow_mut() = ();
 8253        });
 8254
 8255        let mut joint_future =
 8256            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8257        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8258        // - 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).
 8259        // - 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.
 8260        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8261        // - 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,
 8262        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8263        cx.spawn(async move |this, cx| {
 8264            while let Some(()) = joint_future.next().await {
 8265                this.update(cx, |this, cx| {
 8266                    this.refresh_server_tree(cx);
 8267                })
 8268                .ok();
 8269
 8270                Self::refresh_workspace_configurations(&this, cx).await;
 8271            }
 8272
 8273            drop(settings_observation);
 8274            anyhow::Ok(())
 8275        })
 8276    }
 8277
 8278    pub fn running_language_servers_for_local_buffer<'a>(
 8279        &'a self,
 8280        buffer: &Buffer,
 8281        cx: &mut App,
 8282    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8283        let local = self.as_local();
 8284        let language_server_ids = local
 8285            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8286            .unwrap_or_default();
 8287
 8288        language_server_ids
 8289            .into_iter()
 8290            .filter_map(
 8291                move |server_id| match local?.language_servers.get(&server_id)? {
 8292                    LanguageServerState::Running {
 8293                        adapter, server, ..
 8294                    } => Some((adapter, server)),
 8295                    _ => None,
 8296                },
 8297            )
 8298    }
 8299
 8300    pub fn language_servers_for_local_buffer(
 8301        &self,
 8302        buffer: &Buffer,
 8303        cx: &mut App,
 8304    ) -> Vec<LanguageServerId> {
 8305        let local = self.as_local();
 8306        local
 8307            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8308            .unwrap_or_default()
 8309    }
 8310
 8311    pub fn language_server_for_local_buffer<'a>(
 8312        &'a self,
 8313        buffer: &'a Buffer,
 8314        server_id: LanguageServerId,
 8315        cx: &'a mut App,
 8316    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8317        self.as_local()?
 8318            .language_servers_for_buffer(buffer, cx)
 8319            .find(|(_, s)| s.server_id() == server_id)
 8320    }
 8321
 8322    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8323        self.diagnostic_summaries.remove(&id_to_remove);
 8324        if let Some(local) = self.as_local_mut() {
 8325            let to_remove = local.remove_worktree(id_to_remove, cx);
 8326            for server in to_remove {
 8327                self.language_server_statuses.remove(&server);
 8328            }
 8329        }
 8330    }
 8331
 8332    pub fn shared(
 8333        &mut self,
 8334        project_id: u64,
 8335        downstream_client: AnyProtoClient,
 8336        _: &mut Context<Self>,
 8337    ) {
 8338        self.downstream_client = Some((downstream_client.clone(), project_id));
 8339
 8340        for (server_id, status) in &self.language_server_statuses {
 8341            if let Some(server) = self.language_server_for_id(*server_id) {
 8342                downstream_client
 8343                    .send(proto::StartLanguageServer {
 8344                        project_id,
 8345                        server: Some(proto::LanguageServer {
 8346                            id: server_id.to_proto(),
 8347                            name: status.name.to_string(),
 8348                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8349                        }),
 8350                        capabilities: serde_json::to_string(&server.capabilities())
 8351                            .expect("serializing server LSP capabilities"),
 8352                    })
 8353                    .log_err();
 8354            }
 8355        }
 8356    }
 8357
 8358    pub fn disconnected_from_host(&mut self) {
 8359        self.downstream_client.take();
 8360    }
 8361
 8362    pub fn disconnected_from_ssh_remote(&mut self) {
 8363        if let LspStoreMode::Remote(RemoteLspStore {
 8364            upstream_client, ..
 8365        }) = &mut self.mode
 8366        {
 8367            upstream_client.take();
 8368        }
 8369    }
 8370
 8371    pub(crate) fn set_language_server_statuses_from_proto(
 8372        &mut self,
 8373        project: WeakEntity<Project>,
 8374        language_servers: Vec<proto::LanguageServer>,
 8375        server_capabilities: Vec<String>,
 8376        cx: &mut Context<Self>,
 8377    ) {
 8378        let lsp_logs = cx
 8379            .try_global::<GlobalLogStore>()
 8380            .map(|lsp_store| lsp_store.0.clone());
 8381
 8382        self.language_server_statuses = language_servers
 8383            .into_iter()
 8384            .zip(server_capabilities)
 8385            .map(|(server, server_capabilities)| {
 8386                let server_id = LanguageServerId(server.id as usize);
 8387                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8388                    self.lsp_server_capabilities
 8389                        .insert(server_id, server_capabilities);
 8390                }
 8391
 8392                let name = LanguageServerName::from_proto(server.name);
 8393                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8394
 8395                if let Some(lsp_logs) = &lsp_logs {
 8396                    lsp_logs.update(cx, |lsp_logs, cx| {
 8397                        lsp_logs.add_language_server(
 8398                            // Only remote clients get their language servers set from proto
 8399                            LanguageServerKind::Remote {
 8400                                project: project.clone(),
 8401                            },
 8402                            server_id,
 8403                            Some(name.clone()),
 8404                            worktree,
 8405                            None,
 8406                            cx,
 8407                        );
 8408                    });
 8409                }
 8410
 8411                (
 8412                    server_id,
 8413                    LanguageServerStatus {
 8414                        name,
 8415                        server_version: None,
 8416                        pending_work: Default::default(),
 8417                        has_pending_diagnostic_updates: false,
 8418                        progress_tokens: Default::default(),
 8419                        worktree,
 8420                        binary: None,
 8421                        configuration: None,
 8422                        workspace_folders: BTreeSet::new(),
 8423                    },
 8424                )
 8425            })
 8426            .collect();
 8427    }
 8428
 8429    #[cfg(test)]
 8430    pub fn update_diagnostic_entries(
 8431        &mut self,
 8432        server_id: LanguageServerId,
 8433        abs_path: PathBuf,
 8434        result_id: Option<SharedString>,
 8435        version: Option<i32>,
 8436        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8437        cx: &mut Context<Self>,
 8438    ) -> anyhow::Result<()> {
 8439        self.merge_diagnostic_entries(
 8440            vec![DocumentDiagnosticsUpdate {
 8441                diagnostics: DocumentDiagnostics {
 8442                    diagnostics,
 8443                    document_abs_path: abs_path,
 8444                    version,
 8445                },
 8446                result_id,
 8447                server_id,
 8448                disk_based_sources: Cow::Borrowed(&[]),
 8449                registration_id: None,
 8450            }],
 8451            |_, _, _| false,
 8452            cx,
 8453        )?;
 8454        Ok(())
 8455    }
 8456
 8457    pub fn merge_diagnostic_entries<'a>(
 8458        &mut self,
 8459        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8460        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8461        cx: &mut Context<Self>,
 8462    ) -> anyhow::Result<()> {
 8463        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8464        let mut updated_diagnostics_paths = HashMap::default();
 8465        for mut update in diagnostic_updates {
 8466            let abs_path = &update.diagnostics.document_abs_path;
 8467            let server_id = update.server_id;
 8468            let Some((worktree, relative_path)) =
 8469                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8470            else {
 8471                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8472                return Ok(());
 8473            };
 8474
 8475            let worktree_id = worktree.read(cx).id();
 8476            let project_path = ProjectPath {
 8477                worktree_id,
 8478                path: relative_path,
 8479            };
 8480
 8481            let document_uri = lsp::Uri::from_file_path(abs_path)
 8482                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8483            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8484                let snapshot = buffer_handle.read(cx).snapshot();
 8485                let buffer = buffer_handle.read(cx);
 8486                let reused_diagnostics = buffer
 8487                    .buffer_diagnostics(Some(server_id))
 8488                    .iter()
 8489                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8490                    .map(|v| {
 8491                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8492                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8493                        DiagnosticEntry {
 8494                            range: start..end,
 8495                            diagnostic: v.diagnostic.clone(),
 8496                        }
 8497                    })
 8498                    .collect::<Vec<_>>();
 8499
 8500                self.as_local_mut()
 8501                    .context("cannot merge diagnostics on a remote LspStore")?
 8502                    .update_buffer_diagnostics(
 8503                        &buffer_handle,
 8504                        server_id,
 8505                        Some(update.registration_id),
 8506                        update.result_id,
 8507                        update.diagnostics.version,
 8508                        update.diagnostics.diagnostics.clone(),
 8509                        reused_diagnostics.clone(),
 8510                        cx,
 8511                    )?;
 8512
 8513                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8514            } else if let Some(local) = self.as_local() {
 8515                let reused_diagnostics = local
 8516                    .diagnostics
 8517                    .get(&worktree_id)
 8518                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8519                    .and_then(|diagnostics_by_server_id| {
 8520                        diagnostics_by_server_id
 8521                            .binary_search_by_key(&server_id, |e| e.0)
 8522                            .ok()
 8523                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8524                    })
 8525                    .into_iter()
 8526                    .flatten()
 8527                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8528
 8529                update
 8530                    .diagnostics
 8531                    .diagnostics
 8532                    .extend(reused_diagnostics.cloned());
 8533            }
 8534
 8535            let updated = worktree.update(cx, |worktree, cx| {
 8536                self.update_worktree_diagnostics(
 8537                    worktree.id(),
 8538                    server_id,
 8539                    project_path.path.clone(),
 8540                    update.diagnostics.diagnostics,
 8541                    cx,
 8542                )
 8543            })?;
 8544            match updated {
 8545                ControlFlow::Continue(new_summary) => {
 8546                    if let Some((project_id, new_summary)) = new_summary {
 8547                        match &mut diagnostics_summary {
 8548                            Some(diagnostics_summary) => {
 8549                                diagnostics_summary
 8550                                    .more_summaries
 8551                                    .push(proto::DiagnosticSummary {
 8552                                        path: project_path.path.as_ref().to_proto(),
 8553                                        language_server_id: server_id.0 as u64,
 8554                                        error_count: new_summary.error_count,
 8555                                        warning_count: new_summary.warning_count,
 8556                                    })
 8557                            }
 8558                            None => {
 8559                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8560                                    project_id,
 8561                                    worktree_id: worktree_id.to_proto(),
 8562                                    summary: Some(proto::DiagnosticSummary {
 8563                                        path: project_path.path.as_ref().to_proto(),
 8564                                        language_server_id: server_id.0 as u64,
 8565                                        error_count: new_summary.error_count,
 8566                                        warning_count: new_summary.warning_count,
 8567                                    }),
 8568                                    more_summaries: Vec::new(),
 8569                                })
 8570                            }
 8571                        }
 8572                    }
 8573                    updated_diagnostics_paths
 8574                        .entry(server_id)
 8575                        .or_insert_with(Vec::new)
 8576                        .push(project_path);
 8577                }
 8578                ControlFlow::Break(()) => {}
 8579            }
 8580        }
 8581
 8582        if let Some((diagnostics_summary, (downstream_client, _))) =
 8583            diagnostics_summary.zip(self.downstream_client.as_ref())
 8584        {
 8585            downstream_client.send(diagnostics_summary).log_err();
 8586        }
 8587        for (server_id, paths) in updated_diagnostics_paths {
 8588            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8589        }
 8590        Ok(())
 8591    }
 8592
 8593    fn update_worktree_diagnostics(
 8594        &mut self,
 8595        worktree_id: WorktreeId,
 8596        server_id: LanguageServerId,
 8597        path_in_worktree: Arc<RelPath>,
 8598        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8599        _: &mut Context<Worktree>,
 8600    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8601        let local = match &mut self.mode {
 8602            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8603            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8604        };
 8605
 8606        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8607        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8608        let summaries_by_server_id = summaries_for_tree
 8609            .entry(path_in_worktree.clone())
 8610            .or_default();
 8611
 8612        let old_summary = summaries_by_server_id
 8613            .remove(&server_id)
 8614            .unwrap_or_default();
 8615
 8616        let new_summary = DiagnosticSummary::new(&diagnostics);
 8617        if diagnostics.is_empty() {
 8618            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8619            {
 8620                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8621                    diagnostics_by_server_id.remove(ix);
 8622                }
 8623                if diagnostics_by_server_id.is_empty() {
 8624                    diagnostics_for_tree.remove(&path_in_worktree);
 8625                }
 8626            }
 8627        } else {
 8628            summaries_by_server_id.insert(server_id, new_summary);
 8629            let diagnostics_by_server_id = diagnostics_for_tree
 8630                .entry(path_in_worktree.clone())
 8631                .or_default();
 8632            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8633                Ok(ix) => {
 8634                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8635                }
 8636                Err(ix) => {
 8637                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8638                }
 8639            }
 8640        }
 8641
 8642        if !old_summary.is_empty() || !new_summary.is_empty() {
 8643            if let Some((_, project_id)) = &self.downstream_client {
 8644                Ok(ControlFlow::Continue(Some((
 8645                    *project_id,
 8646                    proto::DiagnosticSummary {
 8647                        path: path_in_worktree.to_proto(),
 8648                        language_server_id: server_id.0 as u64,
 8649                        error_count: new_summary.error_count as u32,
 8650                        warning_count: new_summary.warning_count as u32,
 8651                    },
 8652                ))))
 8653            } else {
 8654                Ok(ControlFlow::Continue(None))
 8655            }
 8656        } else {
 8657            Ok(ControlFlow::Break(()))
 8658        }
 8659    }
 8660
 8661    pub fn open_buffer_for_symbol(
 8662        &mut self,
 8663        symbol: &Symbol,
 8664        cx: &mut Context<Self>,
 8665    ) -> Task<Result<Entity<Buffer>>> {
 8666        if let Some((client, project_id)) = self.upstream_client() {
 8667            let request = client.request(proto::OpenBufferForSymbol {
 8668                project_id,
 8669                symbol: Some(Self::serialize_symbol(symbol)),
 8670            });
 8671            cx.spawn(async move |this, cx| {
 8672                let response = request.await?;
 8673                let buffer_id = BufferId::new(response.buffer_id)?;
 8674                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8675                    .await
 8676            })
 8677        } else if let Some(local) = self.as_local() {
 8678            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8679                seed.worktree_id == symbol.source_worktree_id
 8680                    && state.id == symbol.source_language_server_id
 8681                    && symbol.language_server_name == seed.name
 8682            });
 8683            if !is_valid {
 8684                return Task::ready(Err(anyhow!(
 8685                    "language server for worktree and language not found"
 8686                )));
 8687            };
 8688
 8689            let symbol_abs_path = match &symbol.path {
 8690                SymbolLocation::InProject(project_path) => self
 8691                    .worktree_store
 8692                    .read(cx)
 8693                    .absolutize(&project_path, cx)
 8694                    .context("no such worktree"),
 8695                SymbolLocation::OutsideProject {
 8696                    abs_path,
 8697                    signature: _,
 8698                } => Ok(abs_path.to_path_buf()),
 8699            };
 8700            let symbol_abs_path = match symbol_abs_path {
 8701                Ok(abs_path) => abs_path,
 8702                Err(err) => return Task::ready(Err(err)),
 8703            };
 8704            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8705                uri
 8706            } else {
 8707                return Task::ready(Err(anyhow!("invalid symbol path")));
 8708            };
 8709
 8710            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8711        } else {
 8712            Task::ready(Err(anyhow!("no upstream client or local store")))
 8713        }
 8714    }
 8715
 8716    pub(crate) fn open_local_buffer_via_lsp(
 8717        &mut self,
 8718        abs_path: lsp::Uri,
 8719        language_server_id: LanguageServerId,
 8720        cx: &mut Context<Self>,
 8721    ) -> Task<Result<Entity<Buffer>>> {
 8722        cx.spawn(async move |lsp_store, cx| {
 8723            // Escape percent-encoded string.
 8724            let current_scheme = abs_path.scheme().to_owned();
 8725            // Uri is immutable, so we can't modify the scheme
 8726
 8727            let abs_path = abs_path
 8728                .to_file_path()
 8729                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8730            let p = abs_path.clone();
 8731            let yarn_worktree = lsp_store
 8732                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8733                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8734                        cx.spawn(async move |this, cx| {
 8735                            let t = this
 8736                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8737                                .ok()?;
 8738                            t.await
 8739                        })
 8740                    }),
 8741                    None => Task::ready(None),
 8742                })?
 8743                .await;
 8744            let (worktree_root_target, known_relative_path) =
 8745                if let Some((zip_root, relative_path)) = yarn_worktree {
 8746                    (zip_root, Some(relative_path))
 8747                } else {
 8748                    (Arc::<Path>::from(abs_path.as_path()), None)
 8749                };
 8750            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8751                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8752                    worktree_store.find_worktree(&worktree_root_target, cx)
 8753                })
 8754            })?;
 8755            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8756                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8757                (result.0, relative_path, None)
 8758            } else {
 8759                let worktree = lsp_store
 8760                    .update(cx, |lsp_store, cx| {
 8761                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8762                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8763                        })
 8764                    })?
 8765                    .await?;
 8766                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8767                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8768                    lsp_store
 8769                        .update(cx, |lsp_store, cx| {
 8770                            if let Some(local) = lsp_store.as_local_mut() {
 8771                                local.register_language_server_for_invisible_worktree(
 8772                                    &worktree,
 8773                                    language_server_id,
 8774                                    cx,
 8775                                )
 8776                            }
 8777                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8778                                Some(status) => status.worktree,
 8779                                None => None,
 8780                            }
 8781                        })
 8782                        .ok()
 8783                        .flatten()
 8784                        .zip(Some(worktree_root.clone()))
 8785                } else {
 8786                    None
 8787                };
 8788                let relative_path = if let Some(known_path) = known_relative_path {
 8789                    known_path
 8790                } else {
 8791                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8792                        .into_arc()
 8793                };
 8794                (worktree, relative_path, source_ws)
 8795            };
 8796            let project_path = ProjectPath {
 8797                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8798                path: relative_path,
 8799            };
 8800            let buffer = lsp_store
 8801                .update(cx, |lsp_store, cx| {
 8802                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8803                        buffer_store.open_buffer(project_path, cx)
 8804                    })
 8805                })?
 8806                .await?;
 8807            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8808            if let Some((source_ws, worktree_root)) = source_ws {
 8809                buffer.update(cx, |buffer, cx| {
 8810                    let settings = WorktreeSettings::get(
 8811                        Some(
 8812                            (&ProjectPath {
 8813                                worktree_id: source_ws,
 8814                                path: Arc::from(RelPath::empty()),
 8815                            })
 8816                                .into(),
 8817                        ),
 8818                        cx,
 8819                    );
 8820                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8821                    if is_read_only {
 8822                        buffer.set_capability(Capability::ReadOnly, cx);
 8823                    }
 8824                });
 8825            }
 8826            Ok(buffer)
 8827        })
 8828    }
 8829
 8830    fn request_multiple_lsp_locally<P, R>(
 8831        &mut self,
 8832        buffer: &Entity<Buffer>,
 8833        position: Option<P>,
 8834        request: R,
 8835        cx: &mut Context<Self>,
 8836    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8837    where
 8838        P: ToOffset,
 8839        R: LspCommand + Clone,
 8840        <R::LspRequest as lsp::request::Request>::Result: Send,
 8841        <R::LspRequest as lsp::request::Request>::Params: Send,
 8842    {
 8843        let Some(local) = self.as_local() else {
 8844            return Task::ready(Vec::new());
 8845        };
 8846
 8847        let snapshot = buffer.read(cx).snapshot();
 8848        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8849
 8850        let server_ids = buffer.update(cx, |buffer, cx| {
 8851            local
 8852                .language_servers_for_buffer(buffer, cx)
 8853                .filter(|(adapter, _)| {
 8854                    scope
 8855                        .as_ref()
 8856                        .map(|scope| scope.language_allowed(&adapter.name))
 8857                        .unwrap_or(true)
 8858                })
 8859                .map(|(_, server)| server.server_id())
 8860                .filter(|server_id| {
 8861                    self.as_local().is_none_or(|local| {
 8862                        local
 8863                            .buffers_opened_in_servers
 8864                            .get(&snapshot.remote_id())
 8865                            .is_some_and(|servers| servers.contains(server_id))
 8866                    })
 8867                })
 8868                .collect::<Vec<_>>()
 8869        });
 8870
 8871        let mut response_results = server_ids
 8872            .into_iter()
 8873            .map(|server_id| {
 8874                let task = self.request_lsp(
 8875                    buffer.clone(),
 8876                    LanguageServerToQuery::Other(server_id),
 8877                    request.clone(),
 8878                    cx,
 8879                );
 8880                async move { (server_id, task.await) }
 8881            })
 8882            .collect::<FuturesUnordered<_>>();
 8883
 8884        cx.background_spawn(async move {
 8885            let mut responses = Vec::with_capacity(response_results.len());
 8886            while let Some((server_id, response_result)) = response_results.next().await {
 8887                match response_result {
 8888                    Ok(response) => responses.push((server_id, response)),
 8889                    // rust-analyzer likes to error with this when its still loading up
 8890                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8891                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8892                }
 8893            }
 8894            responses
 8895        })
 8896    }
 8897
 8898    async fn handle_lsp_get_completions(
 8899        this: Entity<Self>,
 8900        envelope: TypedEnvelope<proto::GetCompletions>,
 8901        mut cx: AsyncApp,
 8902    ) -> Result<proto::GetCompletionsResponse> {
 8903        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8904
 8905        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8906        let buffer_handle = this.update(&mut cx, |this, cx| {
 8907            this.buffer_store.read(cx).get_existing(buffer_id)
 8908        })?;
 8909        let request = GetCompletions::from_proto(
 8910            envelope.payload,
 8911            this.clone(),
 8912            buffer_handle.clone(),
 8913            cx.clone(),
 8914        )
 8915        .await?;
 8916
 8917        let server_to_query = match request.server_id {
 8918            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8919            None => LanguageServerToQuery::FirstCapable,
 8920        };
 8921
 8922        let response = this
 8923            .update(&mut cx, |this, cx| {
 8924                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8925            })
 8926            .await?;
 8927        this.update(&mut cx, |this, cx| {
 8928            Ok(GetCompletions::response_to_proto(
 8929                response,
 8930                this,
 8931                sender_id,
 8932                &buffer_handle.read(cx).version(),
 8933                cx,
 8934            ))
 8935        })
 8936    }
 8937
 8938    async fn handle_lsp_command<T: LspCommand>(
 8939        this: Entity<Self>,
 8940        envelope: TypedEnvelope<T::ProtoRequest>,
 8941        mut cx: AsyncApp,
 8942    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8943    where
 8944        <T::LspRequest as lsp::request::Request>::Params: Send,
 8945        <T::LspRequest as lsp::request::Request>::Result: Send,
 8946    {
 8947        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8948        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8949        let buffer_handle = this.update(&mut cx, |this, cx| {
 8950            this.buffer_store.read(cx).get_existing(buffer_id)
 8951        })?;
 8952        let request = T::from_proto(
 8953            envelope.payload,
 8954            this.clone(),
 8955            buffer_handle.clone(),
 8956            cx.clone(),
 8957        )
 8958        .await?;
 8959        let response = this
 8960            .update(&mut cx, |this, cx| {
 8961                this.request_lsp(
 8962                    buffer_handle.clone(),
 8963                    LanguageServerToQuery::FirstCapable,
 8964                    request,
 8965                    cx,
 8966                )
 8967            })
 8968            .await?;
 8969        this.update(&mut cx, |this, cx| {
 8970            Ok(T::response_to_proto(
 8971                response,
 8972                this,
 8973                sender_id,
 8974                &buffer_handle.read(cx).version(),
 8975                cx,
 8976            ))
 8977        })
 8978    }
 8979
 8980    async fn handle_lsp_query(
 8981        lsp_store: Entity<Self>,
 8982        envelope: TypedEnvelope<proto::LspQuery>,
 8983        mut cx: AsyncApp,
 8984    ) -> Result<proto::Ack> {
 8985        use proto::lsp_query::Request;
 8986        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8987        let lsp_query = envelope.payload;
 8988        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8989        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8990        match lsp_query.request.context("invalid LSP query request")? {
 8991            Request::GetReferences(get_references) => {
 8992                let position = get_references.position.clone().and_then(deserialize_anchor);
 8993                Self::query_lsp_locally::<GetReferences>(
 8994                    lsp_store,
 8995                    server_id,
 8996                    sender_id,
 8997                    lsp_request_id,
 8998                    get_references,
 8999                    position,
 9000                    &mut cx,
 9001                )
 9002                .await?;
 9003            }
 9004            Request::GetDocumentColor(get_document_color) => {
 9005                Self::query_lsp_locally::<GetDocumentColor>(
 9006                    lsp_store,
 9007                    server_id,
 9008                    sender_id,
 9009                    lsp_request_id,
 9010                    get_document_color,
 9011                    None,
 9012                    &mut cx,
 9013                )
 9014                .await?;
 9015            }
 9016            Request::GetHover(get_hover) => {
 9017                let position = get_hover.position.clone().and_then(deserialize_anchor);
 9018                Self::query_lsp_locally::<GetHover>(
 9019                    lsp_store,
 9020                    server_id,
 9021                    sender_id,
 9022                    lsp_request_id,
 9023                    get_hover,
 9024                    position,
 9025                    &mut cx,
 9026                )
 9027                .await?;
 9028            }
 9029            Request::GetCodeActions(get_code_actions) => {
 9030                Self::query_lsp_locally::<GetCodeActions>(
 9031                    lsp_store,
 9032                    server_id,
 9033                    sender_id,
 9034                    lsp_request_id,
 9035                    get_code_actions,
 9036                    None,
 9037                    &mut cx,
 9038                )
 9039                .await?;
 9040            }
 9041            Request::GetSignatureHelp(get_signature_help) => {
 9042                let position = get_signature_help
 9043                    .position
 9044                    .clone()
 9045                    .and_then(deserialize_anchor);
 9046                Self::query_lsp_locally::<GetSignatureHelp>(
 9047                    lsp_store,
 9048                    server_id,
 9049                    sender_id,
 9050                    lsp_request_id,
 9051                    get_signature_help,
 9052                    position,
 9053                    &mut cx,
 9054                )
 9055                .await?;
 9056            }
 9057            Request::GetCodeLens(get_code_lens) => {
 9058                Self::query_lsp_locally::<GetCodeLens>(
 9059                    lsp_store,
 9060                    server_id,
 9061                    sender_id,
 9062                    lsp_request_id,
 9063                    get_code_lens,
 9064                    None,
 9065                    &mut cx,
 9066                )
 9067                .await?;
 9068            }
 9069            Request::GetDefinition(get_definition) => {
 9070                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9071                Self::query_lsp_locally::<GetDefinitions>(
 9072                    lsp_store,
 9073                    server_id,
 9074                    sender_id,
 9075                    lsp_request_id,
 9076                    get_definition,
 9077                    position,
 9078                    &mut cx,
 9079                )
 9080                .await?;
 9081            }
 9082            Request::GetDeclaration(get_declaration) => {
 9083                let position = get_declaration
 9084                    .position
 9085                    .clone()
 9086                    .and_then(deserialize_anchor);
 9087                Self::query_lsp_locally::<GetDeclarations>(
 9088                    lsp_store,
 9089                    server_id,
 9090                    sender_id,
 9091                    lsp_request_id,
 9092                    get_declaration,
 9093                    position,
 9094                    &mut cx,
 9095                )
 9096                .await?;
 9097            }
 9098            Request::GetTypeDefinition(get_type_definition) => {
 9099                let position = get_type_definition
 9100                    .position
 9101                    .clone()
 9102                    .and_then(deserialize_anchor);
 9103                Self::query_lsp_locally::<GetTypeDefinitions>(
 9104                    lsp_store,
 9105                    server_id,
 9106                    sender_id,
 9107                    lsp_request_id,
 9108                    get_type_definition,
 9109                    position,
 9110                    &mut cx,
 9111                )
 9112                .await?;
 9113            }
 9114            Request::GetImplementation(get_implementation) => {
 9115                let position = get_implementation
 9116                    .position
 9117                    .clone()
 9118                    .and_then(deserialize_anchor);
 9119                Self::query_lsp_locally::<GetImplementations>(
 9120                    lsp_store,
 9121                    server_id,
 9122                    sender_id,
 9123                    lsp_request_id,
 9124                    get_implementation,
 9125                    position,
 9126                    &mut cx,
 9127                )
 9128                .await?;
 9129            }
 9130            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9131                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 9132                let version = deserialize_version(get_document_diagnostics.buffer_version());
 9133                let buffer = lsp_store.update(&mut cx, |this, cx| {
 9134                    this.buffer_store.read(cx).get_existing(buffer_id)
 9135                })?;
 9136                buffer
 9137                    .update(&mut cx, |buffer, _| {
 9138                        buffer.wait_for_version(version.clone())
 9139                    })
 9140                    .await?;
 9141                lsp_store.update(&mut cx, |lsp_store, cx| {
 9142                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9143                    let key = LspKey {
 9144                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9145                        server_queried: server_id,
 9146                    };
 9147                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9148                    ) {
 9149                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9150                            lsp_requests.clear();
 9151                        };
 9152                    }
 9153
 9154                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 9155                    existing_queries.insert(
 9156                        lsp_request_id,
 9157                        cx.spawn(async move |lsp_store, cx| {
 9158                            let diagnostics_pull = lsp_store.update(cx, |lsp_store, cx| {
 9159                                lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9160                            });
 9161                            if let Ok(diagnostics_pull) = diagnostics_pull {
 9162                                match diagnostics_pull.await {
 9163                                    Ok(()) => {}
 9164                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9165                                };
 9166                            }
 9167                        }),
 9168                    );
 9169                });
 9170            }
 9171            Request::InlayHints(inlay_hints) => {
 9172                let query_start = inlay_hints
 9173                    .start
 9174                    .clone()
 9175                    .and_then(deserialize_anchor)
 9176                    .context("invalid inlay hints range start")?;
 9177                let query_end = inlay_hints
 9178                    .end
 9179                    .clone()
 9180                    .and_then(deserialize_anchor)
 9181                    .context("invalid inlay hints range end")?;
 9182                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9183                    &lsp_store,
 9184                    server_id,
 9185                    lsp_request_id,
 9186                    &inlay_hints,
 9187                    query_start..query_end,
 9188                    &mut cx,
 9189                )
 9190                .await
 9191                .context("preparing inlay hints request")?;
 9192                Self::query_lsp_locally::<InlayHints>(
 9193                    lsp_store,
 9194                    server_id,
 9195                    sender_id,
 9196                    lsp_request_id,
 9197                    inlay_hints,
 9198                    None,
 9199                    &mut cx,
 9200                )
 9201                .await
 9202                .context("querying for inlay hints")?
 9203            }
 9204        }
 9205        Ok(proto::Ack {})
 9206    }
 9207
 9208    async fn handle_lsp_query_response(
 9209        lsp_store: Entity<Self>,
 9210        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9211        cx: AsyncApp,
 9212    ) -> Result<()> {
 9213        lsp_store.read_with(&cx, |lsp_store, _| {
 9214            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9215                upstream_client.handle_lsp_response(envelope.clone());
 9216            }
 9217        });
 9218        Ok(())
 9219    }
 9220
 9221    async fn handle_apply_code_action(
 9222        this: Entity<Self>,
 9223        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9224        mut cx: AsyncApp,
 9225    ) -> Result<proto::ApplyCodeActionResponse> {
 9226        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9227        let action =
 9228            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9229        let apply_code_action = this.update(&mut cx, |this, cx| {
 9230            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9231            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9232            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9233        })?;
 9234
 9235        let project_transaction = apply_code_action.await?;
 9236        let project_transaction = this.update(&mut cx, |this, cx| {
 9237            this.buffer_store.update(cx, |buffer_store, cx| {
 9238                buffer_store.serialize_project_transaction_for_peer(
 9239                    project_transaction,
 9240                    sender_id,
 9241                    cx,
 9242                )
 9243            })
 9244        });
 9245        Ok(proto::ApplyCodeActionResponse {
 9246            transaction: Some(project_transaction),
 9247        })
 9248    }
 9249
 9250    async fn handle_register_buffer_with_language_servers(
 9251        this: Entity<Self>,
 9252        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9253        mut cx: AsyncApp,
 9254    ) -> Result<proto::Ack> {
 9255        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9256        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9257        this.update(&mut cx, |this, cx| {
 9258            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9259                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9260                    project_id: upstream_project_id,
 9261                    buffer_id: buffer_id.to_proto(),
 9262                    only_servers: envelope.payload.only_servers,
 9263                });
 9264            }
 9265
 9266            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9267                anyhow::bail!("buffer is not open");
 9268            };
 9269
 9270            let handle = this.register_buffer_with_language_servers(
 9271                &buffer,
 9272                envelope
 9273                    .payload
 9274                    .only_servers
 9275                    .into_iter()
 9276                    .filter_map(|selector| {
 9277                        Some(match selector.selector? {
 9278                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9279                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9280                            }
 9281                            proto::language_server_selector::Selector::Name(name) => {
 9282                                LanguageServerSelector::Name(LanguageServerName(
 9283                                    SharedString::from(name),
 9284                                ))
 9285                            }
 9286                        })
 9287                    })
 9288                    .collect(),
 9289                false,
 9290                cx,
 9291            );
 9292            this.buffer_store().update(cx, |buffer_store, _| {
 9293                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9294            });
 9295
 9296            Ok(())
 9297        })?;
 9298        Ok(proto::Ack {})
 9299    }
 9300
 9301    async fn handle_rename_project_entry(
 9302        this: Entity<Self>,
 9303        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9304        mut cx: AsyncApp,
 9305    ) -> Result<proto::ProjectEntryResponse> {
 9306        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9307        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9308        let new_path =
 9309            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9310
 9311        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9312            .update(&mut cx, |this, cx| {
 9313                let (worktree, entry) = this
 9314                    .worktree_store
 9315                    .read(cx)
 9316                    .worktree_and_entry_for_id(entry_id, cx)?;
 9317                let new_worktree = this
 9318                    .worktree_store
 9319                    .read(cx)
 9320                    .worktree_for_id(new_worktree_id, cx)?;
 9321                Some((
 9322                    this.worktree_store.clone(),
 9323                    worktree,
 9324                    new_worktree,
 9325                    entry.clone(),
 9326                ))
 9327            })
 9328            .context("worktree not found")?;
 9329        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9330            (worktree.absolutize(&old_entry.path), worktree.id())
 9331        });
 9332        let new_abs_path =
 9333            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9334
 9335        let _transaction = Self::will_rename_entry(
 9336            this.downgrade(),
 9337            old_worktree_id,
 9338            &old_abs_path,
 9339            &new_abs_path,
 9340            old_entry.is_dir(),
 9341            cx.clone(),
 9342        )
 9343        .await;
 9344        let response = WorktreeStore::handle_rename_project_entry(
 9345            worktree_store,
 9346            envelope.payload,
 9347            cx.clone(),
 9348        )
 9349        .await;
 9350        this.read_with(&cx, |this, _| {
 9351            this.did_rename_entry(
 9352                old_worktree_id,
 9353                &old_abs_path,
 9354                &new_abs_path,
 9355                old_entry.is_dir(),
 9356            );
 9357        });
 9358        response
 9359    }
 9360
 9361    async fn handle_update_diagnostic_summary(
 9362        this: Entity<Self>,
 9363        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9364        mut cx: AsyncApp,
 9365    ) -> Result<()> {
 9366        this.update(&mut cx, |lsp_store, cx| {
 9367            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9368            let mut updated_diagnostics_paths = HashMap::default();
 9369            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9370            for message_summary in envelope
 9371                .payload
 9372                .summary
 9373                .into_iter()
 9374                .chain(envelope.payload.more_summaries)
 9375            {
 9376                let project_path = ProjectPath {
 9377                    worktree_id,
 9378                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9379                };
 9380                let path = project_path.path.clone();
 9381                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9382                let summary = DiagnosticSummary {
 9383                    error_count: message_summary.error_count as usize,
 9384                    warning_count: message_summary.warning_count as usize,
 9385                };
 9386
 9387                if summary.is_empty() {
 9388                    if let Some(worktree_summaries) =
 9389                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9390                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9391                    {
 9392                        summaries.remove(&server_id);
 9393                        if summaries.is_empty() {
 9394                            worktree_summaries.remove(&path);
 9395                        }
 9396                    }
 9397                } else {
 9398                    lsp_store
 9399                        .diagnostic_summaries
 9400                        .entry(worktree_id)
 9401                        .or_default()
 9402                        .entry(path)
 9403                        .or_default()
 9404                        .insert(server_id, summary);
 9405                }
 9406
 9407                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9408                    match &mut diagnostics_summary {
 9409                        Some(diagnostics_summary) => {
 9410                            diagnostics_summary
 9411                                .more_summaries
 9412                                .push(proto::DiagnosticSummary {
 9413                                    path: project_path.path.as_ref().to_proto(),
 9414                                    language_server_id: server_id.0 as u64,
 9415                                    error_count: summary.error_count as u32,
 9416                                    warning_count: summary.warning_count as u32,
 9417                                })
 9418                        }
 9419                        None => {
 9420                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9421                                project_id: *project_id,
 9422                                worktree_id: worktree_id.to_proto(),
 9423                                summary: Some(proto::DiagnosticSummary {
 9424                                    path: project_path.path.as_ref().to_proto(),
 9425                                    language_server_id: server_id.0 as u64,
 9426                                    error_count: summary.error_count as u32,
 9427                                    warning_count: summary.warning_count as u32,
 9428                                }),
 9429                                more_summaries: Vec::new(),
 9430                            })
 9431                        }
 9432                    }
 9433                }
 9434                updated_diagnostics_paths
 9435                    .entry(server_id)
 9436                    .or_insert_with(Vec::new)
 9437                    .push(project_path);
 9438            }
 9439
 9440            if let Some((diagnostics_summary, (downstream_client, _))) =
 9441                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9442            {
 9443                downstream_client.send(diagnostics_summary).log_err();
 9444            }
 9445            for (server_id, paths) in updated_diagnostics_paths {
 9446                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9447            }
 9448            Ok(())
 9449        })
 9450    }
 9451
 9452    async fn handle_start_language_server(
 9453        lsp_store: Entity<Self>,
 9454        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9455        mut cx: AsyncApp,
 9456    ) -> Result<()> {
 9457        let server = envelope.payload.server.context("invalid server")?;
 9458        let server_capabilities =
 9459            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9460                .with_context(|| {
 9461                    format!(
 9462                        "incorrect server capabilities {}",
 9463                        envelope.payload.capabilities
 9464                    )
 9465                })?;
 9466        lsp_store.update(&mut cx, |lsp_store, cx| {
 9467            let server_id = LanguageServerId(server.id as usize);
 9468            let server_name = LanguageServerName::from_proto(server.name.clone());
 9469            lsp_store
 9470                .lsp_server_capabilities
 9471                .insert(server_id, server_capabilities);
 9472            lsp_store.language_server_statuses.insert(
 9473                server_id,
 9474                LanguageServerStatus {
 9475                    name: server_name.clone(),
 9476                    server_version: None,
 9477                    pending_work: Default::default(),
 9478                    has_pending_diagnostic_updates: false,
 9479                    progress_tokens: Default::default(),
 9480                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9481                    binary: None,
 9482                    configuration: None,
 9483                    workspace_folders: BTreeSet::new(),
 9484                },
 9485            );
 9486            cx.emit(LspStoreEvent::LanguageServerAdded(
 9487                server_id,
 9488                server_name,
 9489                server.worktree_id.map(WorktreeId::from_proto),
 9490            ));
 9491            cx.notify();
 9492        });
 9493        Ok(())
 9494    }
 9495
 9496    async fn handle_update_language_server(
 9497        lsp_store: Entity<Self>,
 9498        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9499        mut cx: AsyncApp,
 9500    ) -> Result<()> {
 9501        lsp_store.update(&mut cx, |lsp_store, cx| {
 9502            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9503
 9504            match envelope.payload.variant.context("invalid variant")? {
 9505                proto::update_language_server::Variant::WorkStart(payload) => {
 9506                    lsp_store.on_lsp_work_start(
 9507                        language_server_id,
 9508                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9509                            .context("invalid progress token value")?,
 9510                        LanguageServerProgress {
 9511                            title: payload.title,
 9512                            is_disk_based_diagnostics_progress: false,
 9513                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9514                            message: payload.message,
 9515                            percentage: payload.percentage.map(|p| p as usize),
 9516                            last_update_at: cx.background_executor().now(),
 9517                        },
 9518                        cx,
 9519                    );
 9520                }
 9521                proto::update_language_server::Variant::WorkProgress(payload) => {
 9522                    lsp_store.on_lsp_work_progress(
 9523                        language_server_id,
 9524                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9525                            .context("invalid progress token value")?,
 9526                        LanguageServerProgress {
 9527                            title: None,
 9528                            is_disk_based_diagnostics_progress: false,
 9529                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9530                            message: payload.message,
 9531                            percentage: payload.percentage.map(|p| p as usize),
 9532                            last_update_at: cx.background_executor().now(),
 9533                        },
 9534                        cx,
 9535                    );
 9536                }
 9537
 9538                proto::update_language_server::Variant::WorkEnd(payload) => {
 9539                    lsp_store.on_lsp_work_end(
 9540                        language_server_id,
 9541                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9542                            .context("invalid progress token value")?,
 9543                        cx,
 9544                    );
 9545                }
 9546
 9547                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9548                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9549                }
 9550
 9551                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9552                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9553                }
 9554
 9555                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9556                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9557                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9558                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9559                        language_server_id,
 9560                        name: envelope
 9561                            .payload
 9562                            .server_name
 9563                            .map(SharedString::new)
 9564                            .map(LanguageServerName),
 9565                        message: non_lsp,
 9566                    });
 9567                }
 9568            }
 9569
 9570            Ok(())
 9571        })
 9572    }
 9573
 9574    async fn handle_language_server_log(
 9575        this: Entity<Self>,
 9576        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9577        mut cx: AsyncApp,
 9578    ) -> Result<()> {
 9579        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9580        let log_type = envelope
 9581            .payload
 9582            .log_type
 9583            .map(LanguageServerLogType::from_proto)
 9584            .context("invalid language server log type")?;
 9585
 9586        let message = envelope.payload.message;
 9587
 9588        this.update(&mut cx, |_, cx| {
 9589            cx.emit(LspStoreEvent::LanguageServerLog(
 9590                language_server_id,
 9591                log_type,
 9592                message,
 9593            ));
 9594        });
 9595        Ok(())
 9596    }
 9597
 9598    async fn handle_lsp_ext_cancel_flycheck(
 9599        lsp_store: Entity<Self>,
 9600        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9601        cx: AsyncApp,
 9602    ) -> Result<proto::Ack> {
 9603        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9604        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9605            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9606                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9607            } else {
 9608                None
 9609            }
 9610        });
 9611        if let Some(task) = task {
 9612            task.context("handling lsp ext cancel flycheck")?;
 9613        }
 9614
 9615        Ok(proto::Ack {})
 9616    }
 9617
 9618    async fn handle_lsp_ext_run_flycheck(
 9619        lsp_store: Entity<Self>,
 9620        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9621        mut cx: AsyncApp,
 9622    ) -> Result<proto::Ack> {
 9623        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9624        lsp_store.update(&mut cx, |lsp_store, cx| {
 9625            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9626                let text_document = if envelope.payload.current_file_only {
 9627                    let buffer_id = envelope
 9628                        .payload
 9629                        .buffer_id
 9630                        .map(|id| BufferId::new(id))
 9631                        .transpose()?;
 9632                    buffer_id
 9633                        .and_then(|buffer_id| {
 9634                            lsp_store
 9635                                .buffer_store()
 9636                                .read(cx)
 9637                                .get(buffer_id)
 9638                                .and_then(|buffer| {
 9639                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9640                                })
 9641                                .map(|path| make_text_document_identifier(&path))
 9642                        })
 9643                        .transpose()?
 9644                } else {
 9645                    None
 9646                };
 9647                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9648                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9649                )?;
 9650            }
 9651            anyhow::Ok(())
 9652        })?;
 9653
 9654        Ok(proto::Ack {})
 9655    }
 9656
 9657    async fn handle_lsp_ext_clear_flycheck(
 9658        lsp_store: Entity<Self>,
 9659        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9660        cx: AsyncApp,
 9661    ) -> Result<proto::Ack> {
 9662        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9663        lsp_store.read_with(&cx, |lsp_store, _| {
 9664            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9665                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9666            } else {
 9667                None
 9668            }
 9669        });
 9670
 9671        Ok(proto::Ack {})
 9672    }
 9673
 9674    pub fn disk_based_diagnostics_started(
 9675        &mut self,
 9676        language_server_id: LanguageServerId,
 9677        cx: &mut Context<Self>,
 9678    ) {
 9679        if let Some(language_server_status) =
 9680            self.language_server_statuses.get_mut(&language_server_id)
 9681        {
 9682            language_server_status.has_pending_diagnostic_updates = true;
 9683        }
 9684
 9685        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9686        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9687            language_server_id,
 9688            name: self
 9689                .language_server_adapter_for_id(language_server_id)
 9690                .map(|adapter| adapter.name()),
 9691            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9692                Default::default(),
 9693            ),
 9694        })
 9695    }
 9696
 9697    pub fn disk_based_diagnostics_finished(
 9698        &mut self,
 9699        language_server_id: LanguageServerId,
 9700        cx: &mut Context<Self>,
 9701    ) {
 9702        if let Some(language_server_status) =
 9703            self.language_server_statuses.get_mut(&language_server_id)
 9704        {
 9705            language_server_status.has_pending_diagnostic_updates = false;
 9706        }
 9707
 9708        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9709        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9710            language_server_id,
 9711            name: self
 9712                .language_server_adapter_for_id(language_server_id)
 9713                .map(|adapter| adapter.name()),
 9714            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9715                Default::default(),
 9716            ),
 9717        })
 9718    }
 9719
 9720    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9721    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9722    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9723    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9724    // the language server might take some time to publish diagnostics.
 9725    fn simulate_disk_based_diagnostics_events_if_needed(
 9726        &mut self,
 9727        language_server_id: LanguageServerId,
 9728        cx: &mut Context<Self>,
 9729    ) {
 9730        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9731
 9732        let Some(LanguageServerState::Running {
 9733            simulate_disk_based_diagnostics_completion,
 9734            adapter,
 9735            ..
 9736        }) = self
 9737            .as_local_mut()
 9738            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9739        else {
 9740            return;
 9741        };
 9742
 9743        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9744            return;
 9745        }
 9746
 9747        let prev_task =
 9748            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9749                cx.background_executor()
 9750                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9751                    .await;
 9752
 9753                this.update(cx, |this, cx| {
 9754                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9755
 9756                    if let Some(LanguageServerState::Running {
 9757                        simulate_disk_based_diagnostics_completion,
 9758                        ..
 9759                    }) = this.as_local_mut().and_then(|local_store| {
 9760                        local_store.language_servers.get_mut(&language_server_id)
 9761                    }) {
 9762                        *simulate_disk_based_diagnostics_completion = None;
 9763                    }
 9764                })
 9765                .ok();
 9766            }));
 9767
 9768        if prev_task.is_none() {
 9769            self.disk_based_diagnostics_started(language_server_id, cx);
 9770        }
 9771    }
 9772
 9773    pub fn language_server_statuses(
 9774        &self,
 9775    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9776        self.language_server_statuses
 9777            .iter()
 9778            .map(|(key, value)| (*key, value))
 9779    }
 9780
 9781    pub(super) fn did_rename_entry(
 9782        &self,
 9783        worktree_id: WorktreeId,
 9784        old_path: &Path,
 9785        new_path: &Path,
 9786        is_dir: bool,
 9787    ) {
 9788        maybe!({
 9789            let local_store = self.as_local()?;
 9790
 9791            let old_uri = lsp::Uri::from_file_path(old_path)
 9792                .ok()
 9793                .map(|uri| uri.to_string())?;
 9794            let new_uri = lsp::Uri::from_file_path(new_path)
 9795                .ok()
 9796                .map(|uri| uri.to_string())?;
 9797
 9798            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9799                let Some(filter) = local_store
 9800                    .language_server_paths_watched_for_rename
 9801                    .get(&language_server.server_id())
 9802                else {
 9803                    continue;
 9804                };
 9805
 9806                if filter.should_send_did_rename(&old_uri, is_dir) {
 9807                    language_server
 9808                        .notify::<DidRenameFiles>(RenameFilesParams {
 9809                            files: vec![FileRename {
 9810                                old_uri: old_uri.clone(),
 9811                                new_uri: new_uri.clone(),
 9812                            }],
 9813                        })
 9814                        .ok();
 9815                }
 9816            }
 9817            Some(())
 9818        });
 9819    }
 9820
 9821    pub(super) fn will_rename_entry(
 9822        this: WeakEntity<Self>,
 9823        worktree_id: WorktreeId,
 9824        old_path: &Path,
 9825        new_path: &Path,
 9826        is_dir: bool,
 9827        cx: AsyncApp,
 9828    ) -> Task<ProjectTransaction> {
 9829        let old_uri = lsp::Uri::from_file_path(old_path)
 9830            .ok()
 9831            .map(|uri| uri.to_string());
 9832        let new_uri = lsp::Uri::from_file_path(new_path)
 9833            .ok()
 9834            .map(|uri| uri.to_string());
 9835        cx.spawn(async move |cx| {
 9836            let mut tasks = vec![];
 9837            this.update(cx, |this, cx| {
 9838                let local_store = this.as_local()?;
 9839                let old_uri = old_uri?;
 9840                let new_uri = new_uri?;
 9841                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9842                    let Some(filter) = local_store
 9843                        .language_server_paths_watched_for_rename
 9844                        .get(&language_server.server_id())
 9845                    else {
 9846                        continue;
 9847                    };
 9848
 9849                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9850                        let apply_edit = cx.spawn({
 9851                            let old_uri = old_uri.clone();
 9852                            let new_uri = new_uri.clone();
 9853                            let language_server = language_server.clone();
 9854                            async move |this, cx| {
 9855                                let edit = language_server
 9856                                    .request::<WillRenameFiles>(RenameFilesParams {
 9857                                        files: vec![FileRename { old_uri, new_uri }],
 9858                                    })
 9859                                    .await
 9860                                    .into_response()
 9861                                    .context("will rename files")
 9862                                    .log_err()
 9863                                    .flatten()?;
 9864
 9865                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9866                                    this.upgrade()?,
 9867                                    edit,
 9868                                    false,
 9869                                    language_server.clone(),
 9870                                    cx,
 9871                                )
 9872                                .await
 9873                                .ok()?;
 9874                                Some(transaction)
 9875                            }
 9876                        });
 9877                        tasks.push(apply_edit);
 9878                    }
 9879                }
 9880                Some(())
 9881            })
 9882            .ok()
 9883            .flatten();
 9884            let mut merged_transaction = ProjectTransaction::default();
 9885            for task in tasks {
 9886                // Await on tasks sequentially so that the order of application of edits is deterministic
 9887                // (at least with regards to the order of registration of language servers)
 9888                if let Some(transaction) = task.await {
 9889                    for (buffer, buffer_transaction) in transaction.0 {
 9890                        merged_transaction.0.insert(buffer, buffer_transaction);
 9891                    }
 9892                }
 9893            }
 9894            merged_transaction
 9895        })
 9896    }
 9897
 9898    fn lsp_notify_abs_paths_changed(
 9899        &mut self,
 9900        server_id: LanguageServerId,
 9901        changes: Vec<PathEvent>,
 9902    ) {
 9903        maybe!({
 9904            let server = self.language_server_for_id(server_id)?;
 9905            let changes = changes
 9906                .into_iter()
 9907                .filter_map(|event| {
 9908                    let typ = match event.kind? {
 9909                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9910                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9911                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9912                    };
 9913                    Some(lsp::FileEvent {
 9914                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9915                        typ,
 9916                    })
 9917                })
 9918                .collect::<Vec<_>>();
 9919            if !changes.is_empty() {
 9920                server
 9921                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9922                        lsp::DidChangeWatchedFilesParams { changes },
 9923                    )
 9924                    .ok();
 9925            }
 9926            Some(())
 9927        });
 9928    }
 9929
 9930    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9931        self.as_local()?.language_server_for_id(id)
 9932    }
 9933
 9934    fn on_lsp_progress(
 9935        &mut self,
 9936        progress_params: lsp::ProgressParams,
 9937        language_server_id: LanguageServerId,
 9938        disk_based_diagnostics_progress_token: Option<String>,
 9939        cx: &mut Context<Self>,
 9940    ) {
 9941        match progress_params.value {
 9942            lsp::ProgressParamsValue::WorkDone(progress) => {
 9943                self.handle_work_done_progress(
 9944                    progress,
 9945                    language_server_id,
 9946                    disk_based_diagnostics_progress_token,
 9947                    ProgressToken::from_lsp(progress_params.token),
 9948                    cx,
 9949                );
 9950            }
 9951            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9952                let registration_id = match progress_params.token {
 9953                    lsp::NumberOrString::Number(_) => None,
 9954                    lsp::NumberOrString::String(token) => token
 9955                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9956                        .map(|(_, id)| id.to_owned()),
 9957                };
 9958                if let Some(LanguageServerState::Running {
 9959                    workspace_diagnostics_refresh_tasks,
 9960                    ..
 9961                }) = self
 9962                    .as_local_mut()
 9963                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9964                    && let Some(workspace_diagnostics) =
 9965                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9966                {
 9967                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9968                    self.apply_workspace_diagnostic_report(
 9969                        language_server_id,
 9970                        report,
 9971                        registration_id.map(SharedString::from),
 9972                        cx,
 9973                    )
 9974                }
 9975            }
 9976        }
 9977    }
 9978
 9979    fn handle_work_done_progress(
 9980        &mut self,
 9981        progress: lsp::WorkDoneProgress,
 9982        language_server_id: LanguageServerId,
 9983        disk_based_diagnostics_progress_token: Option<String>,
 9984        token: ProgressToken,
 9985        cx: &mut Context<Self>,
 9986    ) {
 9987        let language_server_status =
 9988            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9989                status
 9990            } else {
 9991                return;
 9992            };
 9993
 9994        if !language_server_status.progress_tokens.contains(&token) {
 9995            return;
 9996        }
 9997
 9998        let is_disk_based_diagnostics_progress =
 9999            if let (Some(disk_based_token), ProgressToken::String(token)) =
10000                (&disk_based_diagnostics_progress_token, &token)
10001            {
10002                token.starts_with(disk_based_token)
10003            } else {
10004                false
10005            };
10006
10007        match progress {
10008            lsp::WorkDoneProgress::Begin(report) => {
10009                if is_disk_based_diagnostics_progress {
10010                    self.disk_based_diagnostics_started(language_server_id, cx);
10011                }
10012                self.on_lsp_work_start(
10013                    language_server_id,
10014                    token.clone(),
10015                    LanguageServerProgress {
10016                        title: Some(report.title),
10017                        is_disk_based_diagnostics_progress,
10018                        is_cancellable: report.cancellable.unwrap_or(false),
10019                        message: report.message.clone(),
10020                        percentage: report.percentage.map(|p| p as usize),
10021                        last_update_at: cx.background_executor().now(),
10022                    },
10023                    cx,
10024                );
10025            }
10026            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10027                language_server_id,
10028                token,
10029                LanguageServerProgress {
10030                    title: None,
10031                    is_disk_based_diagnostics_progress,
10032                    is_cancellable: report.cancellable.unwrap_or(false),
10033                    message: report.message,
10034                    percentage: report.percentage.map(|p| p as usize),
10035                    last_update_at: cx.background_executor().now(),
10036                },
10037                cx,
10038            ),
10039            lsp::WorkDoneProgress::End(_) => {
10040                language_server_status.progress_tokens.remove(&token);
10041                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10042                if is_disk_based_diagnostics_progress {
10043                    self.disk_based_diagnostics_finished(language_server_id, cx);
10044                }
10045            }
10046        }
10047    }
10048
10049    fn on_lsp_work_start(
10050        &mut self,
10051        language_server_id: LanguageServerId,
10052        token: ProgressToken,
10053        progress: LanguageServerProgress,
10054        cx: &mut Context<Self>,
10055    ) {
10056        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10057            status.pending_work.insert(token.clone(), progress.clone());
10058            cx.notify();
10059        }
10060        cx.emit(LspStoreEvent::LanguageServerUpdate {
10061            language_server_id,
10062            name: self
10063                .language_server_adapter_for_id(language_server_id)
10064                .map(|adapter| adapter.name()),
10065            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10066                token: Some(token.to_proto()),
10067                title: progress.title,
10068                message: progress.message,
10069                percentage: progress.percentage.map(|p| p as u32),
10070                is_cancellable: Some(progress.is_cancellable),
10071            }),
10072        })
10073    }
10074
10075    fn on_lsp_work_progress(
10076        &mut self,
10077        language_server_id: LanguageServerId,
10078        token: ProgressToken,
10079        progress: LanguageServerProgress,
10080        cx: &mut Context<Self>,
10081    ) {
10082        let mut did_update = false;
10083        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10084            match status.pending_work.entry(token.clone()) {
10085                btree_map::Entry::Vacant(entry) => {
10086                    entry.insert(progress.clone());
10087                    did_update = true;
10088                }
10089                btree_map::Entry::Occupied(mut entry) => {
10090                    let entry = entry.get_mut();
10091                    if (progress.last_update_at - entry.last_update_at)
10092                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10093                    {
10094                        entry.last_update_at = progress.last_update_at;
10095                        if progress.message.is_some() {
10096                            entry.message = progress.message.clone();
10097                        }
10098                        if progress.percentage.is_some() {
10099                            entry.percentage = progress.percentage;
10100                        }
10101                        if progress.is_cancellable != entry.is_cancellable {
10102                            entry.is_cancellable = progress.is_cancellable;
10103                        }
10104                        did_update = true;
10105                    }
10106                }
10107            }
10108        }
10109
10110        if did_update {
10111            cx.emit(LspStoreEvent::LanguageServerUpdate {
10112                language_server_id,
10113                name: self
10114                    .language_server_adapter_for_id(language_server_id)
10115                    .map(|adapter| adapter.name()),
10116                message: proto::update_language_server::Variant::WorkProgress(
10117                    proto::LspWorkProgress {
10118                        token: Some(token.to_proto()),
10119                        message: progress.message,
10120                        percentage: progress.percentage.map(|p| p as u32),
10121                        is_cancellable: Some(progress.is_cancellable),
10122                    },
10123                ),
10124            })
10125        }
10126    }
10127
10128    fn on_lsp_work_end(
10129        &mut self,
10130        language_server_id: LanguageServerId,
10131        token: ProgressToken,
10132        cx: &mut Context<Self>,
10133    ) {
10134        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10135            if let Some(work) = status.pending_work.remove(&token)
10136                && !work.is_disk_based_diagnostics_progress
10137            {
10138                cx.emit(LspStoreEvent::RefreshInlayHints {
10139                    server_id: language_server_id,
10140                    request_id: None,
10141                });
10142            }
10143            cx.notify();
10144        }
10145
10146        cx.emit(LspStoreEvent::LanguageServerUpdate {
10147            language_server_id,
10148            name: self
10149                .language_server_adapter_for_id(language_server_id)
10150                .map(|adapter| adapter.name()),
10151            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10152                token: Some(token.to_proto()),
10153            }),
10154        })
10155    }
10156
10157    pub async fn handle_resolve_completion_documentation(
10158        this: Entity<Self>,
10159        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10160        mut cx: AsyncApp,
10161    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10162        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10163
10164        let completion = this
10165            .read_with(&cx, |this, cx| {
10166                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10167                let server = this
10168                    .language_server_for_id(id)
10169                    .with_context(|| format!("No language server {id}"))?;
10170
10171                anyhow::Ok(cx.background_spawn(async move {
10172                    let can_resolve = server
10173                        .capabilities()
10174                        .completion_provider
10175                        .as_ref()
10176                        .and_then(|options| options.resolve_provider)
10177                        .unwrap_or(false);
10178                    if can_resolve {
10179                        server
10180                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
10181                            .await
10182                            .into_response()
10183                            .context("resolve completion item")
10184                    } else {
10185                        anyhow::Ok(lsp_completion)
10186                    }
10187                }))
10188            })?
10189            .await?;
10190
10191        let mut documentation_is_markdown = false;
10192        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10193        let documentation = match completion.documentation {
10194            Some(lsp::Documentation::String(text)) => text,
10195
10196            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10197                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10198                value
10199            }
10200
10201            _ => String::new(),
10202        };
10203
10204        // If we have a new buffer_id, that means we're talking to a new client
10205        // and want to check for new text_edits in the completion too.
10206        let mut old_replace_start = None;
10207        let mut old_replace_end = None;
10208        let mut old_insert_start = None;
10209        let mut old_insert_end = None;
10210        let mut new_text = String::default();
10211        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10212            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10213                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10214                anyhow::Ok(buffer.read(cx).snapshot())
10215            })?;
10216
10217            if let Some(text_edit) = completion.text_edit.as_ref() {
10218                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10219
10220                if let Some(mut edit) = edit {
10221                    LineEnding::normalize(&mut edit.new_text);
10222
10223                    new_text = edit.new_text;
10224                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10225                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10226                    if let Some(insert_range) = edit.insert_range {
10227                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10228                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10229                    }
10230                }
10231            }
10232        }
10233
10234        Ok(proto::ResolveCompletionDocumentationResponse {
10235            documentation,
10236            documentation_is_markdown,
10237            old_replace_start,
10238            old_replace_end,
10239            new_text,
10240            lsp_completion,
10241            old_insert_start,
10242            old_insert_end,
10243        })
10244    }
10245
10246    async fn handle_on_type_formatting(
10247        this: Entity<Self>,
10248        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10249        mut cx: AsyncApp,
10250    ) -> Result<proto::OnTypeFormattingResponse> {
10251        let on_type_formatting = this.update(&mut cx, |this, cx| {
10252            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10253            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10254            let position = envelope
10255                .payload
10256                .position
10257                .and_then(deserialize_anchor)
10258                .context("invalid position")?;
10259            anyhow::Ok(this.apply_on_type_formatting(
10260                buffer,
10261                position,
10262                envelope.payload.trigger.clone(),
10263                cx,
10264            ))
10265        })?;
10266
10267        let transaction = on_type_formatting
10268            .await?
10269            .as_ref()
10270            .map(language::proto::serialize_transaction);
10271        Ok(proto::OnTypeFormattingResponse { transaction })
10272    }
10273
10274    async fn handle_refresh_inlay_hints(
10275        lsp_store: Entity<Self>,
10276        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10277        mut cx: AsyncApp,
10278    ) -> Result<proto::Ack> {
10279        lsp_store.update(&mut cx, |_, cx| {
10280            cx.emit(LspStoreEvent::RefreshInlayHints {
10281                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10282                request_id: envelope.payload.request_id.map(|id| id as usize),
10283            });
10284        });
10285        Ok(proto::Ack {})
10286    }
10287
10288    async fn handle_pull_workspace_diagnostics(
10289        lsp_store: Entity<Self>,
10290        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10291        mut cx: AsyncApp,
10292    ) -> Result<proto::Ack> {
10293        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10294        lsp_store.update(&mut cx, |lsp_store, _| {
10295            lsp_store.pull_workspace_diagnostics(server_id);
10296        });
10297        Ok(proto::Ack {})
10298    }
10299
10300    async fn handle_get_color_presentation(
10301        lsp_store: Entity<Self>,
10302        envelope: TypedEnvelope<proto::GetColorPresentation>,
10303        mut cx: AsyncApp,
10304    ) -> Result<proto::GetColorPresentationResponse> {
10305        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10306        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10307            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10308        })?;
10309
10310        let color = envelope
10311            .payload
10312            .color
10313            .context("invalid color resolve request")?;
10314        let start = color
10315            .lsp_range_start
10316            .context("invalid color resolve request")?;
10317        let end = color
10318            .lsp_range_end
10319            .context("invalid color resolve request")?;
10320
10321        let color = DocumentColor {
10322            lsp_range: lsp::Range {
10323                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10324                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10325            },
10326            color: lsp::Color {
10327                red: color.red,
10328                green: color.green,
10329                blue: color.blue,
10330                alpha: color.alpha,
10331            },
10332            resolved: false,
10333            color_presentations: Vec::new(),
10334        };
10335        let resolved_color = lsp_store
10336            .update(&mut cx, |lsp_store, cx| {
10337                lsp_store.resolve_color_presentation(
10338                    color,
10339                    buffer.clone(),
10340                    LanguageServerId(envelope.payload.server_id as usize),
10341                    cx,
10342                )
10343            })
10344            .await
10345            .context("resolving color presentation")?;
10346
10347        Ok(proto::GetColorPresentationResponse {
10348            presentations: resolved_color
10349                .color_presentations
10350                .into_iter()
10351                .map(|presentation| proto::ColorPresentation {
10352                    label: presentation.label.to_string(),
10353                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10354                    additional_text_edits: presentation
10355                        .additional_text_edits
10356                        .into_iter()
10357                        .map(serialize_lsp_edit)
10358                        .collect(),
10359                })
10360                .collect(),
10361        })
10362    }
10363
10364    async fn handle_resolve_inlay_hint(
10365        lsp_store: Entity<Self>,
10366        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10367        mut cx: AsyncApp,
10368    ) -> Result<proto::ResolveInlayHintResponse> {
10369        let proto_hint = envelope
10370            .payload
10371            .hint
10372            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10373        let hint = InlayHints::proto_to_project_hint(proto_hint)
10374            .context("resolved proto inlay hint conversion")?;
10375        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10376            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10377            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10378        })?;
10379        let response_hint = lsp_store
10380            .update(&mut cx, |lsp_store, cx| {
10381                lsp_store.resolve_inlay_hint(
10382                    hint,
10383                    buffer,
10384                    LanguageServerId(envelope.payload.language_server_id as usize),
10385                    cx,
10386                )
10387            })
10388            .await
10389            .context("inlay hints fetch")?;
10390        Ok(proto::ResolveInlayHintResponse {
10391            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10392        })
10393    }
10394
10395    async fn handle_refresh_code_lens(
10396        this: Entity<Self>,
10397        _: TypedEnvelope<proto::RefreshCodeLens>,
10398        mut cx: AsyncApp,
10399    ) -> Result<proto::Ack> {
10400        this.update(&mut cx, |_, cx| {
10401            cx.emit(LspStoreEvent::RefreshCodeLens);
10402        });
10403        Ok(proto::Ack {})
10404    }
10405
10406    async fn handle_open_buffer_for_symbol(
10407        this: Entity<Self>,
10408        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10409        mut cx: AsyncApp,
10410    ) -> Result<proto::OpenBufferForSymbolResponse> {
10411        let peer_id = envelope.original_sender_id().unwrap_or_default();
10412        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10413        let symbol = Self::deserialize_symbol(symbol)?;
10414        this.read_with(&cx, |this, _| {
10415            if let SymbolLocation::OutsideProject {
10416                abs_path,
10417                signature,
10418            } = &symbol.path
10419            {
10420                let new_signature = this.symbol_signature(&abs_path);
10421                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10422            }
10423            Ok(())
10424        })?;
10425        let buffer = this
10426            .update(&mut cx, |this, cx| {
10427                this.open_buffer_for_symbol(
10428                    &Symbol {
10429                        language_server_name: symbol.language_server_name,
10430                        source_worktree_id: symbol.source_worktree_id,
10431                        source_language_server_id: symbol.source_language_server_id,
10432                        path: symbol.path,
10433                        name: symbol.name,
10434                        kind: symbol.kind,
10435                        range: symbol.range,
10436                        label: CodeLabel::default(),
10437                    },
10438                    cx,
10439                )
10440            })
10441            .await?;
10442
10443        this.update(&mut cx, |this, cx| {
10444            let is_private = buffer
10445                .read(cx)
10446                .file()
10447                .map(|f| f.is_private())
10448                .unwrap_or_default();
10449            if is_private {
10450                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10451            } else {
10452                this.buffer_store
10453                    .update(cx, |buffer_store, cx| {
10454                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10455                    })
10456                    .detach_and_log_err(cx);
10457                let buffer_id = buffer.read(cx).remote_id().to_proto();
10458                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10459            }
10460        })
10461    }
10462
10463    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10464        let mut hasher = Sha256::new();
10465        hasher.update(abs_path.to_string_lossy().as_bytes());
10466        hasher.update(self.nonce.to_be_bytes());
10467        hasher.finalize().as_slice().try_into().unwrap()
10468    }
10469
10470    pub async fn handle_get_project_symbols(
10471        this: Entity<Self>,
10472        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10473        mut cx: AsyncApp,
10474    ) -> Result<proto::GetProjectSymbolsResponse> {
10475        let symbols = this
10476            .update(&mut cx, |this, cx| {
10477                this.symbols(&envelope.payload.query, cx)
10478            })
10479            .await?;
10480
10481        Ok(proto::GetProjectSymbolsResponse {
10482            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10483        })
10484    }
10485
10486    pub async fn handle_restart_language_servers(
10487        this: Entity<Self>,
10488        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10489        mut cx: AsyncApp,
10490    ) -> Result<proto::Ack> {
10491        this.update(&mut cx, |lsp_store, cx| {
10492            let buffers =
10493                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10494            lsp_store.restart_language_servers_for_buffers(
10495                buffers,
10496                envelope
10497                    .payload
10498                    .only_servers
10499                    .into_iter()
10500                    .filter_map(|selector| {
10501                        Some(match selector.selector? {
10502                            proto::language_server_selector::Selector::ServerId(server_id) => {
10503                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10504                            }
10505                            proto::language_server_selector::Selector::Name(name) => {
10506                                LanguageServerSelector::Name(LanguageServerName(
10507                                    SharedString::from(name),
10508                                ))
10509                            }
10510                        })
10511                    })
10512                    .collect(),
10513                cx,
10514            );
10515        });
10516
10517        Ok(proto::Ack {})
10518    }
10519
10520    pub async fn handle_stop_language_servers(
10521        lsp_store: Entity<Self>,
10522        envelope: TypedEnvelope<proto::StopLanguageServers>,
10523        mut cx: AsyncApp,
10524    ) -> Result<proto::Ack> {
10525        lsp_store.update(&mut cx, |lsp_store, cx| {
10526            if envelope.payload.all
10527                && envelope.payload.also_servers.is_empty()
10528                && envelope.payload.buffer_ids.is_empty()
10529            {
10530                lsp_store.stop_all_language_servers(cx);
10531            } else {
10532                let buffers =
10533                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10534                lsp_store
10535                    .stop_language_servers_for_buffers(
10536                        buffers,
10537                        envelope
10538                            .payload
10539                            .also_servers
10540                            .into_iter()
10541                            .filter_map(|selector| {
10542                                Some(match selector.selector? {
10543                                    proto::language_server_selector::Selector::ServerId(
10544                                        server_id,
10545                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10546                                        server_id,
10547                                    )),
10548                                    proto::language_server_selector::Selector::Name(name) => {
10549                                        LanguageServerSelector::Name(LanguageServerName(
10550                                            SharedString::from(name),
10551                                        ))
10552                                    }
10553                                })
10554                            })
10555                            .collect(),
10556                        cx,
10557                    )
10558                    .detach_and_log_err(cx);
10559            }
10560        });
10561
10562        Ok(proto::Ack {})
10563    }
10564
10565    pub async fn handle_cancel_language_server_work(
10566        lsp_store: Entity<Self>,
10567        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10568        mut cx: AsyncApp,
10569    ) -> Result<proto::Ack> {
10570        lsp_store.update(&mut cx, |lsp_store, cx| {
10571            if let Some(work) = envelope.payload.work {
10572                match work {
10573                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10574                        let buffers =
10575                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10576                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10577                    }
10578                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10579                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10580                        let token = work
10581                            .token
10582                            .map(|token| {
10583                                ProgressToken::from_proto(token)
10584                                    .context("invalid work progress token")
10585                            })
10586                            .transpose()?;
10587                        lsp_store.cancel_language_server_work(server_id, token, cx);
10588                    }
10589                }
10590            }
10591            anyhow::Ok(())
10592        })?;
10593
10594        Ok(proto::Ack {})
10595    }
10596
10597    fn buffer_ids_to_buffers(
10598        &mut self,
10599        buffer_ids: impl Iterator<Item = u64>,
10600        cx: &mut Context<Self>,
10601    ) -> Vec<Entity<Buffer>> {
10602        buffer_ids
10603            .into_iter()
10604            .flat_map(|buffer_id| {
10605                self.buffer_store
10606                    .read(cx)
10607                    .get(BufferId::new(buffer_id).log_err()?)
10608            })
10609            .collect::<Vec<_>>()
10610    }
10611
10612    async fn handle_apply_additional_edits_for_completion(
10613        this: Entity<Self>,
10614        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10615        mut cx: AsyncApp,
10616    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10617        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10618            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10619            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10620            let completion = Self::deserialize_completion(
10621                envelope.payload.completion.context("invalid completion")?,
10622            )?;
10623            anyhow::Ok((buffer, completion))
10624        })?;
10625
10626        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10627            this.apply_additional_edits_for_completion(
10628                buffer,
10629                Rc::new(RefCell::new(Box::new([Completion {
10630                    replace_range: completion.replace_range,
10631                    new_text: completion.new_text,
10632                    source: completion.source,
10633                    documentation: None,
10634                    label: CodeLabel::default(),
10635                    match_start: None,
10636                    snippet_deduplication_key: None,
10637                    insert_text_mode: None,
10638                    icon_path: None,
10639                    confirm: None,
10640                }]))),
10641                0,
10642                false,
10643                cx,
10644            )
10645        });
10646
10647        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10648            transaction: apply_additional_edits
10649                .await?
10650                .as_ref()
10651                .map(language::proto::serialize_transaction),
10652        })
10653    }
10654
10655    pub fn last_formatting_failure(&self) -> Option<&str> {
10656        self.last_formatting_failure.as_deref()
10657    }
10658
10659    pub fn reset_last_formatting_failure(&mut self) {
10660        self.last_formatting_failure = None;
10661    }
10662
10663    pub fn environment_for_buffer(
10664        &self,
10665        buffer: &Entity<Buffer>,
10666        cx: &mut Context<Self>,
10667    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10668        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10669            environment.update(cx, |env, cx| {
10670                env.buffer_environment(buffer, &self.worktree_store, cx)
10671            })
10672        } else {
10673            Task::ready(None).shared()
10674        }
10675    }
10676
10677    pub fn format(
10678        &mut self,
10679        buffers: HashSet<Entity<Buffer>>,
10680        target: LspFormatTarget,
10681        push_to_history: bool,
10682        trigger: FormatTrigger,
10683        cx: &mut Context<Self>,
10684    ) -> Task<anyhow::Result<ProjectTransaction>> {
10685        let logger = zlog::scoped!("format");
10686        if self.as_local().is_some() {
10687            zlog::trace!(logger => "Formatting locally");
10688            let logger = zlog::scoped!(logger => "local");
10689            let buffers = buffers
10690                .into_iter()
10691                .map(|buffer_handle| {
10692                    let buffer = buffer_handle.read(cx);
10693                    let buffer_abs_path = File::from_dyn(buffer.file())
10694                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10695
10696                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10697                })
10698                .collect::<Vec<_>>();
10699
10700            cx.spawn(async move |lsp_store, cx| {
10701                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10702
10703                for (handle, abs_path, id) in buffers {
10704                    let env = lsp_store
10705                        .update(cx, |lsp_store, cx| {
10706                            lsp_store.environment_for_buffer(&handle, cx)
10707                        })?
10708                        .await;
10709
10710                    let ranges = match &target {
10711                        LspFormatTarget::Buffers => None,
10712                        LspFormatTarget::Ranges(ranges) => {
10713                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10714                        }
10715                    };
10716
10717                    formattable_buffers.push(FormattableBuffer {
10718                        handle,
10719                        abs_path,
10720                        env,
10721                        ranges,
10722                    });
10723                }
10724                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10725
10726                let format_timer = zlog::time!(logger => "Formatting buffers");
10727                let result = LocalLspStore::format_locally(
10728                    lsp_store.clone(),
10729                    formattable_buffers,
10730                    push_to_history,
10731                    trigger,
10732                    logger,
10733                    cx,
10734                )
10735                .await;
10736                format_timer.end();
10737
10738                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10739
10740                lsp_store.update(cx, |lsp_store, _| {
10741                    lsp_store.update_last_formatting_failure(&result);
10742                })?;
10743
10744                result
10745            })
10746        } else if let Some((client, project_id)) = self.upstream_client() {
10747            zlog::trace!(logger => "Formatting remotely");
10748            let logger = zlog::scoped!(logger => "remote");
10749
10750            let buffer_ranges = match &target {
10751                LspFormatTarget::Buffers => Vec::new(),
10752                LspFormatTarget::Ranges(ranges) => ranges
10753                    .iter()
10754                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10755                        buffer_id: buffer_id.to_proto(),
10756                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10757                    })
10758                    .collect(),
10759            };
10760
10761            let buffer_store = self.buffer_store();
10762            cx.spawn(async move |lsp_store, cx| {
10763                zlog::trace!(logger => "Sending remote format request");
10764                let request_timer = zlog::time!(logger => "remote format request");
10765                let result = client
10766                    .request(proto::FormatBuffers {
10767                        project_id,
10768                        trigger: trigger as i32,
10769                        buffer_ids: buffers
10770                            .iter()
10771                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10772                            .collect(),
10773                        buffer_ranges,
10774                    })
10775                    .await
10776                    .and_then(|result| result.transaction.context("missing transaction"));
10777                request_timer.end();
10778
10779                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10780
10781                lsp_store.update(cx, |lsp_store, _| {
10782                    lsp_store.update_last_formatting_failure(&result);
10783                })?;
10784
10785                let transaction_response = result?;
10786                let _timer = zlog::time!(logger => "deserializing project transaction");
10787                buffer_store
10788                    .update(cx, |buffer_store, cx| {
10789                        buffer_store.deserialize_project_transaction(
10790                            transaction_response,
10791                            push_to_history,
10792                            cx,
10793                        )
10794                    })
10795                    .await
10796            })
10797        } else {
10798            zlog::trace!(logger => "Not formatting");
10799            Task::ready(Ok(ProjectTransaction::default()))
10800        }
10801    }
10802
10803    async fn handle_format_buffers(
10804        this: Entity<Self>,
10805        envelope: TypedEnvelope<proto::FormatBuffers>,
10806        mut cx: AsyncApp,
10807    ) -> Result<proto::FormatBuffersResponse> {
10808        let sender_id = envelope.original_sender_id().unwrap_or_default();
10809        let format = this.update(&mut cx, |this, cx| {
10810            let mut buffers = HashSet::default();
10811            for buffer_id in &envelope.payload.buffer_ids {
10812                let buffer_id = BufferId::new(*buffer_id)?;
10813                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10814            }
10815
10816            let target = if envelope.payload.buffer_ranges.is_empty() {
10817                LspFormatTarget::Buffers
10818            } else {
10819                let mut ranges_map = BTreeMap::new();
10820                for buffer_range in &envelope.payload.buffer_ranges {
10821                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10822                    let ranges: Result<Vec<_>> = buffer_range
10823                        .ranges
10824                        .iter()
10825                        .map(|range| {
10826                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10827                        })
10828                        .collect();
10829                    ranges_map.insert(buffer_id, ranges?);
10830                }
10831                LspFormatTarget::Ranges(ranges_map)
10832            };
10833
10834            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10835            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10836        })?;
10837
10838        let project_transaction = format.await?;
10839        let project_transaction = this.update(&mut cx, |this, cx| {
10840            this.buffer_store.update(cx, |buffer_store, cx| {
10841                buffer_store.serialize_project_transaction_for_peer(
10842                    project_transaction,
10843                    sender_id,
10844                    cx,
10845                )
10846            })
10847        });
10848        Ok(proto::FormatBuffersResponse {
10849            transaction: Some(project_transaction),
10850        })
10851    }
10852
10853    async fn handle_apply_code_action_kind(
10854        this: Entity<Self>,
10855        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10856        mut cx: AsyncApp,
10857    ) -> Result<proto::ApplyCodeActionKindResponse> {
10858        let sender_id = envelope.original_sender_id().unwrap_or_default();
10859        let format = this.update(&mut cx, |this, cx| {
10860            let mut buffers = HashSet::default();
10861            for buffer_id in &envelope.payload.buffer_ids {
10862                let buffer_id = BufferId::new(*buffer_id)?;
10863                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10864            }
10865            let kind = match envelope.payload.kind.as_str() {
10866                "" => CodeActionKind::EMPTY,
10867                "quickfix" => CodeActionKind::QUICKFIX,
10868                "refactor" => CodeActionKind::REFACTOR,
10869                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10870                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10871                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10872                "source" => CodeActionKind::SOURCE,
10873                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10874                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10875                _ => anyhow::bail!(
10876                    "Invalid code action kind {}",
10877                    envelope.payload.kind.as_str()
10878                ),
10879            };
10880            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10881        })?;
10882
10883        let project_transaction = format.await?;
10884        let project_transaction = this.update(&mut cx, |this, cx| {
10885            this.buffer_store.update(cx, |buffer_store, cx| {
10886                buffer_store.serialize_project_transaction_for_peer(
10887                    project_transaction,
10888                    sender_id,
10889                    cx,
10890                )
10891            })
10892        });
10893        Ok(proto::ApplyCodeActionKindResponse {
10894            transaction: Some(project_transaction),
10895        })
10896    }
10897
10898    async fn shutdown_language_server(
10899        server_state: Option<LanguageServerState>,
10900        name: LanguageServerName,
10901        cx: &mut AsyncApp,
10902    ) {
10903        let server = match server_state {
10904            Some(LanguageServerState::Starting { startup, .. }) => {
10905                let mut timer = cx
10906                    .background_executor()
10907                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10908                    .fuse();
10909
10910                select! {
10911                    server = startup.fuse() => server,
10912                    () = timer => {
10913                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10914                        None
10915                    },
10916                }
10917            }
10918
10919            Some(LanguageServerState::Running { server, .. }) => Some(server),
10920
10921            None => None,
10922        };
10923
10924        if let Some(server) = server
10925            && let Some(shutdown) = server.shutdown()
10926        {
10927            shutdown.await;
10928        }
10929    }
10930
10931    // Returns a list of all of the worktrees which no longer have a language server and the root path
10932    // for the stopped server
10933    fn stop_local_language_server(
10934        &mut self,
10935        server_id: LanguageServerId,
10936        cx: &mut Context<Self>,
10937    ) -> Task<()> {
10938        let local = match &mut self.mode {
10939            LspStoreMode::Local(local) => local,
10940            _ => {
10941                return Task::ready(());
10942            }
10943        };
10944
10945        // Remove this server ID from all entries in the given worktree.
10946        local
10947            .language_server_ids
10948            .retain(|_, state| state.id != server_id);
10949        self.buffer_store.update(cx, |buffer_store, cx| {
10950            for buffer in buffer_store.buffers() {
10951                buffer.update(cx, |buffer, cx| {
10952                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10953                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10954                });
10955            }
10956        });
10957
10958        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10959            summaries.retain(|path, summaries_by_server_id| {
10960                if summaries_by_server_id.remove(&server_id).is_some() {
10961                    if let Some((client, project_id)) = self.downstream_client.clone() {
10962                        client
10963                            .send(proto::UpdateDiagnosticSummary {
10964                                project_id,
10965                                worktree_id: worktree_id.to_proto(),
10966                                summary: Some(proto::DiagnosticSummary {
10967                                    path: path.as_ref().to_proto(),
10968                                    language_server_id: server_id.0 as u64,
10969                                    error_count: 0,
10970                                    warning_count: 0,
10971                                }),
10972                                more_summaries: Vec::new(),
10973                            })
10974                            .log_err();
10975                    }
10976                    !summaries_by_server_id.is_empty()
10977                } else {
10978                    true
10979                }
10980            });
10981        }
10982
10983        let local = self.as_local_mut().unwrap();
10984        for diagnostics in local.diagnostics.values_mut() {
10985            diagnostics.retain(|_, diagnostics_by_server_id| {
10986                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10987                    diagnostics_by_server_id.remove(ix);
10988                    !diagnostics_by_server_id.is_empty()
10989                } else {
10990                    true
10991                }
10992            });
10993        }
10994        local.language_server_watched_paths.remove(&server_id);
10995
10996        let server_state = local.language_servers.remove(&server_id);
10997        self.cleanup_lsp_data(server_id);
10998        let name = self
10999            .language_server_statuses
11000            .remove(&server_id)
11001            .map(|status| status.name)
11002            .or_else(|| {
11003                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
11004                    Some(adapter.name())
11005                } else {
11006                    None
11007                }
11008            });
11009
11010        if let Some(name) = name {
11011            log::info!("stopping language server {name}");
11012            self.languages
11013                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
11014            cx.notify();
11015
11016            return cx.spawn(async move |lsp_store, cx| {
11017                Self::shutdown_language_server(server_state, name.clone(), cx).await;
11018                lsp_store
11019                    .update(cx, |lsp_store, cx| {
11020                        lsp_store
11021                            .languages
11022                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
11023                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11024                        cx.notify();
11025                    })
11026                    .ok();
11027            });
11028        }
11029
11030        if server_state.is_some() {
11031            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11032        }
11033        Task::ready(())
11034    }
11035
11036    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
11037        self.shutdown_all_language_servers(cx).detach();
11038    }
11039
11040    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
11041        if let Some((client, project_id)) = self.upstream_client() {
11042            let request = client.request(proto::StopLanguageServers {
11043                project_id,
11044                buffer_ids: Vec::new(),
11045                also_servers: Vec::new(),
11046                all: true,
11047            });
11048            cx.background_spawn(async move {
11049                request.await.ok();
11050            })
11051        } else {
11052            let Some(local) = self.as_local_mut() else {
11053                return Task::ready(());
11054            };
11055            let language_servers_to_stop = local
11056                .language_server_ids
11057                .values()
11058                .map(|state| state.id)
11059                .collect();
11060            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11061            let tasks = language_servers_to_stop
11062                .into_iter()
11063                .map(|server| self.stop_local_language_server(server, cx))
11064                .collect::<Vec<_>>();
11065            cx.background_spawn(async move {
11066                futures::future::join_all(tasks).await;
11067            })
11068        }
11069    }
11070
11071    pub fn restart_language_servers_for_buffers(
11072        &mut self,
11073        buffers: Vec<Entity<Buffer>>,
11074        only_restart_servers: HashSet<LanguageServerSelector>,
11075        cx: &mut Context<Self>,
11076    ) {
11077        if let Some((client, project_id)) = self.upstream_client() {
11078            let request = client.request(proto::RestartLanguageServers {
11079                project_id,
11080                buffer_ids: buffers
11081                    .into_iter()
11082                    .map(|b| b.read(cx).remote_id().to_proto())
11083                    .collect(),
11084                only_servers: only_restart_servers
11085                    .into_iter()
11086                    .map(|selector| {
11087                        let selector = match selector {
11088                            LanguageServerSelector::Id(language_server_id) => {
11089                                proto::language_server_selector::Selector::ServerId(
11090                                    language_server_id.to_proto(),
11091                                )
11092                            }
11093                            LanguageServerSelector::Name(language_server_name) => {
11094                                proto::language_server_selector::Selector::Name(
11095                                    language_server_name.to_string(),
11096                                )
11097                            }
11098                        };
11099                        proto::LanguageServerSelector {
11100                            selector: Some(selector),
11101                        }
11102                    })
11103                    .collect(),
11104                all: false,
11105            });
11106            cx.background_spawn(request).detach_and_log_err(cx);
11107        } else {
11108            let stop_task = if only_restart_servers.is_empty() {
11109                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11110            } else {
11111                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11112            };
11113            cx.spawn(async move |lsp_store, cx| {
11114                stop_task.await;
11115                lsp_store.update(cx, |lsp_store, cx| {
11116                    for buffer in buffers {
11117                        lsp_store.register_buffer_with_language_servers(
11118                            &buffer,
11119                            only_restart_servers.clone(),
11120                            true,
11121                            cx,
11122                        );
11123                    }
11124                })
11125            })
11126            .detach();
11127        }
11128    }
11129
11130    pub fn stop_language_servers_for_buffers(
11131        &mut self,
11132        buffers: Vec<Entity<Buffer>>,
11133        also_stop_servers: HashSet<LanguageServerSelector>,
11134        cx: &mut Context<Self>,
11135    ) -> Task<Result<()>> {
11136        if let Some((client, project_id)) = self.upstream_client() {
11137            let request = client.request(proto::StopLanguageServers {
11138                project_id,
11139                buffer_ids: buffers
11140                    .into_iter()
11141                    .map(|b| b.read(cx).remote_id().to_proto())
11142                    .collect(),
11143                also_servers: also_stop_servers
11144                    .into_iter()
11145                    .map(|selector| {
11146                        let selector = match selector {
11147                            LanguageServerSelector::Id(language_server_id) => {
11148                                proto::language_server_selector::Selector::ServerId(
11149                                    language_server_id.to_proto(),
11150                                )
11151                            }
11152                            LanguageServerSelector::Name(language_server_name) => {
11153                                proto::language_server_selector::Selector::Name(
11154                                    language_server_name.to_string(),
11155                                )
11156                            }
11157                        };
11158                        proto::LanguageServerSelector {
11159                            selector: Some(selector),
11160                        }
11161                    })
11162                    .collect(),
11163                all: false,
11164            });
11165            cx.background_spawn(async move {
11166                let _ = request.await?;
11167                Ok(())
11168            })
11169        } else {
11170            let task =
11171                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11172            cx.background_spawn(async move {
11173                task.await;
11174                Ok(())
11175            })
11176        }
11177    }
11178
11179    fn stop_local_language_servers_for_buffers(
11180        &mut self,
11181        buffers: &[Entity<Buffer>],
11182        also_stop_servers: HashSet<LanguageServerSelector>,
11183        cx: &mut Context<Self>,
11184    ) -> Task<()> {
11185        let Some(local) = self.as_local_mut() else {
11186            return Task::ready(());
11187        };
11188        let mut language_server_names_to_stop = BTreeSet::default();
11189        let mut language_servers_to_stop = also_stop_servers
11190            .into_iter()
11191            .flat_map(|selector| match selector {
11192                LanguageServerSelector::Id(id) => Some(id),
11193                LanguageServerSelector::Name(name) => {
11194                    language_server_names_to_stop.insert(name);
11195                    None
11196                }
11197            })
11198            .collect::<BTreeSet<_>>();
11199
11200        let mut covered_worktrees = HashSet::default();
11201        for buffer in buffers {
11202            buffer.update(cx, |buffer, cx| {
11203                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11204                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11205                    && covered_worktrees.insert(worktree_id)
11206                {
11207                    language_server_names_to_stop.retain(|name| {
11208                        let old_ids_count = language_servers_to_stop.len();
11209                        let all_language_servers_with_this_name = local
11210                            .language_server_ids
11211                            .iter()
11212                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11213                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11214                        old_ids_count == language_servers_to_stop.len()
11215                    });
11216                }
11217            });
11218        }
11219        for name in language_server_names_to_stop {
11220            language_servers_to_stop.extend(
11221                local
11222                    .language_server_ids
11223                    .iter()
11224                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11225            );
11226        }
11227
11228        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11229        let tasks = language_servers_to_stop
11230            .into_iter()
11231            .map(|server| self.stop_local_language_server(server, cx))
11232            .collect::<Vec<_>>();
11233
11234        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11235    }
11236
11237    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11238        let (worktree, relative_path) =
11239            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11240
11241        let project_path = ProjectPath {
11242            worktree_id: worktree.read(cx).id(),
11243            path: relative_path,
11244        };
11245
11246        Some(
11247            self.buffer_store()
11248                .read(cx)
11249                .get_by_path(&project_path)?
11250                .read(cx),
11251        )
11252    }
11253
11254    #[cfg(any(test, feature = "test-support"))]
11255    pub fn update_diagnostics(
11256        &mut self,
11257        server_id: LanguageServerId,
11258        diagnostics: lsp::PublishDiagnosticsParams,
11259        result_id: Option<SharedString>,
11260        source_kind: DiagnosticSourceKind,
11261        disk_based_sources: &[String],
11262        cx: &mut Context<Self>,
11263    ) -> Result<()> {
11264        self.merge_lsp_diagnostics(
11265            source_kind,
11266            vec![DocumentDiagnosticsUpdate {
11267                diagnostics,
11268                result_id,
11269                server_id,
11270                disk_based_sources: Cow::Borrowed(disk_based_sources),
11271                registration_id: None,
11272            }],
11273            |_, _, _| false,
11274            cx,
11275        )
11276    }
11277
11278    pub fn merge_lsp_diagnostics(
11279        &mut self,
11280        source_kind: DiagnosticSourceKind,
11281        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11282        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11283        cx: &mut Context<Self>,
11284    ) -> Result<()> {
11285        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11286        let updates = lsp_diagnostics
11287            .into_iter()
11288            .filter_map(|update| {
11289                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11290                Some(DocumentDiagnosticsUpdate {
11291                    diagnostics: self.lsp_to_document_diagnostics(
11292                        abs_path,
11293                        source_kind,
11294                        update.server_id,
11295                        update.diagnostics,
11296                        &update.disk_based_sources,
11297                        update.registration_id.clone(),
11298                    ),
11299                    result_id: update.result_id,
11300                    server_id: update.server_id,
11301                    disk_based_sources: update.disk_based_sources,
11302                    registration_id: update.registration_id,
11303                })
11304            })
11305            .collect();
11306        self.merge_diagnostic_entries(updates, merge, cx)?;
11307        Ok(())
11308    }
11309
11310    fn lsp_to_document_diagnostics(
11311        &mut self,
11312        document_abs_path: PathBuf,
11313        source_kind: DiagnosticSourceKind,
11314        server_id: LanguageServerId,
11315        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11316        disk_based_sources: &[String],
11317        registration_id: Option<SharedString>,
11318    ) -> DocumentDiagnostics {
11319        let mut diagnostics = Vec::default();
11320        let mut primary_diagnostic_group_ids = HashMap::default();
11321        let mut sources_by_group_id = HashMap::default();
11322        let mut supporting_diagnostics = HashMap::default();
11323
11324        let adapter = self.language_server_adapter_for_id(server_id);
11325
11326        // Ensure that primary diagnostics are always the most severe
11327        lsp_diagnostics
11328            .diagnostics
11329            .sort_by_key(|item| item.severity);
11330
11331        for diagnostic in &lsp_diagnostics.diagnostics {
11332            let source = diagnostic.source.as_ref();
11333            let range = range_from_lsp(diagnostic.range);
11334            let is_supporting = diagnostic
11335                .related_information
11336                .as_ref()
11337                .is_some_and(|infos| {
11338                    infos.iter().any(|info| {
11339                        primary_diagnostic_group_ids.contains_key(&(
11340                            source,
11341                            diagnostic.code.clone(),
11342                            range_from_lsp(info.location.range),
11343                        ))
11344                    })
11345                });
11346
11347            let is_unnecessary = diagnostic
11348                .tags
11349                .as_ref()
11350                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11351
11352            let underline = self
11353                .language_server_adapter_for_id(server_id)
11354                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11355
11356            if is_supporting {
11357                supporting_diagnostics.insert(
11358                    (source, diagnostic.code.clone(), range),
11359                    (diagnostic.severity, is_unnecessary),
11360                );
11361            } else {
11362                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11363                let is_disk_based =
11364                    source.is_some_and(|source| disk_based_sources.contains(source));
11365
11366                sources_by_group_id.insert(group_id, source);
11367                primary_diagnostic_group_ids
11368                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11369
11370                diagnostics.push(DiagnosticEntry {
11371                    range,
11372                    diagnostic: Diagnostic {
11373                        source: diagnostic.source.clone(),
11374                        source_kind,
11375                        code: diagnostic.code.clone(),
11376                        code_description: diagnostic
11377                            .code_description
11378                            .as_ref()
11379                            .and_then(|d| d.href.clone()),
11380                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11381                        markdown: adapter.as_ref().and_then(|adapter| {
11382                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11383                        }),
11384                        message: diagnostic.message.trim().to_string(),
11385                        group_id,
11386                        is_primary: true,
11387                        is_disk_based,
11388                        is_unnecessary,
11389                        underline,
11390                        data: diagnostic.data.clone(),
11391                        registration_id: registration_id.clone(),
11392                    },
11393                });
11394                if let Some(infos) = &diagnostic.related_information {
11395                    for info in infos {
11396                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11397                            let range = range_from_lsp(info.location.range);
11398                            diagnostics.push(DiagnosticEntry {
11399                                range,
11400                                diagnostic: Diagnostic {
11401                                    source: diagnostic.source.clone(),
11402                                    source_kind,
11403                                    code: diagnostic.code.clone(),
11404                                    code_description: diagnostic
11405                                        .code_description
11406                                        .as_ref()
11407                                        .and_then(|d| d.href.clone()),
11408                                    severity: DiagnosticSeverity::INFORMATION,
11409                                    markdown: adapter.as_ref().and_then(|adapter| {
11410                                        adapter.diagnostic_message_to_markdown(&info.message)
11411                                    }),
11412                                    message: info.message.trim().to_string(),
11413                                    group_id,
11414                                    is_primary: false,
11415                                    is_disk_based,
11416                                    is_unnecessary: false,
11417                                    underline,
11418                                    data: diagnostic.data.clone(),
11419                                    registration_id: registration_id.clone(),
11420                                },
11421                            });
11422                        }
11423                    }
11424                }
11425            }
11426        }
11427
11428        for entry in &mut diagnostics {
11429            let diagnostic = &mut entry.diagnostic;
11430            if !diagnostic.is_primary {
11431                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11432                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11433                    source,
11434                    diagnostic.code.clone(),
11435                    entry.range.clone(),
11436                )) {
11437                    if let Some(severity) = severity {
11438                        diagnostic.severity = severity;
11439                    }
11440                    diagnostic.is_unnecessary = is_unnecessary;
11441                }
11442            }
11443        }
11444
11445        DocumentDiagnostics {
11446            diagnostics,
11447            document_abs_path,
11448            version: lsp_diagnostics.version,
11449        }
11450    }
11451
11452    fn insert_newly_running_language_server(
11453        &mut self,
11454        adapter: Arc<CachedLspAdapter>,
11455        language_server: Arc<LanguageServer>,
11456        server_id: LanguageServerId,
11457        key: LanguageServerSeed,
11458        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11459        cx: &mut Context<Self>,
11460    ) {
11461        let Some(local) = self.as_local_mut() else {
11462            return;
11463        };
11464        // If the language server for this key doesn't match the server id, don't store the
11465        // server. Which will cause it to be dropped, killing the process
11466        if local
11467            .language_server_ids
11468            .get(&key)
11469            .map(|state| state.id != server_id)
11470            .unwrap_or(false)
11471        {
11472            return;
11473        }
11474
11475        // Update language_servers collection with Running variant of LanguageServerState
11476        // indicating that the server is up and running and ready
11477        let workspace_folders = workspace_folders.lock().clone();
11478        language_server.set_workspace_folders(workspace_folders);
11479
11480        let workspace_diagnostics_refresh_tasks = language_server
11481            .capabilities()
11482            .diagnostic_provider
11483            .and_then(|provider| {
11484                local
11485                    .language_server_dynamic_registrations
11486                    .entry(server_id)
11487                    .or_default()
11488                    .diagnostics
11489                    .entry(None)
11490                    .or_insert(provider.clone());
11491                let workspace_refresher =
11492                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11493
11494                Some((None, workspace_refresher))
11495            })
11496            .into_iter()
11497            .collect();
11498        local.language_servers.insert(
11499            server_id,
11500            LanguageServerState::Running {
11501                workspace_diagnostics_refresh_tasks,
11502                adapter: adapter.clone(),
11503                server: language_server.clone(),
11504                simulate_disk_based_diagnostics_completion: None,
11505            },
11506        );
11507        local
11508            .languages
11509            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11510        if let Some(file_ops_caps) = language_server
11511            .capabilities()
11512            .workspace
11513            .as_ref()
11514            .and_then(|ws| ws.file_operations.as_ref())
11515        {
11516            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11517            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11518            if did_rename_caps.or(will_rename_caps).is_some() {
11519                let watcher = RenamePathsWatchedForServer::default()
11520                    .with_did_rename_patterns(did_rename_caps)
11521                    .with_will_rename_patterns(will_rename_caps);
11522                local
11523                    .language_server_paths_watched_for_rename
11524                    .insert(server_id, watcher);
11525            }
11526        }
11527
11528        self.language_server_statuses.insert(
11529            server_id,
11530            LanguageServerStatus {
11531                name: language_server.name(),
11532                server_version: language_server.version(),
11533                pending_work: Default::default(),
11534                has_pending_diagnostic_updates: false,
11535                progress_tokens: Default::default(),
11536                worktree: Some(key.worktree_id),
11537                binary: Some(language_server.binary().clone()),
11538                configuration: Some(language_server.configuration().clone()),
11539                workspace_folders: language_server.workspace_folders(),
11540            },
11541        );
11542
11543        cx.emit(LspStoreEvent::LanguageServerAdded(
11544            server_id,
11545            language_server.name(),
11546            Some(key.worktree_id),
11547        ));
11548
11549        let server_capabilities = language_server.capabilities();
11550        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11551            downstream_client
11552                .send(proto::StartLanguageServer {
11553                    project_id: *project_id,
11554                    server: Some(proto::LanguageServer {
11555                        id: server_id.to_proto(),
11556                        name: language_server.name().to_string(),
11557                        worktree_id: Some(key.worktree_id.to_proto()),
11558                    }),
11559                    capabilities: serde_json::to_string(&server_capabilities)
11560                        .expect("serializing server LSP capabilities"),
11561                })
11562                .log_err();
11563        }
11564        self.lsp_server_capabilities
11565            .insert(server_id, server_capabilities);
11566
11567        // Tell the language server about every open buffer in the worktree that matches the language.
11568        // Also check for buffers in worktrees that reused this server
11569        let mut worktrees_using_server = vec![key.worktree_id];
11570        if let Some(local) = self.as_local() {
11571            // Find all worktrees that have this server in their language server tree
11572            for (worktree_id, servers) in &local.lsp_tree.instances {
11573                if *worktree_id != key.worktree_id {
11574                    for server_map in servers.roots.values() {
11575                        if server_map
11576                            .values()
11577                            .any(|(node, _)| node.id() == Some(server_id))
11578                        {
11579                            worktrees_using_server.push(*worktree_id);
11580                        }
11581                    }
11582                }
11583            }
11584        }
11585
11586        let mut buffer_paths_registered = Vec::new();
11587        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11588            let mut lsp_adapters = HashMap::default();
11589            for buffer_handle in buffer_store.buffers() {
11590                let buffer = buffer_handle.read(cx);
11591                let file = match File::from_dyn(buffer.file()) {
11592                    Some(file) => file,
11593                    None => continue,
11594                };
11595                let language = match buffer.language() {
11596                    Some(language) => language,
11597                    None => continue,
11598                };
11599
11600                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11601                    || !lsp_adapters
11602                        .entry(language.name())
11603                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11604                        .iter()
11605                        .any(|a| a.name == key.name)
11606                {
11607                    continue;
11608                }
11609                // didOpen
11610                let file = match file.as_local() {
11611                    Some(file) => file,
11612                    None => continue,
11613                };
11614
11615                let local = self.as_local_mut().unwrap();
11616
11617                let buffer_id = buffer.remote_id();
11618                if local.registered_buffers.contains_key(&buffer_id) {
11619                    let versions = local
11620                        .buffer_snapshots
11621                        .entry(buffer_id)
11622                        .or_default()
11623                        .entry(server_id)
11624                        .and_modify(|_| {
11625                            assert!(
11626                            false,
11627                            "There should not be an existing snapshot for a newly inserted buffer"
11628                        )
11629                        })
11630                        .or_insert_with(|| {
11631                            vec![LspBufferSnapshot {
11632                                version: 0,
11633                                snapshot: buffer.text_snapshot(),
11634                            }]
11635                        });
11636
11637                    let snapshot = versions.last().unwrap();
11638                    let version = snapshot.version;
11639                    let initial_snapshot = &snapshot.snapshot;
11640                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11641                    language_server.register_buffer(
11642                        uri,
11643                        adapter.language_id(&language.name()),
11644                        version,
11645                        initial_snapshot.text(),
11646                    );
11647                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11648                    local
11649                        .buffers_opened_in_servers
11650                        .entry(buffer_id)
11651                        .or_default()
11652                        .insert(server_id);
11653                }
11654                buffer_handle.update(cx, |buffer, cx| {
11655                    buffer.set_completion_triggers(
11656                        server_id,
11657                        language_server
11658                            .capabilities()
11659                            .completion_provider
11660                            .as_ref()
11661                            .and_then(|provider| {
11662                                provider
11663                                    .trigger_characters
11664                                    .as_ref()
11665                                    .map(|characters| characters.iter().cloned().collect())
11666                            })
11667                            .unwrap_or_default(),
11668                        cx,
11669                    )
11670                });
11671            }
11672        });
11673
11674        for (buffer_id, abs_path) in buffer_paths_registered {
11675            cx.emit(LspStoreEvent::LanguageServerUpdate {
11676                language_server_id: server_id,
11677                name: Some(adapter.name()),
11678                message: proto::update_language_server::Variant::RegisteredForBuffer(
11679                    proto::RegisteredForBuffer {
11680                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11681                        buffer_id: buffer_id.to_proto(),
11682                    },
11683                ),
11684            });
11685        }
11686
11687        cx.notify();
11688    }
11689
11690    pub fn language_servers_running_disk_based_diagnostics(
11691        &self,
11692    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11693        self.language_server_statuses
11694            .iter()
11695            .filter_map(|(id, status)| {
11696                if status.has_pending_diagnostic_updates {
11697                    Some(*id)
11698                } else {
11699                    None
11700                }
11701            })
11702    }
11703
11704    pub(crate) fn cancel_language_server_work_for_buffers(
11705        &mut self,
11706        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11707        cx: &mut Context<Self>,
11708    ) {
11709        if let Some((client, project_id)) = self.upstream_client() {
11710            let request = client.request(proto::CancelLanguageServerWork {
11711                project_id,
11712                work: Some(proto::cancel_language_server_work::Work::Buffers(
11713                    proto::cancel_language_server_work::Buffers {
11714                        buffer_ids: buffers
11715                            .into_iter()
11716                            .map(|b| b.read(cx).remote_id().to_proto())
11717                            .collect(),
11718                    },
11719                )),
11720            });
11721            cx.background_spawn(request).detach_and_log_err(cx);
11722        } else if let Some(local) = self.as_local() {
11723            let servers = buffers
11724                .into_iter()
11725                .flat_map(|buffer| {
11726                    buffer.update(cx, |buffer, cx| {
11727                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11728                    })
11729                })
11730                .collect::<HashSet<_>>();
11731            for server_id in servers {
11732                self.cancel_language_server_work(server_id, None, cx);
11733            }
11734        }
11735    }
11736
11737    pub(crate) fn cancel_language_server_work(
11738        &mut self,
11739        server_id: LanguageServerId,
11740        token_to_cancel: Option<ProgressToken>,
11741        cx: &mut Context<Self>,
11742    ) {
11743        if let Some(local) = self.as_local() {
11744            let status = self.language_server_statuses.get(&server_id);
11745            let server = local.language_servers.get(&server_id);
11746            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11747            {
11748                for (token, progress) in &status.pending_work {
11749                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11750                        && token != token_to_cancel
11751                    {
11752                        continue;
11753                    }
11754                    if progress.is_cancellable {
11755                        server
11756                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11757                                WorkDoneProgressCancelParams {
11758                                    token: token.to_lsp(),
11759                                },
11760                            )
11761                            .ok();
11762                    }
11763                }
11764            }
11765        } else if let Some((client, project_id)) = self.upstream_client() {
11766            let request = client.request(proto::CancelLanguageServerWork {
11767                project_id,
11768                work: Some(
11769                    proto::cancel_language_server_work::Work::LanguageServerWork(
11770                        proto::cancel_language_server_work::LanguageServerWork {
11771                            language_server_id: server_id.to_proto(),
11772                            token: token_to_cancel.map(|token| token.to_proto()),
11773                        },
11774                    ),
11775                ),
11776            });
11777            cx.background_spawn(request).detach_and_log_err(cx);
11778        }
11779    }
11780
11781    fn register_supplementary_language_server(
11782        &mut self,
11783        id: LanguageServerId,
11784        name: LanguageServerName,
11785        server: Arc<LanguageServer>,
11786        cx: &mut Context<Self>,
11787    ) {
11788        if let Some(local) = self.as_local_mut() {
11789            local
11790                .supplementary_language_servers
11791                .insert(id, (name.clone(), server));
11792            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11793        }
11794    }
11795
11796    fn unregister_supplementary_language_server(
11797        &mut self,
11798        id: LanguageServerId,
11799        cx: &mut Context<Self>,
11800    ) {
11801        if let Some(local) = self.as_local_mut() {
11802            local.supplementary_language_servers.remove(&id);
11803            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11804        }
11805    }
11806
11807    pub(crate) fn supplementary_language_servers(
11808        &self,
11809    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11810        self.as_local().into_iter().flat_map(|local| {
11811            local
11812                .supplementary_language_servers
11813                .iter()
11814                .map(|(id, (name, _))| (*id, name.clone()))
11815        })
11816    }
11817
11818    pub fn language_server_adapter_for_id(
11819        &self,
11820        id: LanguageServerId,
11821    ) -> Option<Arc<CachedLspAdapter>> {
11822        self.as_local()
11823            .and_then(|local| local.language_servers.get(&id))
11824            .and_then(|language_server_state| match language_server_state {
11825                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11826                _ => None,
11827            })
11828    }
11829
11830    pub(super) fn update_local_worktree_language_servers(
11831        &mut self,
11832        worktree_handle: &Entity<Worktree>,
11833        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11834        cx: &mut Context<Self>,
11835    ) {
11836        if changes.is_empty() {
11837            return;
11838        }
11839
11840        let Some(local) = self.as_local() else { return };
11841
11842        local.prettier_store.update(cx, |prettier_store, cx| {
11843            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11844        });
11845
11846        let worktree_id = worktree_handle.read(cx).id();
11847        let mut language_server_ids = local
11848            .language_server_ids
11849            .iter()
11850            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11851            .collect::<Vec<_>>();
11852        language_server_ids.sort();
11853        language_server_ids.dedup();
11854
11855        // let abs_path = worktree_handle.read(cx).abs_path();
11856        for server_id in &language_server_ids {
11857            if let Some(LanguageServerState::Running { server, .. }) =
11858                local.language_servers.get(server_id)
11859                && let Some(watched_paths) = local
11860                    .language_server_watched_paths
11861                    .get(server_id)
11862                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11863            {
11864                let params = lsp::DidChangeWatchedFilesParams {
11865                    changes: changes
11866                        .iter()
11867                        .filter_map(|(path, _, change)| {
11868                            if !watched_paths.is_match(path.as_std_path()) {
11869                                return None;
11870                            }
11871                            let typ = match change {
11872                                PathChange::Loaded => return None,
11873                                PathChange::Added => lsp::FileChangeType::CREATED,
11874                                PathChange::Removed => lsp::FileChangeType::DELETED,
11875                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11876                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11877                            };
11878                            let uri = lsp::Uri::from_file_path(
11879                                worktree_handle.read(cx).absolutize(&path),
11880                            )
11881                            .ok()?;
11882                            Some(lsp::FileEvent { uri, typ })
11883                        })
11884                        .collect(),
11885                };
11886                if !params.changes.is_empty() {
11887                    server
11888                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11889                        .ok();
11890                }
11891            }
11892        }
11893        for (path, _, _) in changes {
11894            if let Some(file_name) = path.file_name()
11895                && local.watched_manifest_filenames.contains(file_name)
11896            {
11897                self.request_workspace_config_refresh();
11898                break;
11899            }
11900        }
11901    }
11902
11903    pub fn wait_for_remote_buffer(
11904        &mut self,
11905        id: BufferId,
11906        cx: &mut Context<Self>,
11907    ) -> Task<Result<Entity<Buffer>>> {
11908        self.buffer_store.update(cx, |buffer_store, cx| {
11909            buffer_store.wait_for_remote_buffer(id, cx)
11910        })
11911    }
11912
11913    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11914        let mut result = proto::Symbol {
11915            language_server_name: symbol.language_server_name.0.to_string(),
11916            source_worktree_id: symbol.source_worktree_id.to_proto(),
11917            language_server_id: symbol.source_language_server_id.to_proto(),
11918            name: symbol.name.clone(),
11919            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11920            start: Some(proto::PointUtf16 {
11921                row: symbol.range.start.0.row,
11922                column: symbol.range.start.0.column,
11923            }),
11924            end: Some(proto::PointUtf16 {
11925                row: symbol.range.end.0.row,
11926                column: symbol.range.end.0.column,
11927            }),
11928            worktree_id: Default::default(),
11929            path: Default::default(),
11930            signature: Default::default(),
11931        };
11932        match &symbol.path {
11933            SymbolLocation::InProject(path) => {
11934                result.worktree_id = path.worktree_id.to_proto();
11935                result.path = path.path.to_proto();
11936            }
11937            SymbolLocation::OutsideProject {
11938                abs_path,
11939                signature,
11940            } => {
11941                result.path = abs_path.to_string_lossy().into_owned();
11942                result.signature = signature.to_vec();
11943            }
11944        }
11945        result
11946    }
11947
11948    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11949        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11950        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11951        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11952
11953        let path = if serialized_symbol.signature.is_empty() {
11954            SymbolLocation::InProject(ProjectPath {
11955                worktree_id,
11956                path: RelPath::from_proto(&serialized_symbol.path)
11957                    .context("invalid symbol path")?,
11958            })
11959        } else {
11960            SymbolLocation::OutsideProject {
11961                abs_path: Path::new(&serialized_symbol.path).into(),
11962                signature: serialized_symbol
11963                    .signature
11964                    .try_into()
11965                    .map_err(|_| anyhow!("invalid signature"))?,
11966            }
11967        };
11968
11969        let start = serialized_symbol.start.context("invalid start")?;
11970        let end = serialized_symbol.end.context("invalid end")?;
11971        Ok(CoreSymbol {
11972            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11973            source_worktree_id,
11974            source_language_server_id: LanguageServerId::from_proto(
11975                serialized_symbol.language_server_id,
11976            ),
11977            path,
11978            name: serialized_symbol.name,
11979            range: Unclipped(PointUtf16::new(start.row, start.column))
11980                ..Unclipped(PointUtf16::new(end.row, end.column)),
11981            kind,
11982        })
11983    }
11984
11985    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11986        let mut serialized_completion = proto::Completion {
11987            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11988            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11989            new_text: completion.new_text.clone(),
11990            ..proto::Completion::default()
11991        };
11992        match &completion.source {
11993            CompletionSource::Lsp {
11994                insert_range,
11995                server_id,
11996                lsp_completion,
11997                lsp_defaults,
11998                resolved,
11999            } => {
12000                let (old_insert_start, old_insert_end) = insert_range
12001                    .as_ref()
12002                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
12003                    .unzip();
12004
12005                serialized_completion.old_insert_start = old_insert_start;
12006                serialized_completion.old_insert_end = old_insert_end;
12007                serialized_completion.source = proto::completion::Source::Lsp as i32;
12008                serialized_completion.server_id = server_id.0 as u64;
12009                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
12010                serialized_completion.lsp_defaults = lsp_defaults
12011                    .as_deref()
12012                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
12013                serialized_completion.resolved = *resolved;
12014            }
12015            CompletionSource::BufferWord {
12016                word_range,
12017                resolved,
12018            } => {
12019                serialized_completion.source = proto::completion::Source::BufferWord as i32;
12020                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
12021                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
12022                serialized_completion.resolved = *resolved;
12023            }
12024            CompletionSource::Custom => {
12025                serialized_completion.source = proto::completion::Source::Custom as i32;
12026                serialized_completion.resolved = true;
12027            }
12028            CompletionSource::Dap { sort_text } => {
12029                serialized_completion.source = proto::completion::Source::Dap as i32;
12030                serialized_completion.sort_text = Some(sort_text.clone());
12031            }
12032        }
12033
12034        serialized_completion
12035    }
12036
12037    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
12038        let old_replace_start = completion
12039            .old_replace_start
12040            .and_then(deserialize_anchor)
12041            .context("invalid old start")?;
12042        let old_replace_end = completion
12043            .old_replace_end
12044            .and_then(deserialize_anchor)
12045            .context("invalid old end")?;
12046        let insert_range = {
12047            match completion.old_insert_start.zip(completion.old_insert_end) {
12048                Some((start, end)) => {
12049                    let start = deserialize_anchor(start).context("invalid insert old start")?;
12050                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12051                    Some(start..end)
12052                }
12053                None => None,
12054            }
12055        };
12056        Ok(CoreCompletion {
12057            replace_range: old_replace_start..old_replace_end,
12058            new_text: completion.new_text,
12059            source: match proto::completion::Source::from_i32(completion.source) {
12060                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12061                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12062                    insert_range,
12063                    server_id: LanguageServerId::from_proto(completion.server_id),
12064                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12065                    lsp_defaults: completion
12066                        .lsp_defaults
12067                        .as_deref()
12068                        .map(serde_json::from_slice)
12069                        .transpose()?,
12070                    resolved: completion.resolved,
12071                },
12072                Some(proto::completion::Source::BufferWord) => {
12073                    let word_range = completion
12074                        .buffer_word_start
12075                        .and_then(deserialize_anchor)
12076                        .context("invalid buffer word start")?
12077                        ..completion
12078                            .buffer_word_end
12079                            .and_then(deserialize_anchor)
12080                            .context("invalid buffer word end")?;
12081                    CompletionSource::BufferWord {
12082                        word_range,
12083                        resolved: completion.resolved,
12084                    }
12085                }
12086                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12087                    sort_text: completion
12088                        .sort_text
12089                        .context("expected sort text to exist")?,
12090                },
12091                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12092            },
12093        })
12094    }
12095
12096    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12097        let (kind, lsp_action) = match &action.lsp_action {
12098            LspAction::Action(code_action) => (
12099                proto::code_action::Kind::Action as i32,
12100                serde_json::to_vec(code_action).unwrap(),
12101            ),
12102            LspAction::Command(command) => (
12103                proto::code_action::Kind::Command as i32,
12104                serde_json::to_vec(command).unwrap(),
12105            ),
12106            LspAction::CodeLens(code_lens) => (
12107                proto::code_action::Kind::CodeLens as i32,
12108                serde_json::to_vec(code_lens).unwrap(),
12109            ),
12110        };
12111
12112        proto::CodeAction {
12113            server_id: action.server_id.0 as u64,
12114            start: Some(serialize_anchor(&action.range.start)),
12115            end: Some(serialize_anchor(&action.range.end)),
12116            lsp_action,
12117            kind,
12118            resolved: action.resolved,
12119        }
12120    }
12121
12122    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12123        let start = action
12124            .start
12125            .and_then(deserialize_anchor)
12126            .context("invalid start")?;
12127        let end = action
12128            .end
12129            .and_then(deserialize_anchor)
12130            .context("invalid end")?;
12131        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12132            Some(proto::code_action::Kind::Action) => {
12133                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12134            }
12135            Some(proto::code_action::Kind::Command) => {
12136                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12137            }
12138            Some(proto::code_action::Kind::CodeLens) => {
12139                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12140            }
12141            None => anyhow::bail!("Unknown action kind {}", action.kind),
12142        };
12143        Ok(CodeAction {
12144            server_id: LanguageServerId(action.server_id as usize),
12145            range: start..end,
12146            resolved: action.resolved,
12147            lsp_action,
12148        })
12149    }
12150
12151    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12152        match &formatting_result {
12153            Ok(_) => self.last_formatting_failure = None,
12154            Err(error) => {
12155                let error_string = format!("{error:#}");
12156                log::error!("Formatting failed: {error_string}");
12157                self.last_formatting_failure
12158                    .replace(error_string.lines().join(" "));
12159            }
12160        }
12161    }
12162
12163    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12164        self.lsp_server_capabilities.remove(&for_server);
12165        for lsp_data in self.lsp_data.values_mut() {
12166            lsp_data.remove_server_data(for_server);
12167        }
12168        if let Some(local) = self.as_local_mut() {
12169            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12170            local
12171                .workspace_pull_diagnostics_result_ids
12172                .remove(&for_server);
12173            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12174                buffer_servers.remove(&for_server);
12175            }
12176        }
12177    }
12178
12179    pub fn result_id_for_buffer_pull(
12180        &self,
12181        server_id: LanguageServerId,
12182        buffer_id: BufferId,
12183        registration_id: &Option<SharedString>,
12184        cx: &App,
12185    ) -> Option<SharedString> {
12186        let abs_path = self
12187            .buffer_store
12188            .read(cx)
12189            .get(buffer_id)
12190            .and_then(|b| File::from_dyn(b.read(cx).file()))
12191            .map(|f| f.abs_path(cx))?;
12192        self.as_local()?
12193            .buffer_pull_diagnostics_result_ids
12194            .get(&server_id)?
12195            .get(registration_id)?
12196            .get(&abs_path)?
12197            .clone()
12198    }
12199
12200    /// Gets all result_ids for a workspace diagnostics pull request.
12201    /// 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.
12202    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12203    pub fn result_ids_for_workspace_refresh(
12204        &self,
12205        server_id: LanguageServerId,
12206        registration_id: &Option<SharedString>,
12207    ) -> HashMap<PathBuf, SharedString> {
12208        let Some(local) = self.as_local() else {
12209            return HashMap::default();
12210        };
12211        local
12212            .workspace_pull_diagnostics_result_ids
12213            .get(&server_id)
12214            .into_iter()
12215            .filter_map(|diagnostics| diagnostics.get(registration_id))
12216            .flatten()
12217            .filter_map(|(abs_path, result_id)| {
12218                let result_id = local
12219                    .buffer_pull_diagnostics_result_ids
12220                    .get(&server_id)
12221                    .and_then(|buffer_ids_result_ids| {
12222                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12223                    })
12224                    .cloned()
12225                    .flatten()
12226                    .or_else(|| result_id.clone())?;
12227                Some((abs_path.clone(), result_id))
12228            })
12229            .collect()
12230    }
12231
12232    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12233        if let Some(LanguageServerState::Running {
12234            workspace_diagnostics_refresh_tasks,
12235            ..
12236        }) = self
12237            .as_local_mut()
12238            .and_then(|local| local.language_servers.get_mut(&server_id))
12239        {
12240            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12241                diagnostics.refresh_tx.try_send(()).ok();
12242            }
12243        }
12244    }
12245
12246    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12247    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12248    /// which requires refreshing both workspace and document diagnostics.
12249    pub fn pull_document_diagnostics_for_server(
12250        &mut self,
12251        server_id: LanguageServerId,
12252        cx: &mut Context<Self>,
12253    ) -> Task<()> {
12254        let buffers_to_pull = self
12255            .as_local()
12256            .into_iter()
12257            .flat_map(|local| {
12258                self.buffer_store.read(cx).buffers().filter(|buffer| {
12259                    let buffer_id = buffer.read(cx).remote_id();
12260                    local
12261                        .buffers_opened_in_servers
12262                        .get(&buffer_id)
12263                        .is_some_and(|servers| servers.contains(&server_id))
12264                })
12265            })
12266            .collect::<Vec<_>>();
12267
12268        let pulls = join_all(buffers_to_pull.into_iter().map(|buffer| {
12269            let buffer_path = buffer.read(cx).file().map(|f| f.full_path(cx));
12270            let pull_task = self.pull_diagnostics_for_buffer(buffer, cx);
12271            async move { (buffer_path, pull_task.await) }
12272        }));
12273        cx.background_spawn(async move {
12274            for (pull_task_path, pull_task_result) in pulls.await {
12275                if let Err(e) = pull_task_result {
12276                    match pull_task_path {
12277                        Some(path) => {
12278                            log::error!("Failed to pull diagnostics for buffer {path:?}: {e:#}");
12279                        }
12280                        None => log::error!("Failed to pull diagnostics: {e:#}"),
12281                    }
12282                }
12283            }
12284        })
12285    }
12286
12287    fn apply_workspace_diagnostic_report(
12288        &mut self,
12289        server_id: LanguageServerId,
12290        report: lsp::WorkspaceDiagnosticReportResult,
12291        registration_id: Option<SharedString>,
12292        cx: &mut Context<Self>,
12293    ) {
12294        let mut workspace_diagnostics =
12295            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12296                report,
12297                server_id,
12298                registration_id,
12299            );
12300        workspace_diagnostics.retain(|d| match &d.diagnostics {
12301            LspPullDiagnostics::Response {
12302                server_id,
12303                registration_id,
12304                ..
12305            } => self.diagnostic_registration_exists(*server_id, registration_id),
12306            LspPullDiagnostics::Default => false,
12307        });
12308        let mut unchanged_buffers = HashMap::default();
12309        let workspace_diagnostics_updates = workspace_diagnostics
12310            .into_iter()
12311            .filter_map(
12312                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12313                    LspPullDiagnostics::Response {
12314                        server_id,
12315                        uri,
12316                        diagnostics,
12317                        registration_id,
12318                    } => Some((
12319                        server_id,
12320                        uri,
12321                        diagnostics,
12322                        workspace_diagnostics.version,
12323                        registration_id,
12324                    )),
12325                    LspPullDiagnostics::Default => None,
12326                },
12327            )
12328            .fold(
12329                HashMap::default(),
12330                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12331                    let (result_id, diagnostics) = match diagnostics {
12332                        PulledDiagnostics::Unchanged { result_id } => {
12333                            unchanged_buffers
12334                                .entry(new_registration_id.clone())
12335                                .or_insert_with(HashSet::default)
12336                                .insert(uri.clone());
12337                            (Some(result_id), Vec::new())
12338                        }
12339                        PulledDiagnostics::Changed {
12340                            result_id,
12341                            diagnostics,
12342                        } => (result_id, diagnostics),
12343                    };
12344                    let disk_based_sources = Cow::Owned(
12345                        self.language_server_adapter_for_id(server_id)
12346                            .as_ref()
12347                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12348                            .unwrap_or(&[])
12349                            .to_vec(),
12350                    );
12351
12352                    let Some(abs_path) = uri.to_file_path().ok() else {
12353                        return acc;
12354                    };
12355                    let Some((worktree, relative_path)) =
12356                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12357                    else {
12358                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12359                        return acc;
12360                    };
12361                    let worktree_id = worktree.read(cx).id();
12362                    let project_path = ProjectPath {
12363                        worktree_id,
12364                        path: relative_path,
12365                    };
12366                    if let Some(local_lsp_store) = self.as_local_mut() {
12367                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12368                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12369                    }
12370                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12371                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12372                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12373                        acc.entry(server_id)
12374                            .or_insert_with(HashMap::default)
12375                            .entry(new_registration_id.clone())
12376                            .or_insert_with(Vec::new)
12377                            .push(DocumentDiagnosticsUpdate {
12378                                server_id,
12379                                diagnostics: lsp::PublishDiagnosticsParams {
12380                                    uri,
12381                                    diagnostics,
12382                                    version,
12383                                },
12384                                result_id,
12385                                disk_based_sources,
12386                                registration_id: new_registration_id,
12387                            });
12388                    }
12389                    acc
12390                },
12391            );
12392
12393        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12394            for (registration_id, diagnostic_updates) in diagnostic_updates {
12395                self.merge_lsp_diagnostics(
12396                    DiagnosticSourceKind::Pulled,
12397                    diagnostic_updates,
12398                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12399                        DiagnosticSourceKind::Pulled => {
12400                            old_diagnostic.registration_id != registration_id
12401                                || unchanged_buffers
12402                                    .get(&old_diagnostic.registration_id)
12403                                    .is_some_and(|unchanged_buffers| {
12404                                        unchanged_buffers.contains(&document_uri)
12405                                    })
12406                        }
12407                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12408                    },
12409                    cx,
12410                )
12411                .log_err();
12412            }
12413        }
12414    }
12415
12416    fn register_server_capabilities(
12417        &mut self,
12418        server_id: LanguageServerId,
12419        params: lsp::RegistrationParams,
12420        cx: &mut Context<Self>,
12421    ) -> anyhow::Result<()> {
12422        let server = self
12423            .language_server_for_id(server_id)
12424            .with_context(|| format!("no server {server_id} found"))?;
12425        for reg in params.registrations {
12426            match reg.method.as_str() {
12427                "workspace/didChangeWatchedFiles" => {
12428                    if let Some(options) = reg.register_options {
12429                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12430                            let caps = serde_json::from_value(options)?;
12431                            local_lsp_store
12432                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12433                            true
12434                        } else {
12435                            false
12436                        };
12437                        if notify {
12438                            notify_server_capabilities_updated(&server, cx);
12439                        }
12440                    }
12441                }
12442                "workspace/didChangeConfiguration" => {
12443                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12444                }
12445                "workspace/didChangeWorkspaceFolders" => {
12446                    // In this case register options is an empty object, we can ignore it
12447                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12448                        supported: Some(true),
12449                        change_notifications: Some(OneOf::Right(reg.id)),
12450                    };
12451                    server.update_capabilities(|capabilities| {
12452                        capabilities
12453                            .workspace
12454                            .get_or_insert_default()
12455                            .workspace_folders = Some(caps);
12456                    });
12457                    notify_server_capabilities_updated(&server, cx);
12458                }
12459                "workspace/symbol" => {
12460                    let options = parse_register_capabilities(reg)?;
12461                    server.update_capabilities(|capabilities| {
12462                        capabilities.workspace_symbol_provider = Some(options);
12463                    });
12464                    notify_server_capabilities_updated(&server, cx);
12465                }
12466                "workspace/fileOperations" => {
12467                    if let Some(options) = reg.register_options {
12468                        let caps = serde_json::from_value(options)?;
12469                        server.update_capabilities(|capabilities| {
12470                            capabilities
12471                                .workspace
12472                                .get_or_insert_default()
12473                                .file_operations = Some(caps);
12474                        });
12475                        notify_server_capabilities_updated(&server, cx);
12476                    }
12477                }
12478                "workspace/executeCommand" => {
12479                    if let Some(options) = reg.register_options {
12480                        let options = serde_json::from_value(options)?;
12481                        server.update_capabilities(|capabilities| {
12482                            capabilities.execute_command_provider = Some(options);
12483                        });
12484                        notify_server_capabilities_updated(&server, cx);
12485                    }
12486                }
12487                "textDocument/rangeFormatting" => {
12488                    let options = parse_register_capabilities(reg)?;
12489                    server.update_capabilities(|capabilities| {
12490                        capabilities.document_range_formatting_provider = Some(options);
12491                    });
12492                    notify_server_capabilities_updated(&server, cx);
12493                }
12494                "textDocument/onTypeFormatting" => {
12495                    if let Some(options) = reg
12496                        .register_options
12497                        .map(serde_json::from_value)
12498                        .transpose()?
12499                    {
12500                        server.update_capabilities(|capabilities| {
12501                            capabilities.document_on_type_formatting_provider = Some(options);
12502                        });
12503                        notify_server_capabilities_updated(&server, cx);
12504                    }
12505                }
12506                "textDocument/formatting" => {
12507                    let options = parse_register_capabilities(reg)?;
12508                    server.update_capabilities(|capabilities| {
12509                        capabilities.document_formatting_provider = Some(options);
12510                    });
12511                    notify_server_capabilities_updated(&server, cx);
12512                }
12513                "textDocument/rename" => {
12514                    let options = parse_register_capabilities(reg)?;
12515                    server.update_capabilities(|capabilities| {
12516                        capabilities.rename_provider = Some(options);
12517                    });
12518                    notify_server_capabilities_updated(&server, cx);
12519                }
12520                "textDocument/inlayHint" => {
12521                    let options = parse_register_capabilities(reg)?;
12522                    server.update_capabilities(|capabilities| {
12523                        capabilities.inlay_hint_provider = Some(options);
12524                    });
12525                    notify_server_capabilities_updated(&server, cx);
12526                }
12527                "textDocument/documentSymbol" => {
12528                    let options = parse_register_capabilities(reg)?;
12529                    server.update_capabilities(|capabilities| {
12530                        capabilities.document_symbol_provider = Some(options);
12531                    });
12532                    notify_server_capabilities_updated(&server, cx);
12533                }
12534                "textDocument/codeAction" => {
12535                    let options = parse_register_capabilities(reg)?;
12536                    let provider = match options {
12537                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12538                        OneOf::Right(caps) => caps,
12539                    };
12540                    server.update_capabilities(|capabilities| {
12541                        capabilities.code_action_provider = Some(provider);
12542                    });
12543                    notify_server_capabilities_updated(&server, cx);
12544                }
12545                "textDocument/definition" => {
12546                    let options = parse_register_capabilities(reg)?;
12547                    server.update_capabilities(|capabilities| {
12548                        capabilities.definition_provider = Some(options);
12549                    });
12550                    notify_server_capabilities_updated(&server, cx);
12551                }
12552                "textDocument/completion" => {
12553                    if let Some(caps) = reg
12554                        .register_options
12555                        .map(serde_json::from_value::<CompletionOptions>)
12556                        .transpose()?
12557                    {
12558                        server.update_capabilities(|capabilities| {
12559                            capabilities.completion_provider = Some(caps.clone());
12560                        });
12561
12562                        if let Some(local) = self.as_local() {
12563                            let mut buffers_with_language_server = Vec::new();
12564                            for handle in self.buffer_store.read(cx).buffers() {
12565                                let buffer_id = handle.read(cx).remote_id();
12566                                if local
12567                                    .buffers_opened_in_servers
12568                                    .get(&buffer_id)
12569                                    .filter(|s| s.contains(&server_id))
12570                                    .is_some()
12571                                {
12572                                    buffers_with_language_server.push(handle);
12573                                }
12574                            }
12575                            let triggers = caps
12576                                .trigger_characters
12577                                .unwrap_or_default()
12578                                .into_iter()
12579                                .collect::<BTreeSet<_>>();
12580                            for handle in buffers_with_language_server {
12581                                let triggers = triggers.clone();
12582                                let _ = handle.update(cx, move |buffer, cx| {
12583                                    buffer.set_completion_triggers(server_id, triggers, cx);
12584                                });
12585                            }
12586                        }
12587                        notify_server_capabilities_updated(&server, cx);
12588                    }
12589                }
12590                "textDocument/hover" => {
12591                    let options = parse_register_capabilities(reg)?;
12592                    let provider = match options {
12593                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12594                        OneOf::Right(caps) => caps,
12595                    };
12596                    server.update_capabilities(|capabilities| {
12597                        capabilities.hover_provider = Some(provider);
12598                    });
12599                    notify_server_capabilities_updated(&server, cx);
12600                }
12601                "textDocument/signatureHelp" => {
12602                    if let Some(caps) = reg
12603                        .register_options
12604                        .map(serde_json::from_value)
12605                        .transpose()?
12606                    {
12607                        server.update_capabilities(|capabilities| {
12608                            capabilities.signature_help_provider = Some(caps);
12609                        });
12610                        notify_server_capabilities_updated(&server, cx);
12611                    }
12612                }
12613                "textDocument/didChange" => {
12614                    if let Some(sync_kind) = reg
12615                        .register_options
12616                        .and_then(|opts| opts.get("syncKind").cloned())
12617                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12618                        .transpose()?
12619                    {
12620                        server.update_capabilities(|capabilities| {
12621                            let mut sync_options =
12622                                Self::take_text_document_sync_options(capabilities);
12623                            sync_options.change = Some(sync_kind);
12624                            capabilities.text_document_sync =
12625                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12626                        });
12627                        notify_server_capabilities_updated(&server, cx);
12628                    }
12629                }
12630                "textDocument/didSave" => {
12631                    if let Some(include_text) = reg
12632                        .register_options
12633                        .map(|opts| {
12634                            let transpose = opts
12635                                .get("includeText")
12636                                .cloned()
12637                                .map(serde_json::from_value::<Option<bool>>)
12638                                .transpose();
12639                            match transpose {
12640                                Ok(value) => Ok(value.flatten()),
12641                                Err(e) => Err(e),
12642                            }
12643                        })
12644                        .transpose()?
12645                    {
12646                        server.update_capabilities(|capabilities| {
12647                            let mut sync_options =
12648                                Self::take_text_document_sync_options(capabilities);
12649                            sync_options.save =
12650                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12651                                    include_text,
12652                                }));
12653                            capabilities.text_document_sync =
12654                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12655                        });
12656                        notify_server_capabilities_updated(&server, cx);
12657                    }
12658                }
12659                "textDocument/codeLens" => {
12660                    if let Some(caps) = reg
12661                        .register_options
12662                        .map(serde_json::from_value)
12663                        .transpose()?
12664                    {
12665                        server.update_capabilities(|capabilities| {
12666                            capabilities.code_lens_provider = Some(caps);
12667                        });
12668                        notify_server_capabilities_updated(&server, cx);
12669                    }
12670                }
12671                "textDocument/diagnostic" => {
12672                    if let Some(caps) = reg
12673                        .register_options
12674                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12675                        .transpose()?
12676                    {
12677                        let local = self
12678                            .as_local_mut()
12679                            .context("Expected LSP Store to be local")?;
12680                        let state = local
12681                            .language_servers
12682                            .get_mut(&server_id)
12683                            .context("Could not obtain Language Servers state")?;
12684                        local
12685                            .language_server_dynamic_registrations
12686                            .entry(server_id)
12687                            .or_default()
12688                            .diagnostics
12689                            .insert(Some(reg.id.clone()), caps.clone());
12690
12691                        let supports_workspace_diagnostics =
12692                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12693                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12694                                    diagnostic_options.workspace_diagnostics
12695                                }
12696                                DiagnosticServerCapabilities::RegistrationOptions(
12697                                    diagnostic_registration_options,
12698                                ) => {
12699                                    diagnostic_registration_options
12700                                        .diagnostic_options
12701                                        .workspace_diagnostics
12702                                }
12703                            };
12704
12705                        if supports_workspace_diagnostics(&caps) {
12706                            if let LanguageServerState::Running {
12707                                workspace_diagnostics_refresh_tasks,
12708                                ..
12709                            } = state
12710                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12711                                    Some(reg.id.clone()),
12712                                    caps.clone(),
12713                                    server.clone(),
12714                                    cx,
12715                                )
12716                            {
12717                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12718                            }
12719                        }
12720
12721                        server.update_capabilities(|capabilities| {
12722                            capabilities.diagnostic_provider = Some(caps);
12723                        });
12724
12725                        notify_server_capabilities_updated(&server, cx);
12726
12727                        self.pull_document_diagnostics_for_server(server_id, cx)
12728                            .detach();
12729                    }
12730                }
12731                "textDocument/documentColor" => {
12732                    let options = parse_register_capabilities(reg)?;
12733                    let provider = match options {
12734                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12735                        OneOf::Right(caps) => caps,
12736                    };
12737                    server.update_capabilities(|capabilities| {
12738                        capabilities.color_provider = Some(provider);
12739                    });
12740                    notify_server_capabilities_updated(&server, cx);
12741                }
12742                _ => log::warn!("unhandled capability registration: {reg:?}"),
12743            }
12744        }
12745
12746        Ok(())
12747    }
12748
12749    fn unregister_server_capabilities(
12750        &mut self,
12751        server_id: LanguageServerId,
12752        params: lsp::UnregistrationParams,
12753        cx: &mut Context<Self>,
12754    ) -> anyhow::Result<()> {
12755        let server = self
12756            .language_server_for_id(server_id)
12757            .with_context(|| format!("no server {server_id} found"))?;
12758        for unreg in params.unregisterations.iter() {
12759            match unreg.method.as_str() {
12760                "workspace/didChangeWatchedFiles" => {
12761                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12762                        local_lsp_store
12763                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12764                        true
12765                    } else {
12766                        false
12767                    };
12768                    if notify {
12769                        notify_server_capabilities_updated(&server, cx);
12770                    }
12771                }
12772                "workspace/didChangeConfiguration" => {
12773                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12774                }
12775                "workspace/didChangeWorkspaceFolders" => {
12776                    server.update_capabilities(|capabilities| {
12777                        capabilities
12778                            .workspace
12779                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12780                                workspace_folders: None,
12781                                file_operations: None,
12782                            })
12783                            .workspace_folders = None;
12784                    });
12785                    notify_server_capabilities_updated(&server, cx);
12786                }
12787                "workspace/symbol" => {
12788                    server.update_capabilities(|capabilities| {
12789                        capabilities.workspace_symbol_provider = None
12790                    });
12791                    notify_server_capabilities_updated(&server, cx);
12792                }
12793                "workspace/fileOperations" => {
12794                    server.update_capabilities(|capabilities| {
12795                        capabilities
12796                            .workspace
12797                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12798                                workspace_folders: None,
12799                                file_operations: None,
12800                            })
12801                            .file_operations = None;
12802                    });
12803                    notify_server_capabilities_updated(&server, cx);
12804                }
12805                "workspace/executeCommand" => {
12806                    server.update_capabilities(|capabilities| {
12807                        capabilities.execute_command_provider = None;
12808                    });
12809                    notify_server_capabilities_updated(&server, cx);
12810                }
12811                "textDocument/rangeFormatting" => {
12812                    server.update_capabilities(|capabilities| {
12813                        capabilities.document_range_formatting_provider = None
12814                    });
12815                    notify_server_capabilities_updated(&server, cx);
12816                }
12817                "textDocument/onTypeFormatting" => {
12818                    server.update_capabilities(|capabilities| {
12819                        capabilities.document_on_type_formatting_provider = None;
12820                    });
12821                    notify_server_capabilities_updated(&server, cx);
12822                }
12823                "textDocument/formatting" => {
12824                    server.update_capabilities(|capabilities| {
12825                        capabilities.document_formatting_provider = None;
12826                    });
12827                    notify_server_capabilities_updated(&server, cx);
12828                }
12829                "textDocument/rename" => {
12830                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12831                    notify_server_capabilities_updated(&server, cx);
12832                }
12833                "textDocument/codeAction" => {
12834                    server.update_capabilities(|capabilities| {
12835                        capabilities.code_action_provider = None;
12836                    });
12837                    notify_server_capabilities_updated(&server, cx);
12838                }
12839                "textDocument/definition" => {
12840                    server.update_capabilities(|capabilities| {
12841                        capabilities.definition_provider = None;
12842                    });
12843                    notify_server_capabilities_updated(&server, cx);
12844                }
12845                "textDocument/completion" => {
12846                    server.update_capabilities(|capabilities| {
12847                        capabilities.completion_provider = None;
12848                    });
12849                    notify_server_capabilities_updated(&server, cx);
12850                }
12851                "textDocument/hover" => {
12852                    server.update_capabilities(|capabilities| {
12853                        capabilities.hover_provider = None;
12854                    });
12855                    notify_server_capabilities_updated(&server, cx);
12856                }
12857                "textDocument/signatureHelp" => {
12858                    server.update_capabilities(|capabilities| {
12859                        capabilities.signature_help_provider = None;
12860                    });
12861                    notify_server_capabilities_updated(&server, cx);
12862                }
12863                "textDocument/didChange" => {
12864                    server.update_capabilities(|capabilities| {
12865                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12866                        sync_options.change = None;
12867                        capabilities.text_document_sync =
12868                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12869                    });
12870                    notify_server_capabilities_updated(&server, cx);
12871                }
12872                "textDocument/didSave" => {
12873                    server.update_capabilities(|capabilities| {
12874                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12875                        sync_options.save = None;
12876                        capabilities.text_document_sync =
12877                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12878                    });
12879                    notify_server_capabilities_updated(&server, cx);
12880                }
12881                "textDocument/codeLens" => {
12882                    server.update_capabilities(|capabilities| {
12883                        capabilities.code_lens_provider = None;
12884                    });
12885                    notify_server_capabilities_updated(&server, cx);
12886                }
12887                "textDocument/diagnostic" => {
12888                    let local = self
12889                        .as_local_mut()
12890                        .context("Expected LSP Store to be local")?;
12891
12892                    let state = local
12893                        .language_servers
12894                        .get_mut(&server_id)
12895                        .context("Could not obtain Language Servers state")?;
12896                    let registrations = local
12897                        .language_server_dynamic_registrations
12898                        .get_mut(&server_id)
12899                        .with_context(|| {
12900                            format!("Expected dynamic registration to exist for server {server_id}")
12901                        })?;
12902                    registrations.diagnostics
12903                        .remove(&Some(unreg.id.clone()))
12904                        .with_context(|| format!(
12905                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12906                            unreg.id)
12907                        )?;
12908                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12909
12910                    if let LanguageServerState::Running {
12911                        workspace_diagnostics_refresh_tasks,
12912                        ..
12913                    } = state
12914                    {
12915                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12916                    }
12917
12918                    self.clear_unregistered_diagnostics(
12919                        server_id,
12920                        SharedString::from(unreg.id.clone()),
12921                        cx,
12922                    )?;
12923
12924                    if removed_last_diagnostic_provider {
12925                        server.update_capabilities(|capabilities| {
12926                            debug_assert!(capabilities.diagnostic_provider.is_some());
12927                            capabilities.diagnostic_provider = None;
12928                        });
12929                    }
12930
12931                    notify_server_capabilities_updated(&server, cx);
12932                }
12933                "textDocument/documentColor" => {
12934                    server.update_capabilities(|capabilities| {
12935                        capabilities.color_provider = None;
12936                    });
12937                    notify_server_capabilities_updated(&server, cx);
12938                }
12939                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12940            }
12941        }
12942
12943        Ok(())
12944    }
12945
12946    fn clear_unregistered_diagnostics(
12947        &mut self,
12948        server_id: LanguageServerId,
12949        cleared_registration_id: SharedString,
12950        cx: &mut Context<Self>,
12951    ) -> anyhow::Result<()> {
12952        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12953
12954        self.buffer_store.update(cx, |buffer_store, cx| {
12955            for buffer_handle in buffer_store.buffers() {
12956                let buffer = buffer_handle.read(cx);
12957                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12958                let Some(abs_path) = abs_path else {
12959                    continue;
12960                };
12961                affected_abs_paths.insert(abs_path);
12962            }
12963        });
12964
12965        let local = self.as_local().context("Expected LSP Store to be local")?;
12966        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12967            let Some(worktree) = self
12968                .worktree_store
12969                .read(cx)
12970                .worktree_for_id(*worktree_id, cx)
12971            else {
12972                continue;
12973            };
12974
12975            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
12976                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
12977                    let has_matching_registration =
12978                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
12979                            entry.diagnostic.registration_id.as_ref()
12980                                == Some(&cleared_registration_id)
12981                        });
12982                    if has_matching_registration {
12983                        let abs_path = worktree.read(cx).absolutize(rel_path);
12984                        affected_abs_paths.insert(abs_path);
12985                    }
12986                }
12987            }
12988        }
12989
12990        if affected_abs_paths.is_empty() {
12991            return Ok(());
12992        }
12993
12994        // Send a fake diagnostic update which clears the state for the registration ID
12995        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
12996            affected_abs_paths
12997                .into_iter()
12998                .map(|abs_path| DocumentDiagnosticsUpdate {
12999                    diagnostics: DocumentDiagnostics {
13000                        diagnostics: Vec::new(),
13001                        document_abs_path: abs_path,
13002                        version: None,
13003                    },
13004                    result_id: None,
13005                    registration_id: Some(cleared_registration_id.clone()),
13006                    server_id,
13007                    disk_based_sources: Cow::Borrowed(&[]),
13008                })
13009                .collect();
13010
13011        let merge_registration_id = cleared_registration_id.clone();
13012        self.merge_diagnostic_entries(
13013            clears,
13014            move |_, diagnostic, _| {
13015                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
13016                    diagnostic.registration_id != Some(merge_registration_id.clone())
13017                } else {
13018                    true
13019                }
13020            },
13021            cx,
13022        )?;
13023
13024        Ok(())
13025    }
13026
13027    async fn deduplicate_range_based_lsp_requests<T>(
13028        lsp_store: &Entity<Self>,
13029        server_id: Option<LanguageServerId>,
13030        lsp_request_id: LspRequestId,
13031        proto_request: &T::ProtoRequest,
13032        range: Range<Anchor>,
13033        cx: &mut AsyncApp,
13034    ) -> Result<()>
13035    where
13036        T: LspCommand,
13037        T::ProtoRequest: proto::LspRequestMessage,
13038    {
13039        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13040        let version = deserialize_version(proto_request.buffer_version());
13041        let buffer = lsp_store.update(cx, |this, cx| {
13042            this.buffer_store.read(cx).get_existing(buffer_id)
13043        })?;
13044        buffer
13045            .update(cx, |buffer, _| buffer.wait_for_version(version))
13046            .await?;
13047        lsp_store.update(cx, |lsp_store, cx| {
13048            let buffer_snapshot = buffer.read(cx).snapshot();
13049            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13050            let chunks_queried_for = lsp_data
13051                .inlay_hints
13052                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
13053                .collect::<Vec<_>>();
13054            match chunks_queried_for.as_slice() {
13055                &[chunk] => {
13056                    let key = LspKey {
13057                        request_type: TypeId::of::<T>(),
13058                        server_queried: server_id,
13059                    };
13060                    let previous_request = lsp_data
13061                        .chunk_lsp_requests
13062                        .entry(key)
13063                        .or_default()
13064                        .insert(chunk, lsp_request_id);
13065                    if let Some((previous_request, running_requests)) =
13066                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13067                    {
13068                        running_requests.remove(&previous_request);
13069                    }
13070                }
13071                _ambiguous_chunks => {
13072                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13073                    // there, a buffer version-based check will be performed and outdated requests discarded.
13074                }
13075            }
13076            anyhow::Ok(())
13077        })?;
13078
13079        Ok(())
13080    }
13081
13082    async fn query_lsp_locally<T>(
13083        lsp_store: Entity<Self>,
13084        for_server_id: Option<LanguageServerId>,
13085        sender_id: proto::PeerId,
13086        lsp_request_id: LspRequestId,
13087        proto_request: T::ProtoRequest,
13088        position: Option<Anchor>,
13089        cx: &mut AsyncApp,
13090    ) -> Result<()>
13091    where
13092        T: LspCommand + Clone,
13093        T::ProtoRequest: proto::LspRequestMessage,
13094        <T::ProtoRequest as proto::RequestMessage>::Response:
13095            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13096    {
13097        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13098        let version = deserialize_version(proto_request.buffer_version());
13099        let buffer = lsp_store.update(cx, |this, cx| {
13100            this.buffer_store.read(cx).get_existing(buffer_id)
13101        })?;
13102        buffer
13103            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13104            .await?;
13105        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13106        let request =
13107            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13108        let key = LspKey {
13109            request_type: TypeId::of::<T>(),
13110            server_queried: for_server_id,
13111        };
13112        lsp_store.update(cx, |lsp_store, cx| {
13113            let request_task = match for_server_id {
13114                Some(server_id) => {
13115                    let server_task = lsp_store.request_lsp(
13116                        buffer.clone(),
13117                        LanguageServerToQuery::Other(server_id),
13118                        request.clone(),
13119                        cx,
13120                    );
13121                    cx.background_spawn(async move {
13122                        let mut responses = Vec::new();
13123                        match server_task.await {
13124                            Ok(response) => responses.push((server_id, response)),
13125                            // rust-analyzer likes to error with this when its still loading up
13126                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13127                            Err(e) => log::error!(
13128                                "Error handling response for request {request:?}: {e:#}"
13129                            ),
13130                        }
13131                        responses
13132                    })
13133                }
13134                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13135            };
13136            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13137            if T::ProtoRequest::stop_previous_requests() {
13138                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13139                    lsp_requests.clear();
13140                }
13141            }
13142            lsp_data.lsp_requests.entry(key).or_default().insert(
13143                lsp_request_id,
13144                cx.spawn(async move |lsp_store, cx| {
13145                    let response = request_task.await;
13146                    lsp_store
13147                        .update(cx, |lsp_store, cx| {
13148                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13149                            {
13150                                let response = response
13151                                    .into_iter()
13152                                    .map(|(server_id, response)| {
13153                                        (
13154                                            server_id.to_proto(),
13155                                            T::response_to_proto(
13156                                                response,
13157                                                lsp_store,
13158                                                sender_id,
13159                                                &buffer_version,
13160                                                cx,
13161                                            )
13162                                            .into(),
13163                                        )
13164                                    })
13165                                    .collect::<HashMap<_, _>>();
13166                                match client.send_lsp_response::<T::ProtoRequest>(
13167                                    project_id,
13168                                    lsp_request_id,
13169                                    response,
13170                                ) {
13171                                    Ok(()) => {}
13172                                    Err(e) => {
13173                                        log::error!("Failed to send LSP response: {e:#}",)
13174                                    }
13175                                }
13176                            }
13177                        })
13178                        .ok();
13179                }),
13180            );
13181        });
13182        Ok(())
13183    }
13184
13185    fn take_text_document_sync_options(
13186        capabilities: &mut lsp::ServerCapabilities,
13187    ) -> lsp::TextDocumentSyncOptions {
13188        match capabilities.text_document_sync.take() {
13189            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13190            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13191                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13192                sync_options.change = Some(sync_kind);
13193                sync_options
13194            }
13195            None => lsp::TextDocumentSyncOptions::default(),
13196        }
13197    }
13198
13199    #[cfg(any(test, feature = "test-support"))]
13200    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
13201        Some(
13202            self.lsp_data
13203                .get_mut(&buffer_id)?
13204                .code_lens
13205                .take()?
13206                .update
13207                .take()?
13208                .1,
13209        )
13210    }
13211
13212    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13213        self.downstream_client.clone()
13214    }
13215
13216    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13217        self.worktree_store.clone()
13218    }
13219
13220    /// Gets what's stored in the LSP data for the given buffer.
13221    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13222        self.lsp_data.get_mut(&buffer_id)
13223    }
13224
13225    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13226    /// new [`BufferLspData`] will be created to replace the previous state.
13227    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13228        let (buffer_id, buffer_version) =
13229            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13230        let lsp_data = self
13231            .lsp_data
13232            .entry(buffer_id)
13233            .or_insert_with(|| BufferLspData::new(buffer, cx));
13234        if buffer_version.changed_since(&lsp_data.buffer_version) {
13235            *lsp_data = BufferLspData::new(buffer, cx);
13236        }
13237        lsp_data
13238    }
13239}
13240
13241// Registration with registerOptions as null, should fallback to true.
13242// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13243fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13244    reg: lsp::Registration,
13245) -> Result<OneOf<bool, T>> {
13246    Ok(match reg.register_options {
13247        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13248        None => OneOf::Left(true),
13249    })
13250}
13251
13252fn subscribe_to_binary_statuses(
13253    languages: &Arc<LanguageRegistry>,
13254    cx: &mut Context<'_, LspStore>,
13255) -> Task<()> {
13256    let mut server_statuses = languages.language_server_binary_statuses();
13257    cx.spawn(async move |lsp_store, cx| {
13258        while let Some((server_name, binary_status)) = server_statuses.next().await {
13259            if lsp_store
13260                .update(cx, |_, cx| {
13261                    let mut message = None;
13262                    let binary_status = match binary_status {
13263                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13264                        BinaryStatus::CheckingForUpdate => {
13265                            proto::ServerBinaryStatus::CheckingForUpdate
13266                        }
13267                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13268                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13269                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13270                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13271                        BinaryStatus::Failed { error } => {
13272                            message = Some(error);
13273                            proto::ServerBinaryStatus::Failed
13274                        }
13275                    };
13276                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13277                        // Binary updates are about the binary that might not have any language server id at that point.
13278                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13279                        language_server_id: LanguageServerId(0),
13280                        name: Some(server_name),
13281                        message: proto::update_language_server::Variant::StatusUpdate(
13282                            proto::StatusUpdate {
13283                                message,
13284                                status: Some(proto::status_update::Status::Binary(
13285                                    binary_status as i32,
13286                                )),
13287                            },
13288                        ),
13289                    });
13290                })
13291                .is_err()
13292            {
13293                break;
13294            }
13295        }
13296    })
13297}
13298
13299fn lsp_workspace_diagnostics_refresh(
13300    registration_id: Option<String>,
13301    options: DiagnosticServerCapabilities,
13302    server: Arc<LanguageServer>,
13303    cx: &mut Context<'_, LspStore>,
13304) -> Option<WorkspaceRefreshTask> {
13305    let identifier = workspace_diagnostic_identifier(&options)?;
13306    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13307
13308    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13309    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13310    refresh_tx.try_send(()).ok();
13311
13312    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13313        let mut attempts = 0;
13314        let max_attempts = 50;
13315        let mut requests = 0;
13316
13317        loop {
13318            let Some(()) = refresh_rx.recv().await else {
13319                return;
13320            };
13321
13322            'request: loop {
13323                requests += 1;
13324                if attempts > max_attempts {
13325                    log::error!(
13326                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13327                    );
13328                    return;
13329                }
13330                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13331                cx.background_executor()
13332                    .timer(Duration::from_millis(backoff_millis))
13333                    .await;
13334                attempts += 1;
13335
13336                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13337                    lsp_store
13338                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13339                        .into_iter()
13340                        .filter_map(|(abs_path, result_id)| {
13341                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13342                            Some(lsp::PreviousResultId {
13343                                uri,
13344                                value: result_id.to_string(),
13345                            })
13346                        })
13347                        .collect()
13348                }) else {
13349                    return;
13350                };
13351
13352                let token = if let Some(registration_id) = &registration_id {
13353                    format!(
13354                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13355                        server.server_id(),
13356                    )
13357                } else {
13358                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13359                };
13360
13361                progress_rx.try_recv().ok();
13362                let timer =
13363                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13364                let progress = pin!(progress_rx.recv().fuse());
13365                let response_result = server
13366                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13367                        lsp::WorkspaceDiagnosticParams {
13368                            previous_result_ids,
13369                            identifier: identifier.clone(),
13370                            work_done_progress_params: Default::default(),
13371                            partial_result_params: lsp::PartialResultParams {
13372                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13373                            },
13374                        },
13375                        select(timer, progress).then(|either| match either {
13376                            Either::Left((message, ..)) => ready(message).left_future(),
13377                            Either::Right(..) => pending::<String>().right_future(),
13378                        }),
13379                    )
13380                    .await;
13381
13382                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13383                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13384                match response_result {
13385                    ConnectionResult::Timeout => {
13386                        log::error!("Timeout during workspace diagnostics pull");
13387                        continue 'request;
13388                    }
13389                    ConnectionResult::ConnectionReset => {
13390                        log::error!("Server closed a workspace diagnostics pull request");
13391                        continue 'request;
13392                    }
13393                    ConnectionResult::Result(Err(e)) => {
13394                        log::error!("Error during workspace diagnostics pull: {e:#}");
13395                        break 'request;
13396                    }
13397                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13398                        attempts = 0;
13399                        if lsp_store
13400                            .update(cx, |lsp_store, cx| {
13401                                lsp_store.apply_workspace_diagnostic_report(
13402                                    server.server_id(),
13403                                    pulled_diagnostics,
13404                                    registration_id_shared.clone(),
13405                                    cx,
13406                                )
13407                            })
13408                            .is_err()
13409                        {
13410                            return;
13411                        }
13412                        break 'request;
13413                    }
13414                }
13415            }
13416        }
13417    });
13418
13419    Some(WorkspaceRefreshTask {
13420        refresh_tx,
13421        progress_tx,
13422        task: workspace_query_language_server,
13423    })
13424}
13425
13426fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13427    match &options {
13428        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13429            diagnostic_options.identifier.clone()
13430        }
13431        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13432            let diagnostic_options = &registration_options.diagnostic_options;
13433            diagnostic_options.identifier.clone()
13434        }
13435    }
13436}
13437
13438fn workspace_diagnostic_identifier(
13439    options: &DiagnosticServerCapabilities,
13440) -> Option<Option<String>> {
13441    match &options {
13442        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13443            if !diagnostic_options.workspace_diagnostics {
13444                return None;
13445            }
13446            Some(diagnostic_options.identifier.clone())
13447        }
13448        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13449            let diagnostic_options = &registration_options.diagnostic_options;
13450            if !diagnostic_options.workspace_diagnostics {
13451                return None;
13452            }
13453            Some(diagnostic_options.identifier.clone())
13454        }
13455    }
13456}
13457
13458fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13459    let CompletionSource::BufferWord {
13460        word_range,
13461        resolved,
13462    } = &mut completion.source
13463    else {
13464        return;
13465    };
13466    if *resolved {
13467        return;
13468    }
13469
13470    if completion.new_text
13471        != snapshot
13472            .text_for_range(word_range.clone())
13473            .collect::<String>()
13474    {
13475        return;
13476    }
13477
13478    let mut offset = 0;
13479    for chunk in snapshot.chunks(word_range.clone(), true) {
13480        let end_offset = offset + chunk.text.len();
13481        if let Some(highlight_id) = chunk.syntax_highlight_id {
13482            completion
13483                .label
13484                .runs
13485                .push((offset..end_offset, highlight_id));
13486        }
13487        offset = end_offset;
13488    }
13489    *resolved = true;
13490}
13491
13492impl EventEmitter<LspStoreEvent> for LspStore {}
13493
13494fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13495    hover
13496        .contents
13497        .retain(|hover_block| !hover_block.text.trim().is_empty());
13498    if hover.contents.is_empty() {
13499        None
13500    } else {
13501        Some(hover)
13502    }
13503}
13504
13505async fn populate_labels_for_completions(
13506    new_completions: Vec<CoreCompletion>,
13507    language: Option<Arc<Language>>,
13508    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13509) -> Vec<Completion> {
13510    let lsp_completions = new_completions
13511        .iter()
13512        .filter_map(|new_completion| {
13513            new_completion
13514                .source
13515                .lsp_completion(true)
13516                .map(|lsp_completion| lsp_completion.into_owned())
13517        })
13518        .collect::<Vec<_>>();
13519
13520    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13521        lsp_adapter
13522            .labels_for_completions(&lsp_completions, language)
13523            .await
13524            .log_err()
13525            .unwrap_or_default()
13526    } else {
13527        Vec::new()
13528    }
13529    .into_iter()
13530    .fuse();
13531
13532    let mut completions = Vec::new();
13533    for completion in new_completions {
13534        match completion.source.lsp_completion(true) {
13535            Some(lsp_completion) => {
13536                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13537
13538                let mut label = labels.next().flatten().unwrap_or_else(|| {
13539                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13540                });
13541                ensure_uniform_list_compatible_label(&mut label);
13542                completions.push(Completion {
13543                    label,
13544                    documentation,
13545                    replace_range: completion.replace_range,
13546                    new_text: completion.new_text,
13547                    insert_text_mode: lsp_completion.insert_text_mode,
13548                    source: completion.source,
13549                    icon_path: None,
13550                    confirm: None,
13551                    match_start: None,
13552                    snippet_deduplication_key: None,
13553                });
13554            }
13555            None => {
13556                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13557                ensure_uniform_list_compatible_label(&mut label);
13558                completions.push(Completion {
13559                    label,
13560                    documentation: None,
13561                    replace_range: completion.replace_range,
13562                    new_text: completion.new_text,
13563                    source: completion.source,
13564                    insert_text_mode: None,
13565                    icon_path: None,
13566                    confirm: None,
13567                    match_start: None,
13568                    snippet_deduplication_key: None,
13569                });
13570            }
13571        }
13572    }
13573    completions
13574}
13575
13576#[derive(Debug)]
13577pub enum LanguageServerToQuery {
13578    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13579    FirstCapable,
13580    /// Query a specific language server.
13581    Other(LanguageServerId),
13582}
13583
13584#[derive(Default)]
13585struct RenamePathsWatchedForServer {
13586    did_rename: Vec<RenameActionPredicate>,
13587    will_rename: Vec<RenameActionPredicate>,
13588}
13589
13590impl RenamePathsWatchedForServer {
13591    fn with_did_rename_patterns(
13592        mut self,
13593        did_rename: Option<&FileOperationRegistrationOptions>,
13594    ) -> Self {
13595        if let Some(did_rename) = did_rename {
13596            self.did_rename = did_rename
13597                .filters
13598                .iter()
13599                .filter_map(|filter| filter.try_into().log_err())
13600                .collect();
13601        }
13602        self
13603    }
13604    fn with_will_rename_patterns(
13605        mut self,
13606        will_rename: Option<&FileOperationRegistrationOptions>,
13607    ) -> Self {
13608        if let Some(will_rename) = will_rename {
13609            self.will_rename = will_rename
13610                .filters
13611                .iter()
13612                .filter_map(|filter| filter.try_into().log_err())
13613                .collect();
13614        }
13615        self
13616    }
13617
13618    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13619        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13620    }
13621    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13622        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13623    }
13624}
13625
13626impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13627    type Error = globset::Error;
13628    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13629        Ok(Self {
13630            kind: ops.pattern.matches.clone(),
13631            glob: GlobBuilder::new(&ops.pattern.glob)
13632                .case_insensitive(
13633                    ops.pattern
13634                        .options
13635                        .as_ref()
13636                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13637                )
13638                .build()?
13639                .compile_matcher(),
13640        })
13641    }
13642}
13643struct RenameActionPredicate {
13644    glob: GlobMatcher,
13645    kind: Option<FileOperationPatternKind>,
13646}
13647
13648impl RenameActionPredicate {
13649    // Returns true if language server should be notified
13650    fn eval(&self, path: &str, is_dir: bool) -> bool {
13651        self.kind.as_ref().is_none_or(|kind| {
13652            let expected_kind = if is_dir {
13653                FileOperationPatternKind::Folder
13654            } else {
13655                FileOperationPatternKind::File
13656            };
13657            kind == &expected_kind
13658        }) && self.glob.is_match(path)
13659    }
13660}
13661
13662#[derive(Default)]
13663struct LanguageServerWatchedPaths {
13664    worktree_paths: HashMap<WorktreeId, GlobSet>,
13665    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13666}
13667
13668#[derive(Default)]
13669struct LanguageServerWatchedPathsBuilder {
13670    worktree_paths: HashMap<WorktreeId, GlobSet>,
13671    abs_paths: HashMap<Arc<Path>, GlobSet>,
13672}
13673
13674impl LanguageServerWatchedPathsBuilder {
13675    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13676        self.worktree_paths.insert(worktree_id, glob_set);
13677    }
13678    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13679        self.abs_paths.insert(path, glob_set);
13680    }
13681    fn build(
13682        self,
13683        fs: Arc<dyn Fs>,
13684        language_server_id: LanguageServerId,
13685        cx: &mut Context<LspStore>,
13686    ) -> LanguageServerWatchedPaths {
13687        let lsp_store = cx.weak_entity();
13688
13689        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13690        let abs_paths = self
13691            .abs_paths
13692            .into_iter()
13693            .map(|(abs_path, globset)| {
13694                let task = cx.spawn({
13695                    let abs_path = abs_path.clone();
13696                    let fs = fs.clone();
13697
13698                    let lsp_store = lsp_store.clone();
13699                    async move |_, cx| {
13700                        maybe!(async move {
13701                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13702                            while let Some(update) = push_updates.0.next().await {
13703                                let action = lsp_store
13704                                    .update(cx, |this, _| {
13705                                        let Some(local) = this.as_local() else {
13706                                            return ControlFlow::Break(());
13707                                        };
13708                                        let Some(watcher) = local
13709                                            .language_server_watched_paths
13710                                            .get(&language_server_id)
13711                                        else {
13712                                            return ControlFlow::Break(());
13713                                        };
13714                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13715                                            "Watched abs path is not registered with a watcher",
13716                                        );
13717                                        let matching_entries = update
13718                                            .into_iter()
13719                                            .filter(|event| globs.is_match(&event.path))
13720                                            .collect::<Vec<_>>();
13721                                        this.lsp_notify_abs_paths_changed(
13722                                            language_server_id,
13723                                            matching_entries,
13724                                        );
13725                                        ControlFlow::Continue(())
13726                                    })
13727                                    .ok()?;
13728
13729                                if action.is_break() {
13730                                    break;
13731                                }
13732                            }
13733                            Some(())
13734                        })
13735                        .await;
13736                    }
13737                });
13738                (abs_path, (globset, task))
13739            })
13740            .collect();
13741        LanguageServerWatchedPaths {
13742            worktree_paths: self.worktree_paths,
13743            abs_paths,
13744        }
13745    }
13746}
13747
13748struct LspBufferSnapshot {
13749    version: i32,
13750    snapshot: TextBufferSnapshot,
13751}
13752
13753/// A prompt requested by LSP server.
13754#[derive(Clone, Debug)]
13755pub struct LanguageServerPromptRequest {
13756    pub id: usize,
13757    pub level: PromptLevel,
13758    pub message: String,
13759    pub actions: Vec<MessageActionItem>,
13760    pub lsp_name: String,
13761    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13762}
13763
13764impl LanguageServerPromptRequest {
13765    pub fn new(
13766        level: PromptLevel,
13767        message: String,
13768        actions: Vec<MessageActionItem>,
13769        lsp_name: String,
13770        response_channel: smol::channel::Sender<MessageActionItem>,
13771    ) -> Self {
13772        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13773        LanguageServerPromptRequest {
13774            id,
13775            level,
13776            message,
13777            actions,
13778            lsp_name,
13779            response_channel,
13780        }
13781    }
13782    pub async fn respond(self, index: usize) -> Option<()> {
13783        if let Some(response) = self.actions.into_iter().nth(index) {
13784            self.response_channel.send(response).await.ok()
13785        } else {
13786            None
13787        }
13788    }
13789
13790    #[cfg(any(test, feature = "test-support"))]
13791    pub fn test(
13792        level: PromptLevel,
13793        message: String,
13794        actions: Vec<MessageActionItem>,
13795        lsp_name: String,
13796    ) -> Self {
13797        let (tx, _rx) = smol::channel::unbounded();
13798        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13799    }
13800}
13801impl PartialEq for LanguageServerPromptRequest {
13802    fn eq(&self, other: &Self) -> bool {
13803        self.message == other.message && self.actions == other.actions
13804    }
13805}
13806
13807#[derive(Clone, Debug, PartialEq)]
13808pub enum LanguageServerLogType {
13809    Log(MessageType),
13810    Trace { verbose_info: Option<String> },
13811    Rpc { received: bool },
13812}
13813
13814impl LanguageServerLogType {
13815    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13816        match self {
13817            Self::Log(log_type) => {
13818                use proto::log_message::LogLevel;
13819                let level = match *log_type {
13820                    MessageType::ERROR => LogLevel::Error,
13821                    MessageType::WARNING => LogLevel::Warning,
13822                    MessageType::INFO => LogLevel::Info,
13823                    MessageType::LOG => LogLevel::Log,
13824                    other => {
13825                        log::warn!("Unknown lsp log message type: {other:?}");
13826                        LogLevel::Log
13827                    }
13828                };
13829                proto::language_server_log::LogType::Log(proto::LogMessage {
13830                    level: level as i32,
13831                })
13832            }
13833            Self::Trace { verbose_info } => {
13834                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13835                    verbose_info: verbose_info.to_owned(),
13836                })
13837            }
13838            Self::Rpc { received } => {
13839                let kind = if *received {
13840                    proto::rpc_message::Kind::Received
13841                } else {
13842                    proto::rpc_message::Kind::Sent
13843                };
13844                let kind = kind as i32;
13845                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13846            }
13847        }
13848    }
13849
13850    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13851        use proto::log_message::LogLevel;
13852        use proto::rpc_message;
13853        match log_type {
13854            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13855                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13856                    LogLevel::Error => MessageType::ERROR,
13857                    LogLevel::Warning => MessageType::WARNING,
13858                    LogLevel::Info => MessageType::INFO,
13859                    LogLevel::Log => MessageType::LOG,
13860                },
13861            ),
13862            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13863                verbose_info: trace_message.verbose_info,
13864            },
13865            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13866                received: match rpc_message::Kind::from_i32(message.kind)
13867                    .unwrap_or(rpc_message::Kind::Received)
13868                {
13869                    rpc_message::Kind::Received => true,
13870                    rpc_message::Kind::Sent => false,
13871                },
13872            },
13873        }
13874    }
13875}
13876
13877pub struct WorkspaceRefreshTask {
13878    refresh_tx: mpsc::Sender<()>,
13879    progress_tx: mpsc::Sender<()>,
13880    #[allow(dead_code)]
13881    task: Task<()>,
13882}
13883
13884pub enum LanguageServerState {
13885    Starting {
13886        startup: Task<Option<Arc<LanguageServer>>>,
13887        /// List of language servers that will be added to the workspace once it's initialization completes.
13888        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13889    },
13890
13891    Running {
13892        adapter: Arc<CachedLspAdapter>,
13893        server: Arc<LanguageServer>,
13894        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13895        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13896    },
13897}
13898
13899impl LanguageServerState {
13900    fn add_workspace_folder(&self, uri: Uri) {
13901        match self {
13902            LanguageServerState::Starting {
13903                pending_workspace_folders,
13904                ..
13905            } => {
13906                pending_workspace_folders.lock().insert(uri);
13907            }
13908            LanguageServerState::Running { server, .. } => {
13909                server.add_workspace_folder(uri);
13910            }
13911        }
13912    }
13913    fn _remove_workspace_folder(&self, uri: Uri) {
13914        match self {
13915            LanguageServerState::Starting {
13916                pending_workspace_folders,
13917                ..
13918            } => {
13919                pending_workspace_folders.lock().remove(&uri);
13920            }
13921            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13922        }
13923    }
13924}
13925
13926impl std::fmt::Debug for LanguageServerState {
13927    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13928        match self {
13929            LanguageServerState::Starting { .. } => {
13930                f.debug_struct("LanguageServerState::Starting").finish()
13931            }
13932            LanguageServerState::Running { .. } => {
13933                f.debug_struct("LanguageServerState::Running").finish()
13934            }
13935        }
13936    }
13937}
13938
13939#[derive(Clone, Debug, Serialize)]
13940pub struct LanguageServerProgress {
13941    pub is_disk_based_diagnostics_progress: bool,
13942    pub is_cancellable: bool,
13943    pub title: Option<String>,
13944    pub message: Option<String>,
13945    pub percentage: Option<usize>,
13946    #[serde(skip_serializing)]
13947    pub last_update_at: Instant,
13948}
13949
13950#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13951pub struct DiagnosticSummary {
13952    pub error_count: usize,
13953    pub warning_count: usize,
13954}
13955
13956impl DiagnosticSummary {
13957    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13958        let mut this = Self {
13959            error_count: 0,
13960            warning_count: 0,
13961        };
13962
13963        for entry in diagnostics {
13964            if entry.diagnostic.is_primary {
13965                match entry.diagnostic.severity {
13966                    DiagnosticSeverity::ERROR => this.error_count += 1,
13967                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13968                    _ => {}
13969                }
13970            }
13971        }
13972
13973        this
13974    }
13975
13976    pub fn is_empty(&self) -> bool {
13977        self.error_count == 0 && self.warning_count == 0
13978    }
13979
13980    pub fn to_proto(
13981        self,
13982        language_server_id: LanguageServerId,
13983        path: &RelPath,
13984    ) -> proto::DiagnosticSummary {
13985        proto::DiagnosticSummary {
13986            path: path.to_proto(),
13987            language_server_id: language_server_id.0 as u64,
13988            error_count: self.error_count as u32,
13989            warning_count: self.warning_count as u32,
13990        }
13991    }
13992}
13993
13994#[derive(Clone, Debug)]
13995pub enum CompletionDocumentation {
13996    /// There is no documentation for this completion.
13997    Undocumented,
13998    /// A single line of documentation.
13999    SingleLine(SharedString),
14000    /// Multiple lines of plain text documentation.
14001    MultiLinePlainText(SharedString),
14002    /// Markdown documentation.
14003    MultiLineMarkdown(SharedString),
14004    /// Both single line and multiple lines of plain text documentation.
14005    SingleLineAndMultiLinePlainText {
14006        single_line: SharedString,
14007        plain_text: Option<SharedString>,
14008    },
14009}
14010
14011impl CompletionDocumentation {
14012    #[cfg(any(test, feature = "test-support"))]
14013    pub fn text(&self) -> SharedString {
14014        match self {
14015            CompletionDocumentation::Undocumented => "".into(),
14016            CompletionDocumentation::SingleLine(s) => s.clone(),
14017            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
14018            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
14019            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
14020                single_line.clone()
14021            }
14022        }
14023    }
14024}
14025
14026impl From<lsp::Documentation> for CompletionDocumentation {
14027    fn from(docs: lsp::Documentation) -> Self {
14028        match docs {
14029            lsp::Documentation::String(text) => {
14030                if text.lines().count() <= 1 {
14031                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
14032                } else {
14033                    CompletionDocumentation::MultiLinePlainText(text.into())
14034                }
14035            }
14036
14037            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
14038                lsp::MarkupKind::PlainText => {
14039                    if value.lines().count() <= 1 {
14040                        CompletionDocumentation::SingleLine(value.into())
14041                    } else {
14042                        CompletionDocumentation::MultiLinePlainText(value.into())
14043                    }
14044                }
14045
14046                lsp::MarkupKind::Markdown => {
14047                    CompletionDocumentation::MultiLineMarkdown(value.into())
14048                }
14049            },
14050        }
14051    }
14052}
14053
14054pub enum ResolvedHint {
14055    Resolved(InlayHint),
14056    Resolving(Shared<Task<()>>),
14057}
14058
14059fn glob_literal_prefix(glob: &Path) -> PathBuf {
14060    glob.components()
14061        .take_while(|component| match component {
14062            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
14063            _ => true,
14064        })
14065        .collect()
14066}
14067
14068pub struct SshLspAdapter {
14069    name: LanguageServerName,
14070    binary: LanguageServerBinary,
14071    initialization_options: Option<String>,
14072    code_action_kinds: Option<Vec<CodeActionKind>>,
14073}
14074
14075impl SshLspAdapter {
14076    pub fn new(
14077        name: LanguageServerName,
14078        binary: LanguageServerBinary,
14079        initialization_options: Option<String>,
14080        code_action_kinds: Option<String>,
14081    ) -> Self {
14082        Self {
14083            name,
14084            binary,
14085            initialization_options,
14086            code_action_kinds: code_action_kinds
14087                .as_ref()
14088                .and_then(|c| serde_json::from_str(c).ok()),
14089        }
14090    }
14091}
14092
14093impl LspInstaller for SshLspAdapter {
14094    type BinaryVersion = ();
14095    async fn check_if_user_installed(
14096        &self,
14097        _: &dyn LspAdapterDelegate,
14098        _: Option<Toolchain>,
14099        _: &AsyncApp,
14100    ) -> Option<LanguageServerBinary> {
14101        Some(self.binary.clone())
14102    }
14103
14104    async fn cached_server_binary(
14105        &self,
14106        _: PathBuf,
14107        _: &dyn LspAdapterDelegate,
14108    ) -> Option<LanguageServerBinary> {
14109        None
14110    }
14111
14112    async fn fetch_latest_server_version(
14113        &self,
14114        _: &dyn LspAdapterDelegate,
14115        _: bool,
14116        _: &mut AsyncApp,
14117    ) -> Result<()> {
14118        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14119    }
14120
14121    async fn fetch_server_binary(
14122        &self,
14123        _: (),
14124        _: PathBuf,
14125        _: &dyn LspAdapterDelegate,
14126    ) -> Result<LanguageServerBinary> {
14127        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14128    }
14129}
14130
14131#[async_trait(?Send)]
14132impl LspAdapter for SshLspAdapter {
14133    fn name(&self) -> LanguageServerName {
14134        self.name.clone()
14135    }
14136
14137    async fn initialization_options(
14138        self: Arc<Self>,
14139        _: &Arc<dyn LspAdapterDelegate>,
14140    ) -> Result<Option<serde_json::Value>> {
14141        let Some(options) = &self.initialization_options else {
14142            return Ok(None);
14143        };
14144        let result = serde_json::from_str(options)?;
14145        Ok(result)
14146    }
14147
14148    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14149        self.code_action_kinds.clone()
14150    }
14151}
14152
14153pub fn language_server_settings<'a>(
14154    delegate: &'a dyn LspAdapterDelegate,
14155    language: &LanguageServerName,
14156    cx: &'a App,
14157) -> Option<&'a LspSettings> {
14158    language_server_settings_for(
14159        SettingsLocation {
14160            worktree_id: delegate.worktree_id(),
14161            path: RelPath::empty(),
14162        },
14163        language,
14164        cx,
14165    )
14166}
14167
14168pub fn language_server_settings_for<'a>(
14169    location: SettingsLocation<'a>,
14170    language: &LanguageServerName,
14171    cx: &'a App,
14172) -> Option<&'a LspSettings> {
14173    ProjectSettings::get(Some(location), cx).lsp.get(language)
14174}
14175
14176pub struct LocalLspAdapterDelegate {
14177    lsp_store: WeakEntity<LspStore>,
14178    worktree: worktree::Snapshot,
14179    fs: Arc<dyn Fs>,
14180    http_client: Arc<dyn HttpClient>,
14181    language_registry: Arc<LanguageRegistry>,
14182    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14183}
14184
14185impl LocalLspAdapterDelegate {
14186    pub fn new(
14187        language_registry: Arc<LanguageRegistry>,
14188        environment: &Entity<ProjectEnvironment>,
14189        lsp_store: WeakEntity<LspStore>,
14190        worktree: &Entity<Worktree>,
14191        http_client: Arc<dyn HttpClient>,
14192        fs: Arc<dyn Fs>,
14193        cx: &mut App,
14194    ) -> Arc<Self> {
14195        let load_shell_env_task =
14196            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14197
14198        Arc::new(Self {
14199            lsp_store,
14200            worktree: worktree.read(cx).snapshot(),
14201            fs,
14202            http_client,
14203            language_registry,
14204            load_shell_env_task,
14205        })
14206    }
14207
14208    pub fn from_local_lsp(
14209        local: &LocalLspStore,
14210        worktree: &Entity<Worktree>,
14211        cx: &mut App,
14212    ) -> Arc<Self> {
14213        Self::new(
14214            local.languages.clone(),
14215            &local.environment,
14216            local.weak.clone(),
14217            worktree,
14218            local.http_client.clone(),
14219            local.fs.clone(),
14220            cx,
14221        )
14222    }
14223}
14224
14225#[async_trait]
14226impl LspAdapterDelegate for LocalLspAdapterDelegate {
14227    fn show_notification(&self, message: &str, cx: &mut App) {
14228        self.lsp_store
14229            .update(cx, |_, cx| {
14230                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14231            })
14232            .ok();
14233    }
14234
14235    fn http_client(&self) -> Arc<dyn HttpClient> {
14236        self.http_client.clone()
14237    }
14238
14239    fn worktree_id(&self) -> WorktreeId {
14240        self.worktree.id()
14241    }
14242
14243    fn worktree_root_path(&self) -> &Path {
14244        self.worktree.abs_path().as_ref()
14245    }
14246
14247    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
14248        self.worktree.resolve_executable_path(path)
14249    }
14250
14251    async fn shell_env(&self) -> HashMap<String, String> {
14252        let task = self.load_shell_env_task.clone();
14253        task.await.unwrap_or_default()
14254    }
14255
14256    async fn npm_package_installed_version(
14257        &self,
14258        package_name: &str,
14259    ) -> Result<Option<(PathBuf, Version)>> {
14260        let local_package_directory = self.worktree_root_path();
14261        let node_modules_directory = local_package_directory.join("node_modules");
14262
14263        if let Some(version) =
14264            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14265        {
14266            return Ok(Some((node_modules_directory, version)));
14267        }
14268        let Some(npm) = self.which("npm".as_ref()).await else {
14269            log::warn!(
14270                "Failed to find npm executable for {:?}",
14271                local_package_directory
14272            );
14273            return Ok(None);
14274        };
14275
14276        let env = self.shell_env().await;
14277        let output = util::command::new_smol_command(&npm)
14278            .args(["root", "-g"])
14279            .envs(env)
14280            .current_dir(local_package_directory)
14281            .output()
14282            .await?;
14283        let global_node_modules =
14284            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14285
14286        if let Some(version) =
14287            read_package_installed_version(global_node_modules.clone(), package_name).await?
14288        {
14289            return Ok(Some((global_node_modules, version)));
14290        }
14291        return Ok(None);
14292    }
14293
14294    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14295        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14296        if self.fs.is_file(&worktree_abs_path).await {
14297            worktree_abs_path.pop();
14298        }
14299
14300        let env = self.shell_env().await;
14301
14302        let shell_path = env.get("PATH").cloned();
14303
14304        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14305    }
14306
14307    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14308        let mut working_dir = self.worktree_root_path().to_path_buf();
14309        if self.fs.is_file(&working_dir).await {
14310            working_dir.pop();
14311        }
14312        let output = util::command::new_smol_command(&command.path)
14313            .args(command.arguments)
14314            .envs(command.env.clone().unwrap_or_default())
14315            .current_dir(working_dir)
14316            .output()
14317            .await?;
14318
14319        anyhow::ensure!(
14320            output.status.success(),
14321            "{}, stdout: {:?}, stderr: {:?}",
14322            output.status,
14323            String::from_utf8_lossy(&output.stdout),
14324            String::from_utf8_lossy(&output.stderr)
14325        );
14326        Ok(())
14327    }
14328
14329    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14330        self.language_registry
14331            .update_lsp_binary_status(server_name, status);
14332    }
14333
14334    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14335        self.language_registry
14336            .all_lsp_adapters()
14337            .into_iter()
14338            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14339            .collect()
14340    }
14341
14342    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14343        let dir = self.language_registry.language_server_download_dir(name)?;
14344
14345        if !dir.exists() {
14346            smol::fs::create_dir_all(&dir)
14347                .await
14348                .context("failed to create container directory")
14349                .log_err()?;
14350        }
14351
14352        Some(dir)
14353    }
14354
14355    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14356        let entry = self
14357            .worktree
14358            .entry_for_path(path)
14359            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14360        let abs_path = self.worktree.absolutize(&entry.path);
14361        self.fs.load(&abs_path).await
14362    }
14363}
14364
14365async fn populate_labels_for_symbols(
14366    symbols: Vec<CoreSymbol>,
14367    language_registry: &Arc<LanguageRegistry>,
14368    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14369    output: &mut Vec<Symbol>,
14370) {
14371    #[allow(clippy::mutable_key_type)]
14372    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14373
14374    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14375    for symbol in symbols {
14376        let Some(file_name) = symbol.path.file_name() else {
14377            continue;
14378        };
14379        let language = language_registry
14380            .load_language_for_file_path(Path::new(file_name))
14381            .await
14382            .ok()
14383            .or_else(|| {
14384                unknown_paths.insert(file_name.into());
14385                None
14386            });
14387        symbols_by_language
14388            .entry(language)
14389            .or_default()
14390            .push(symbol);
14391    }
14392
14393    for unknown_path in unknown_paths {
14394        log::info!("no language found for symbol in file {unknown_path:?}");
14395    }
14396
14397    let mut label_params = Vec::new();
14398    for (language, mut symbols) in symbols_by_language {
14399        label_params.clear();
14400        label_params.extend(
14401            symbols
14402                .iter_mut()
14403                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14404        );
14405
14406        let mut labels = Vec::new();
14407        if let Some(language) = language {
14408            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14409                language_registry
14410                    .lsp_adapters(&language.name())
14411                    .first()
14412                    .cloned()
14413            });
14414            if let Some(lsp_adapter) = lsp_adapter {
14415                labels = lsp_adapter
14416                    .labels_for_symbols(&label_params, &language)
14417                    .await
14418                    .log_err()
14419                    .unwrap_or_default();
14420            }
14421        }
14422
14423        for ((symbol, (name, _)), label) in symbols
14424            .into_iter()
14425            .zip(label_params.drain(..))
14426            .zip(labels.into_iter().chain(iter::repeat(None)))
14427        {
14428            output.push(Symbol {
14429                language_server_name: symbol.language_server_name,
14430                source_worktree_id: symbol.source_worktree_id,
14431                source_language_server_id: symbol.source_language_server_id,
14432                path: symbol.path,
14433                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14434                name,
14435                kind: symbol.kind,
14436                range: symbol.range,
14437            });
14438        }
14439    }
14440}
14441
14442fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14443    match server.capabilities().text_document_sync.as_ref()? {
14444        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14445            // Server wants didSave but didn't specify includeText.
14446            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14447            // Server doesn't want didSave at all.
14448            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14449            // Server provided SaveOptions.
14450            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14451                Some(save_options.include_text.unwrap_or(false))
14452            }
14453        },
14454        // We do not have any save info. Kind affects didChange only.
14455        lsp::TextDocumentSyncCapability::Kind(_) => None,
14456    }
14457}
14458
14459/// Completion items are displayed in a `UniformList`.
14460/// Usually, those items are single-line strings, but in LSP responses,
14461/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14462/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14463/// 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,
14464/// breaking the completions menu presentation.
14465///
14466/// 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.
14467fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14468    let mut new_text = String::with_capacity(label.text.len());
14469    let mut offset_map = vec![0; label.text.len() + 1];
14470    let mut last_char_was_space = false;
14471    let mut new_idx = 0;
14472    let chars = label.text.char_indices().fuse();
14473    let mut newlines_removed = false;
14474
14475    for (idx, c) in chars {
14476        offset_map[idx] = new_idx;
14477
14478        match c {
14479            '\n' if last_char_was_space => {
14480                newlines_removed = true;
14481            }
14482            '\t' | ' ' if last_char_was_space => {}
14483            '\n' if !last_char_was_space => {
14484                new_text.push(' ');
14485                new_idx += 1;
14486                last_char_was_space = true;
14487                newlines_removed = true;
14488            }
14489            ' ' | '\t' => {
14490                new_text.push(' ');
14491                new_idx += 1;
14492                last_char_was_space = true;
14493            }
14494            _ => {
14495                new_text.push(c);
14496                new_idx += c.len_utf8();
14497                last_char_was_space = false;
14498            }
14499        }
14500    }
14501    offset_map[label.text.len()] = new_idx;
14502
14503    // Only modify the label if newlines were removed.
14504    if !newlines_removed {
14505        return;
14506    }
14507
14508    let last_index = new_idx;
14509    let mut run_ranges_errors = Vec::new();
14510    label.runs.retain_mut(|(range, _)| {
14511        match offset_map.get(range.start) {
14512            Some(&start) => range.start = start,
14513            None => {
14514                run_ranges_errors.push(range.clone());
14515                return false;
14516            }
14517        }
14518
14519        match offset_map.get(range.end) {
14520            Some(&end) => range.end = end,
14521            None => {
14522                run_ranges_errors.push(range.clone());
14523                range.end = last_index;
14524            }
14525        }
14526        true
14527    });
14528    if !run_ranges_errors.is_empty() {
14529        log::error!(
14530            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14531            label.text
14532        );
14533    }
14534
14535    let mut wrong_filter_range = None;
14536    if label.filter_range == (0..label.text.len()) {
14537        label.filter_range = 0..new_text.len();
14538    } else {
14539        let mut original_filter_range = Some(label.filter_range.clone());
14540        match offset_map.get(label.filter_range.start) {
14541            Some(&start) => label.filter_range.start = start,
14542            None => {
14543                wrong_filter_range = original_filter_range.take();
14544                label.filter_range.start = last_index;
14545            }
14546        }
14547
14548        match offset_map.get(label.filter_range.end) {
14549            Some(&end) => label.filter_range.end = end,
14550            None => {
14551                wrong_filter_range = original_filter_range.take();
14552                label.filter_range.end = last_index;
14553            }
14554        }
14555    }
14556    if let Some(wrong_filter_range) = wrong_filter_range {
14557        log::error!(
14558            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14559            label.text
14560        );
14561    }
14562
14563    label.text = new_text;
14564}
14565
14566#[cfg(test)]
14567mod tests {
14568    use language::HighlightId;
14569
14570    use super::*;
14571
14572    #[test]
14573    fn test_glob_literal_prefix() {
14574        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14575        assert_eq!(
14576            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14577            Path::new("node_modules")
14578        );
14579        assert_eq!(
14580            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14581            Path::new("foo")
14582        );
14583        assert_eq!(
14584            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14585            Path::new("foo/bar/baz.js")
14586        );
14587
14588        #[cfg(target_os = "windows")]
14589        {
14590            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14591            assert_eq!(
14592                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14593                Path::new("node_modules")
14594            );
14595            assert_eq!(
14596                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14597                Path::new("foo")
14598            );
14599            assert_eq!(
14600                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14601                Path::new("foo/bar/baz.js")
14602            );
14603        }
14604    }
14605
14606    #[test]
14607    fn test_multi_len_chars_normalization() {
14608        let mut label = CodeLabel::new(
14609            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14610            0..6,
14611            vec![(0..6, HighlightId(1))],
14612        );
14613        ensure_uniform_list_compatible_label(&mut label);
14614        assert_eq!(
14615            label,
14616            CodeLabel::new(
14617                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14618                0..6,
14619                vec![(0..6, HighlightId(1))],
14620            )
14621        );
14622    }
14623
14624    #[test]
14625    fn test_trailing_newline_in_completion_documentation() {
14626        let doc = lsp::Documentation::String(
14627            "Inappropriate argument value (of correct type).\n".to_string(),
14628        );
14629        let completion_doc: CompletionDocumentation = doc.into();
14630        assert!(
14631            matches!(completion_doc, CompletionDocumentation::SingleLine(s) if s == "Inappropriate argument value (of correct type).")
14632        );
14633
14634        let doc = lsp::Documentation::String("  some value  \n".to_string());
14635        let completion_doc: CompletionDocumentation = doc.into();
14636        assert!(matches!(
14637            completion_doc,
14638            CompletionDocumentation::SingleLine(s) if s == "some value"
14639        ));
14640    }
14641}