lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13pub mod json_language_server_ext;
   14pub mod log_store;
   15pub mod lsp_ext_command;
   16pub mod rust_analyzer_ext;
   17pub mod vue_language_server_ext;
   18
   19mod inlay_hint_cache;
   20
   21use self::inlay_hint_cache::BufferInlayHints;
   22use crate::{
   23    CodeAction, ColorPresentation, Completion, CompletionDisplayOptions, CompletionResponse,
   24    CompletionSource, CoreCompletion, DocumentColor, Hover, InlayHint, InlayId, LocationLink,
   25    LspAction, LspPullDiagnostics, ManifestProvidersStore, Project, ProjectItem, ProjectPath,
   26    ProjectTransaction, PulledDiagnostics, ResolveState, Symbol,
   27    buffer_store::{BufferStore, BufferStoreEvent},
   28    environment::ProjectEnvironment,
   29    lsp_command::{self, *},
   30    lsp_store::{
   31        self,
   32        log_store::{GlobalLogStore, LanguageServerKind},
   33    },
   34    manifest_tree::{
   35        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   36        ManifestTree,
   37    },
   38    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   39    project_settings::{LspSettings, ProjectSettings},
   40    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   41    trusted_worktrees::{PathTrust, TrustedWorktrees, TrustedWorktreesEvent},
   42    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   43    yarn::YarnPathStore,
   44};
   45use anyhow::{Context as _, Result, anyhow};
   46use async_trait::async_trait;
   47use client::{TypedEnvelope, proto};
   48use clock::Global;
   49use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   50use futures::{
   51    AsyncWriteExt, Future, FutureExt, StreamExt,
   52    future::{Either, Shared, join_all, pending, select},
   53    select, select_biased,
   54    stream::FuturesUnordered,
   55};
   56use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   57use gpui::{
   58    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString,
   59    Subscription, Task, WeakEntity,
   60};
   61use http_client::HttpClient;
   62use itertools::Itertools as _;
   63use language::{
   64    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, Capability, CodeLabel,
   65    Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language,
   66    LanguageName, LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller,
   67    ManifestDelegate, ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16,
   68    Toolchain, Transaction, Unclipped,
   69    language_settings::{FormatOnSave, Formatter, LanguageSettings, language_settings},
   70    point_to_lsp,
   71    proto::{
   72        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   73        serialize_lsp_edit, serialize_version,
   74    },
   75    range_from_lsp, range_to_lsp,
   76    row_chunk::RowChunk,
   77};
   78use lsp::{
   79    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   80    DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   81    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   82    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LSP_REQUEST_TIMEOUT,
   83    LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId,
   84    LanguageServerName, LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType,
   85    OneOf, RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri,
   86    WillRenameFiles, WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   87};
   88use node_runtime::read_package_installed_version;
   89use parking_lot::Mutex;
   90use postage::{mpsc, sink::Sink, stream::Stream, watch};
   91use rand::prelude::*;
   92use rpc::{
   93    AnyProtoClient, ErrorCode, ErrorExt as _,
   94    proto::{LspRequestId, LspRequestMessage as _},
   95};
   96use semver::Version;
   97use serde::Serialize;
   98use serde_json::Value;
   99use settings::{Settings, SettingsLocation, SettingsStore};
  100use sha2::{Digest, Sha256};
  101use smol::channel::{Receiver, Sender};
  102use snippet::Snippet;
  103use std::{
  104    any::TypeId,
  105    borrow::Cow,
  106    cell::RefCell,
  107    cmp::{Ordering, Reverse},
  108    collections::hash_map,
  109    convert::TryInto,
  110    ffi::OsStr,
  111    future::ready,
  112    iter, mem,
  113    ops::{ControlFlow, Range},
  114    path::{self, Path, PathBuf},
  115    pin::pin,
  116    rc::Rc,
  117    sync::{
  118        Arc,
  119        atomic::{self, AtomicUsize},
  120    },
  121    time::{Duration, Instant},
  122    vec,
  123};
  124use sum_tree::Dimensions;
  125use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  126
  127use util::{
  128    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  129    paths::{PathStyle, SanitizedPath},
  130    post_inc,
  131    redact::redact_command,
  132    rel_path::RelPath,
  133};
  134
  135pub use fs::*;
  136pub use language::Location;
  137pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  138#[cfg(any(test, feature = "test-support"))]
  139pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  140pub use worktree::{
  141    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  142    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  143};
  144
  145const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  146pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  147const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  148const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  149
  150#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  151pub enum ProgressToken {
  152    Number(i32),
  153    String(SharedString),
  154}
  155
  156impl std::fmt::Display for ProgressToken {
  157    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  158        match self {
  159            Self::Number(number) => write!(f, "{number}"),
  160            Self::String(string) => write!(f, "{string}"),
  161        }
  162    }
  163}
  164
  165impl ProgressToken {
  166    fn from_lsp(value: lsp::NumberOrString) -> Self {
  167        match value {
  168            lsp::NumberOrString::Number(number) => Self::Number(number),
  169            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  170        }
  171    }
  172
  173    fn to_lsp(&self) -> lsp::NumberOrString {
  174        match self {
  175            Self::Number(number) => lsp::NumberOrString::Number(*number),
  176            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  177        }
  178    }
  179
  180    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  181        Some(match value.value? {
  182            proto::progress_token::Value::Number(number) => Self::Number(number),
  183            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  184        })
  185    }
  186
  187    fn to_proto(&self) -> proto::ProgressToken {
  188        proto::ProgressToken {
  189            value: Some(match self {
  190                Self::Number(number) => proto::progress_token::Value::Number(*number),
  191                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  192            }),
  193        }
  194    }
  195}
  196
  197#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  198pub enum FormatTrigger {
  199    Save,
  200    Manual,
  201}
  202
  203pub enum LspFormatTarget {
  204    Buffers,
  205    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  206}
  207
  208#[derive(Clone, PartialEq, Eq, Hash)]
  209pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  210
  211struct OpenLspBuffer(Entity<Buffer>);
  212
  213impl FormatTrigger {
  214    fn from_proto(value: i32) -> FormatTrigger {
  215        match value {
  216            0 => FormatTrigger::Save,
  217            1 => FormatTrigger::Manual,
  218            _ => FormatTrigger::Save,
  219        }
  220    }
  221}
  222
  223#[derive(Clone)]
  224struct UnifiedLanguageServer {
  225    id: LanguageServerId,
  226    project_roots: HashSet<Arc<RelPath>>,
  227}
  228
  229#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  230struct LanguageServerSeed {
  231    worktree_id: WorktreeId,
  232    name: LanguageServerName,
  233    toolchain: Option<Toolchain>,
  234    settings: Arc<LspSettings>,
  235}
  236
  237#[derive(Debug)]
  238pub struct DocumentDiagnosticsUpdate<'a, D> {
  239    pub diagnostics: D,
  240    pub result_id: Option<SharedString>,
  241    pub registration_id: Option<SharedString>,
  242    pub server_id: LanguageServerId,
  243    pub disk_based_sources: Cow<'a, [String]>,
  244}
  245
  246pub struct DocumentDiagnostics {
  247    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  248    document_abs_path: PathBuf,
  249    version: Option<i32>,
  250}
  251
  252#[derive(Default, Debug)]
  253struct DynamicRegistrations {
  254    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  255    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  256}
  257
  258pub struct LocalLspStore {
  259    weak: WeakEntity<LspStore>,
  260    pub worktree_store: Entity<WorktreeStore>,
  261    toolchain_store: Entity<LocalToolchainStore>,
  262    http_client: Arc<dyn HttpClient>,
  263    environment: Entity<ProjectEnvironment>,
  264    fs: Arc<dyn Fs>,
  265    languages: Arc<LanguageRegistry>,
  266    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  267    yarn: Entity<YarnPathStore>,
  268    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  269    buffers_being_formatted: HashSet<BufferId>,
  270    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  271    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  272    watched_manifest_filenames: HashSet<ManifestName>,
  273    language_server_paths_watched_for_rename:
  274        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  275    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  276    supplementary_language_servers:
  277        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  278    prettier_store: Entity<PrettierStore>,
  279    next_diagnostic_group_id: usize,
  280    diagnostics: HashMap<
  281        WorktreeId,
  282        HashMap<
  283            Arc<RelPath>,
  284            Vec<(
  285                LanguageServerId,
  286                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  287            )>,
  288        >,
  289    >,
  290    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  291    _subscription: gpui::Subscription,
  292    lsp_tree: LanguageServerTree,
  293    registered_buffers: HashMap<BufferId, usize>,
  294    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  295    buffer_pull_diagnostics_result_ids: HashMap<
  296        LanguageServerId,
  297        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  298    >,
  299    workspace_pull_diagnostics_result_ids: HashMap<
  300        LanguageServerId,
  301        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  302    >,
  303    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, Receiver<()>)>,
  304}
  305
  306impl LocalLspStore {
  307    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  308    pub fn running_language_server_for_id(
  309        &self,
  310        id: LanguageServerId,
  311    ) -> Option<&Arc<LanguageServer>> {
  312        let language_server_state = self.language_servers.get(&id)?;
  313
  314        match language_server_state {
  315            LanguageServerState::Running { server, .. } => Some(server),
  316            LanguageServerState::Starting { .. } => None,
  317        }
  318    }
  319
  320    fn get_or_insert_language_server(
  321        &mut self,
  322        worktree_handle: &Entity<Worktree>,
  323        delegate: Arc<LocalLspAdapterDelegate>,
  324        disposition: &Arc<LaunchDisposition>,
  325        language_name: &LanguageName,
  326        cx: &mut App,
  327    ) -> LanguageServerId {
  328        let key = LanguageServerSeed {
  329            worktree_id: worktree_handle.read(cx).id(),
  330            name: disposition.server_name.clone(),
  331            settings: disposition.settings.clone(),
  332            toolchain: disposition.toolchain.clone(),
  333        };
  334        if let Some(state) = self.language_server_ids.get_mut(&key) {
  335            state.project_roots.insert(disposition.path.path.clone());
  336            state.id
  337        } else {
  338            let adapter = self
  339                .languages
  340                .lsp_adapters(language_name)
  341                .into_iter()
  342                .find(|adapter| adapter.name() == disposition.server_name)
  343                .expect("To find LSP adapter");
  344            let new_language_server_id = self.start_language_server(
  345                worktree_handle,
  346                delegate,
  347                adapter,
  348                disposition.settings.clone(),
  349                key.clone(),
  350                cx,
  351            );
  352            if let Some(state) = self.language_server_ids.get_mut(&key) {
  353                state.project_roots.insert(disposition.path.path.clone());
  354            } else {
  355                debug_assert!(
  356                    false,
  357                    "Expected `start_language_server` to ensure that `key` exists in a map"
  358                );
  359            }
  360            new_language_server_id
  361        }
  362    }
  363
  364    fn start_language_server(
  365        &mut self,
  366        worktree_handle: &Entity<Worktree>,
  367        delegate: Arc<LocalLspAdapterDelegate>,
  368        adapter: Arc<CachedLspAdapter>,
  369        settings: Arc<LspSettings>,
  370        key: LanguageServerSeed,
  371        cx: &mut App,
  372    ) -> LanguageServerId {
  373        let worktree = worktree_handle.read(cx);
  374
  375        let worktree_id = worktree.id();
  376        let worktree_abs_path = worktree.abs_path();
  377        let toolchain = key.toolchain.clone();
  378        let override_options = settings.initialization_options.clone();
  379
  380        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  381
  382        let server_id = self.languages.next_language_server_id();
  383        log::trace!(
  384            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  385            adapter.name.0
  386        );
  387
  388        let untrusted_worktree_task =
  389            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  390                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  391                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  392                });
  393                if can_trust {
  394                    self.restricted_worktrees_tasks.remove(&worktree_id);
  395                    None
  396                } else {
  397                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  398                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  399                        hash_map::Entry::Vacant(v) => {
  400                            let (tx, rx) = smol::channel::bounded::<()>(1);
  401                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, _| {
  402                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  403                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  404                                        tx.send_blocking(()).ok();
  405                                    }
  406                                }
  407                            });
  408                            v.insert((subscription, rx.clone()));
  409                            Some(rx)
  410                        }
  411                    }
  412                }
  413            });
  414        let update_binary_status = untrusted_worktree_task.is_none();
  415
  416        let binary = self.get_language_server_binary(
  417            worktree_abs_path.clone(),
  418            adapter.clone(),
  419            settings,
  420            toolchain.clone(),
  421            delegate.clone(),
  422            true,
  423            untrusted_worktree_task,
  424            cx,
  425        );
  426        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  427
  428        let pending_server = cx.spawn({
  429            let adapter = adapter.clone();
  430            let server_name = adapter.name.clone();
  431            let stderr_capture = stderr_capture.clone();
  432            #[cfg(any(test, feature = "test-support"))]
  433            let lsp_store = self.weak.clone();
  434            let pending_workspace_folders = pending_workspace_folders.clone();
  435            async move |cx| {
  436                let binary = binary.await?;
  437                #[cfg(any(test, feature = "test-support"))]
  438                if let Some(server) = lsp_store
  439                    .update(&mut cx.clone(), |this, cx| {
  440                        this.languages.create_fake_language_server(
  441                            server_id,
  442                            &server_name,
  443                            binary.clone(),
  444                            &mut cx.to_async(),
  445                        )
  446                    })
  447                    .ok()
  448                    .flatten()
  449                {
  450                    return Ok(server);
  451                }
  452
  453                let code_action_kinds = adapter.code_action_kinds();
  454                lsp::LanguageServer::new(
  455                    stderr_capture,
  456                    server_id,
  457                    server_name,
  458                    binary,
  459                    &worktree_abs_path,
  460                    code_action_kinds,
  461                    Some(pending_workspace_folders),
  462                    cx,
  463                )
  464            }
  465        });
  466
  467        let startup = {
  468            let server_name = adapter.name.0.clone();
  469            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  470            let key = key.clone();
  471            let adapter = adapter.clone();
  472            let lsp_store = self.weak.clone();
  473            let pending_workspace_folders = pending_workspace_folders.clone();
  474
  475            let pull_diagnostics = ProjectSettings::get_global(cx)
  476                .diagnostics
  477                .lsp_pull_diagnostics
  478                .enabled;
  479            cx.spawn(async move |cx| {
  480                let result = async {
  481                    let language_server = pending_server.await?;
  482
  483                    let workspace_config = Self::workspace_configuration_for_adapter(
  484                        adapter.adapter.clone(),
  485                        &delegate,
  486                        toolchain,
  487                        None,
  488                        cx,
  489                    )
  490                    .await?;
  491
  492                    let mut initialization_options = Self::initialization_options_for_adapter(
  493                        adapter.adapter.clone(),
  494                        &delegate,
  495                    )
  496                    .await?;
  497
  498                    match (&mut initialization_options, override_options) {
  499                        (Some(initialization_options), Some(override_options)) => {
  500                            merge_json_value_into(override_options, initialization_options);
  501                        }
  502                        (None, override_options) => initialization_options = override_options,
  503                        _ => {}
  504                    }
  505
  506                    let initialization_params = cx.update(|cx| {
  507                        let mut params =
  508                            language_server.default_initialize_params(pull_diagnostics, cx);
  509                        params.initialization_options = initialization_options;
  510                        adapter.adapter.prepare_initialize_params(params, cx)
  511                    })??;
  512
  513                    Self::setup_lsp_messages(
  514                        lsp_store.clone(),
  515                        &language_server,
  516                        delegate.clone(),
  517                        adapter.clone(),
  518                    );
  519
  520                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  521                        settings: workspace_config,
  522                    };
  523                    let language_server = cx
  524                        .update(|cx| {
  525                            language_server.initialize(
  526                                initialization_params,
  527                                Arc::new(did_change_configuration_params.clone()),
  528                                cx,
  529                            )
  530                        })?
  531                        .await
  532                        .inspect_err(|_| {
  533                            if let Some(lsp_store) = lsp_store.upgrade() {
  534                                lsp_store
  535                                    .update(cx, |lsp_store, cx| {
  536                                        lsp_store.cleanup_lsp_data(server_id);
  537                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  538                                    })
  539                                    .ok();
  540                            }
  541                        })?;
  542
  543                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  544                        did_change_configuration_params,
  545                    )?;
  546
  547                    anyhow::Ok(language_server)
  548                }
  549                .await;
  550
  551                match result {
  552                    Ok(server) => {
  553                        lsp_store
  554                            .update(cx, |lsp_store, cx| {
  555                                lsp_store.insert_newly_running_language_server(
  556                                    adapter,
  557                                    server.clone(),
  558                                    server_id,
  559                                    key,
  560                                    pending_workspace_folders,
  561                                    cx,
  562                                );
  563                            })
  564                            .ok();
  565                        stderr_capture.lock().take();
  566                        Some(server)
  567                    }
  568
  569                    Err(err) => {
  570                        let log = stderr_capture.lock().take().unwrap_or_default();
  571                        delegate.update_status(
  572                            adapter.name(),
  573                            BinaryStatus::Failed {
  574                                error: if log.is_empty() {
  575                                    format!("{err:#}")
  576                                } else {
  577                                    format!("{err:#}\n-- stderr --\n{log}")
  578                                },
  579                            },
  580                        );
  581                        log::error!(
  582                            "Failed to start language server {server_name:?}: {}",
  583                            redact_command(&format!("{err:?}"))
  584                        );
  585                        if !log.is_empty() {
  586                            log::error!("server stderr: {}", redact_command(&log));
  587                        }
  588                        None
  589                    }
  590                }
  591            })
  592        };
  593        let state = LanguageServerState::Starting {
  594            startup,
  595            pending_workspace_folders,
  596        };
  597
  598        if update_binary_status {
  599            self.languages
  600                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  601        }
  602
  603        self.language_servers.insert(server_id, state);
  604        self.language_server_ids
  605            .entry(key)
  606            .or_insert(UnifiedLanguageServer {
  607                id: server_id,
  608                project_roots: Default::default(),
  609            });
  610        server_id
  611    }
  612
  613    fn get_language_server_binary(
  614        &self,
  615        worktree_abs_path: Arc<Path>,
  616        adapter: Arc<CachedLspAdapter>,
  617        settings: Arc<LspSettings>,
  618        toolchain: Option<Toolchain>,
  619        delegate: Arc<dyn LspAdapterDelegate>,
  620        allow_binary_download: bool,
  621        untrusted_worktree_task: Option<Receiver<()>>,
  622        cx: &mut App,
  623    ) -> Task<Result<LanguageServerBinary>> {
  624        if let Some(settings) = &settings.binary
  625            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  626        {
  627            let settings = settings.clone();
  628            let languages = self.languages.clone();
  629            return cx.background_spawn(async move {
  630                if let Some(untrusted_worktree_task) = untrusted_worktree_task {
  631                    log::info!(
  632                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  633                        adapter.name(),
  634                    );
  635                    untrusted_worktree_task.recv().await.ok();
  636                    log::info!(
  637                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  638                        adapter.name(),
  639                    );
  640                    languages
  641                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  642                }
  643                let mut env = delegate.shell_env().await;
  644                env.extend(settings.env.unwrap_or_default());
  645
  646                Ok(LanguageServerBinary {
  647                    path: delegate.resolve_executable_path(path),
  648                    env: Some(env),
  649                    arguments: settings
  650                        .arguments
  651                        .unwrap_or_default()
  652                        .iter()
  653                        .map(Into::into)
  654                        .collect(),
  655                })
  656            });
  657        }
  658        let lsp_binary_options = LanguageServerBinaryOptions {
  659            allow_path_lookup: !settings
  660                .binary
  661                .as_ref()
  662                .and_then(|b| b.ignore_system_version)
  663                .unwrap_or_default(),
  664            allow_binary_download,
  665            pre_release: settings
  666                .fetch
  667                .as_ref()
  668                .and_then(|f| f.pre_release)
  669                .unwrap_or(false),
  670        };
  671
  672        cx.spawn(async move |cx| {
  673            if let Some(untrusted_worktree_task) = untrusted_worktree_task {
  674                log::info!(
  675                    "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  676                    adapter.name(),
  677                );
  678                untrusted_worktree_task.recv().await.ok();
  679                log::info!(
  680                    "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  681                    adapter.name(),
  682                );
  683            }
  684
  685            let (existing_binary, maybe_download_binary) = adapter
  686                .clone()
  687                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  688                .await
  689                .await;
  690
  691            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  692
  693            let mut binary = match (existing_binary, maybe_download_binary) {
  694                (binary, None) => binary?,
  695                (Err(_), Some(downloader)) => downloader.await?,
  696                (Ok(existing_binary), Some(downloader)) => {
  697                    let mut download_timeout = cx
  698                        .background_executor()
  699                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  700                        .fuse();
  701                    let mut downloader = downloader.fuse();
  702                    futures::select! {
  703                        _ = download_timeout => {
  704                            // Return existing binary and kick the existing work to the background.
  705                            cx.spawn(async move |_| downloader.await).detach();
  706                            Ok(existing_binary)
  707                        },
  708                        downloaded_or_existing_binary = downloader => {
  709                            // If download fails, this results in the existing binary.
  710                            downloaded_or_existing_binary
  711                        }
  712                    }?
  713                }
  714            };
  715            let mut shell_env = delegate.shell_env().await;
  716
  717            shell_env.extend(binary.env.unwrap_or_default());
  718
  719            if let Some(settings) = settings.binary.as_ref() {
  720                if let Some(arguments) = &settings.arguments {
  721                    binary.arguments = arguments.iter().map(Into::into).collect();
  722                }
  723                if let Some(env) = &settings.env {
  724                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  725                }
  726            }
  727
  728            binary.env = Some(shell_env);
  729            Ok(binary)
  730        })
  731    }
  732
  733    fn setup_lsp_messages(
  734        lsp_store: WeakEntity<LspStore>,
  735        language_server: &LanguageServer,
  736        delegate: Arc<dyn LspAdapterDelegate>,
  737        adapter: Arc<CachedLspAdapter>,
  738    ) {
  739        let name = language_server.name();
  740        let server_id = language_server.server_id();
  741        language_server
  742            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  743                let adapter = adapter.clone();
  744                let this = lsp_store.clone();
  745                move |mut params, cx| {
  746                    let adapter = adapter.clone();
  747                    if let Some(this) = this.upgrade() {
  748                        this.update(cx, |this, cx| {
  749                            {
  750                                let buffer = params
  751                                    .uri
  752                                    .to_file_path()
  753                                    .map(|file_path| this.get_buffer(&file_path, cx))
  754                                    .ok()
  755                                    .flatten();
  756                                adapter.process_diagnostics(&mut params, server_id, buffer);
  757                            }
  758
  759                            this.merge_lsp_diagnostics(
  760                                DiagnosticSourceKind::Pushed,
  761                                vec![DocumentDiagnosticsUpdate {
  762                                    server_id,
  763                                    diagnostics: params,
  764                                    result_id: None,
  765                                    disk_based_sources: Cow::Borrowed(
  766                                        &adapter.disk_based_diagnostic_sources,
  767                                    ),
  768                                    registration_id: None,
  769                                }],
  770                                |_, diagnostic, cx| match diagnostic.source_kind {
  771                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  772                                        adapter.retain_old_diagnostic(diagnostic, cx)
  773                                    }
  774                                    DiagnosticSourceKind::Pulled => true,
  775                                },
  776                                cx,
  777                            )
  778                            .log_err();
  779                        })
  780                        .ok();
  781                    }
  782                }
  783            })
  784            .detach();
  785        language_server
  786            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  787                let adapter = adapter.adapter.clone();
  788                let delegate = delegate.clone();
  789                let this = lsp_store.clone();
  790                move |params, cx| {
  791                    let adapter = adapter.clone();
  792                    let delegate = delegate.clone();
  793                    let this = this.clone();
  794                    let mut cx = cx.clone();
  795                    async move {
  796                        let toolchain_for_id = this
  797                            .update(&mut cx, |this, _| {
  798                                this.as_local()?.language_server_ids.iter().find_map(
  799                                    |(seed, value)| {
  800                                        (value.id == server_id).then(|| seed.toolchain.clone())
  801                                    },
  802                                )
  803                            })?
  804                            .context("Expected the LSP store to be in a local mode")?;
  805
  806                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  807                        for item in &params.items {
  808                            let scope_uri = item.scope_uri.clone();
  809                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  810                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  811                            else {
  812                                // We've already queried workspace configuration of this URI.
  813                                continue;
  814                            };
  815                            let workspace_config = Self::workspace_configuration_for_adapter(
  816                                adapter.clone(),
  817                                &delegate,
  818                                toolchain_for_id.clone(),
  819                                scope_uri,
  820                                &mut cx,
  821                            )
  822                            .await?;
  823                            new_scope_uri.insert(workspace_config);
  824                        }
  825
  826                        Ok(params
  827                            .items
  828                            .into_iter()
  829                            .filter_map(|item| {
  830                                let workspace_config =
  831                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  832                                if let Some(section) = &item.section {
  833                                    Some(
  834                                        workspace_config
  835                                            .get(section)
  836                                            .cloned()
  837                                            .unwrap_or(serde_json::Value::Null),
  838                                    )
  839                                } else {
  840                                    Some(workspace_config.clone())
  841                                }
  842                            })
  843                            .collect())
  844                    }
  845                }
  846            })
  847            .detach();
  848
  849        language_server
  850            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  851                let this = lsp_store.clone();
  852                move |_, cx| {
  853                    let this = this.clone();
  854                    let cx = cx.clone();
  855                    async move {
  856                        let Some(server) =
  857                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  858                        else {
  859                            return Ok(None);
  860                        };
  861                        let root = server.workspace_folders();
  862                        Ok(Some(
  863                            root.into_iter()
  864                                .map(|uri| WorkspaceFolder {
  865                                    uri,
  866                                    name: Default::default(),
  867                                })
  868                                .collect(),
  869                        ))
  870                    }
  871                }
  872            })
  873            .detach();
  874        // Even though we don't have handling for these requests, respond to them to
  875        // avoid stalling any language server like `gopls` which waits for a response
  876        // to these requests when initializing.
  877        language_server
  878            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  879                let this = lsp_store.clone();
  880                move |params, cx| {
  881                    let this = this.clone();
  882                    let mut cx = cx.clone();
  883                    async move {
  884                        this.update(&mut cx, |this, _| {
  885                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  886                            {
  887                                status
  888                                    .progress_tokens
  889                                    .insert(ProgressToken::from_lsp(params.token));
  890                            }
  891                        })?;
  892
  893                        Ok(())
  894                    }
  895                }
  896            })
  897            .detach();
  898
  899        language_server
  900            .on_request::<lsp::request::RegisterCapability, _, _>({
  901                let lsp_store = lsp_store.clone();
  902                move |params, cx| {
  903                    let lsp_store = lsp_store.clone();
  904                    let mut cx = cx.clone();
  905                    async move {
  906                        lsp_store
  907                            .update(&mut cx, |lsp_store, cx| {
  908                                if lsp_store.as_local().is_some() {
  909                                    match lsp_store
  910                                        .register_server_capabilities(server_id, params, cx)
  911                                    {
  912                                        Ok(()) => {}
  913                                        Err(e) => {
  914                                            log::error!(
  915                                                "Failed to register server capabilities: {e:#}"
  916                                            );
  917                                        }
  918                                    };
  919                                }
  920                            })
  921                            .ok();
  922                        Ok(())
  923                    }
  924                }
  925            })
  926            .detach();
  927
  928        language_server
  929            .on_request::<lsp::request::UnregisterCapability, _, _>({
  930                let lsp_store = lsp_store.clone();
  931                move |params, cx| {
  932                    let lsp_store = lsp_store.clone();
  933                    let mut cx = cx.clone();
  934                    async move {
  935                        lsp_store
  936                            .update(&mut cx, |lsp_store, cx| {
  937                                if lsp_store.as_local().is_some() {
  938                                    match lsp_store
  939                                        .unregister_server_capabilities(server_id, params, cx)
  940                                    {
  941                                        Ok(()) => {}
  942                                        Err(e) => {
  943                                            log::error!(
  944                                                "Failed to unregister server capabilities: {e:#}"
  945                                            );
  946                                        }
  947                                    }
  948                                }
  949                            })
  950                            .ok();
  951                        Ok(())
  952                    }
  953                }
  954            })
  955            .detach();
  956
  957        language_server
  958            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  959                let this = lsp_store.clone();
  960                move |params, cx| {
  961                    let mut cx = cx.clone();
  962                    let this = this.clone();
  963                    async move {
  964                        LocalLspStore::on_lsp_workspace_edit(
  965                            this.clone(),
  966                            params,
  967                            server_id,
  968                            &mut cx,
  969                        )
  970                        .await
  971                    }
  972                }
  973            })
  974            .detach();
  975
  976        language_server
  977            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  978                let lsp_store = lsp_store.clone();
  979                let request_id = Arc::new(AtomicUsize::new(0));
  980                move |(), cx| {
  981                    let lsp_store = lsp_store.clone();
  982                    let request_id = request_id.clone();
  983                    let mut cx = cx.clone();
  984                    async move {
  985                        lsp_store
  986                            .update(&mut cx, |lsp_store, cx| {
  987                                let request_id =
  988                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
  989                                cx.emit(LspStoreEvent::RefreshInlayHints {
  990                                    server_id,
  991                                    request_id,
  992                                });
  993                                lsp_store
  994                                    .downstream_client
  995                                    .as_ref()
  996                                    .map(|(client, project_id)| {
  997                                        client.send(proto::RefreshInlayHints {
  998                                            project_id: *project_id,
  999                                            server_id: server_id.to_proto(),
 1000                                            request_id: request_id.map(|id| id as u64),
 1001                                        })
 1002                                    })
 1003                            })?
 1004                            .transpose()?;
 1005                        Ok(())
 1006                    }
 1007                }
 1008            })
 1009            .detach();
 1010
 1011        language_server
 1012            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1013                let this = lsp_store.clone();
 1014                move |(), cx| {
 1015                    let this = this.clone();
 1016                    let mut cx = cx.clone();
 1017                    async move {
 1018                        this.update(&mut cx, |this, cx| {
 1019                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1020                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1021                                client.send(proto::RefreshCodeLens {
 1022                                    project_id: *project_id,
 1023                                })
 1024                            })
 1025                        })?
 1026                        .transpose()?;
 1027                        Ok(())
 1028                    }
 1029                }
 1030            })
 1031            .detach();
 1032
 1033        language_server
 1034            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1035                let this = lsp_store.clone();
 1036                move |(), cx| {
 1037                    let this = this.clone();
 1038                    let mut cx = cx.clone();
 1039                    async move {
 1040                        this.update(&mut cx, |lsp_store, _| {
 1041                            lsp_store.pull_workspace_diagnostics(server_id);
 1042                            lsp_store
 1043                                .downstream_client
 1044                                .as_ref()
 1045                                .map(|(client, project_id)| {
 1046                                    client.send(proto::PullWorkspaceDiagnostics {
 1047                                        project_id: *project_id,
 1048                                        server_id: server_id.to_proto(),
 1049                                    })
 1050                                })
 1051                        })?
 1052                        .transpose()?;
 1053                        Ok(())
 1054                    }
 1055                }
 1056            })
 1057            .detach();
 1058
 1059        language_server
 1060            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1061                let this = lsp_store.clone();
 1062                let name = name.to_string();
 1063                let adapter = adapter.clone();
 1064                move |params, cx| {
 1065                    let this = this.clone();
 1066                    let name = name.to_string();
 1067                    let adapter = adapter.clone();
 1068                    let mut cx = cx.clone();
 1069                    async move {
 1070                        let actions = params.actions.unwrap_or_default();
 1071                        let message = params.message.clone();
 1072                        let (tx, rx) = smol::channel::bounded(1);
 1073                        let request = LanguageServerPromptRequest {
 1074                            level: match params.typ {
 1075                                lsp::MessageType::ERROR => PromptLevel::Critical,
 1076                                lsp::MessageType::WARNING => PromptLevel::Warning,
 1077                                _ => PromptLevel::Info,
 1078                            },
 1079                            message: params.message,
 1080                            actions,
 1081                            response_channel: tx,
 1082                            lsp_name: name.clone(),
 1083                        };
 1084
 1085                        let did_update = this
 1086                            .update(&mut cx, |_, cx| {
 1087                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1088                            })
 1089                            .is_ok();
 1090                        if did_update {
 1091                            let response = rx.recv().await.ok();
 1092                            if let Some(ref selected_action) = response {
 1093                                let context = language::PromptResponseContext {
 1094                                    message,
 1095                                    selected_action: selected_action.clone(),
 1096                                };
 1097                                adapter.process_prompt_response(&context, &mut cx)
 1098                            }
 1099
 1100                            Ok(response)
 1101                        } else {
 1102                            Ok(None)
 1103                        }
 1104                    }
 1105                }
 1106            })
 1107            .detach();
 1108        language_server
 1109            .on_notification::<lsp::notification::ShowMessage, _>({
 1110                let this = lsp_store.clone();
 1111                let name = name.to_string();
 1112                move |params, cx| {
 1113                    let this = this.clone();
 1114                    let name = name.to_string();
 1115                    let mut cx = cx.clone();
 1116
 1117                    let (tx, _) = smol::channel::bounded(1);
 1118                    let request = LanguageServerPromptRequest {
 1119                        level: match params.typ {
 1120                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1121                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1122                            _ => PromptLevel::Info,
 1123                        },
 1124                        message: params.message,
 1125                        actions: vec![],
 1126                        response_channel: tx,
 1127                        lsp_name: name,
 1128                    };
 1129
 1130                    let _ = this.update(&mut cx, |_, cx| {
 1131                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1132                    });
 1133                }
 1134            })
 1135            .detach();
 1136
 1137        let disk_based_diagnostics_progress_token =
 1138            adapter.disk_based_diagnostics_progress_token.clone();
 1139
 1140        language_server
 1141            .on_notification::<lsp::notification::Progress, _>({
 1142                let this = lsp_store.clone();
 1143                move |params, cx| {
 1144                    if let Some(this) = this.upgrade() {
 1145                        this.update(cx, |this, cx| {
 1146                            this.on_lsp_progress(
 1147                                params,
 1148                                server_id,
 1149                                disk_based_diagnostics_progress_token.clone(),
 1150                                cx,
 1151                            );
 1152                        })
 1153                        .ok();
 1154                    }
 1155                }
 1156            })
 1157            .detach();
 1158
 1159        language_server
 1160            .on_notification::<lsp::notification::LogMessage, _>({
 1161                let this = lsp_store.clone();
 1162                move |params, cx| {
 1163                    if let Some(this) = this.upgrade() {
 1164                        this.update(cx, |_, cx| {
 1165                            cx.emit(LspStoreEvent::LanguageServerLog(
 1166                                server_id,
 1167                                LanguageServerLogType::Log(params.typ),
 1168                                params.message,
 1169                            ));
 1170                        })
 1171                        .ok();
 1172                    }
 1173                }
 1174            })
 1175            .detach();
 1176
 1177        language_server
 1178            .on_notification::<lsp::notification::LogTrace, _>({
 1179                let this = lsp_store.clone();
 1180                move |params, cx| {
 1181                    let mut cx = cx.clone();
 1182                    if let Some(this) = this.upgrade() {
 1183                        this.update(&mut cx, |_, cx| {
 1184                            cx.emit(LspStoreEvent::LanguageServerLog(
 1185                                server_id,
 1186                                LanguageServerLogType::Trace {
 1187                                    verbose_info: params.verbose,
 1188                                },
 1189                                params.message,
 1190                            ));
 1191                        })
 1192                        .ok();
 1193                    }
 1194                }
 1195            })
 1196            .detach();
 1197
 1198        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1199        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1200        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1201        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1202    }
 1203
 1204    fn shutdown_language_servers_on_quit(
 1205        &mut self,
 1206        _: &mut Context<LspStore>,
 1207    ) -> impl Future<Output = ()> + use<> {
 1208        let shutdown_futures = self
 1209            .language_servers
 1210            .drain()
 1211            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1212            .collect::<Vec<_>>();
 1213
 1214        async move {
 1215            join_all(shutdown_futures).await;
 1216        }
 1217    }
 1218
 1219    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1220        match server_state {
 1221            LanguageServerState::Running { server, .. } => {
 1222                if let Some(shutdown) = server.shutdown() {
 1223                    shutdown.await;
 1224                }
 1225            }
 1226            LanguageServerState::Starting { startup, .. } => {
 1227                if let Some(server) = startup.await
 1228                    && let Some(shutdown) = server.shutdown()
 1229                {
 1230                    shutdown.await;
 1231                }
 1232            }
 1233        }
 1234        Ok(())
 1235    }
 1236
 1237    fn language_servers_for_worktree(
 1238        &self,
 1239        worktree_id: WorktreeId,
 1240    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1241        self.language_server_ids
 1242            .iter()
 1243            .filter_map(move |(seed, state)| {
 1244                if seed.worktree_id != worktree_id {
 1245                    return None;
 1246                }
 1247
 1248                if let Some(LanguageServerState::Running { server, .. }) =
 1249                    self.language_servers.get(&state.id)
 1250                {
 1251                    Some(server)
 1252                } else {
 1253                    None
 1254                }
 1255            })
 1256    }
 1257
 1258    fn language_server_ids_for_project_path(
 1259        &self,
 1260        project_path: ProjectPath,
 1261        language: &Language,
 1262        cx: &mut App,
 1263    ) -> Vec<LanguageServerId> {
 1264        let Some(worktree) = self
 1265            .worktree_store
 1266            .read(cx)
 1267            .worktree_for_id(project_path.worktree_id, cx)
 1268        else {
 1269            return Vec::new();
 1270        };
 1271        let delegate: Arc<dyn ManifestDelegate> =
 1272            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1273
 1274        self.lsp_tree
 1275            .get(
 1276                project_path,
 1277                language.name(),
 1278                language.manifest(),
 1279                &delegate,
 1280                cx,
 1281            )
 1282            .collect::<Vec<_>>()
 1283    }
 1284
 1285    fn language_server_ids_for_buffer(
 1286        &self,
 1287        buffer: &Buffer,
 1288        cx: &mut App,
 1289    ) -> Vec<LanguageServerId> {
 1290        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1291            let worktree_id = file.worktree_id(cx);
 1292
 1293            let path: Arc<RelPath> = file
 1294                .path()
 1295                .parent()
 1296                .map(Arc::from)
 1297                .unwrap_or_else(|| file.path().clone());
 1298            let worktree_path = ProjectPath { worktree_id, path };
 1299            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1300        } else {
 1301            Vec::new()
 1302        }
 1303    }
 1304
 1305    fn language_servers_for_buffer<'a>(
 1306        &'a self,
 1307        buffer: &'a Buffer,
 1308        cx: &'a mut App,
 1309    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1310        self.language_server_ids_for_buffer(buffer, cx)
 1311            .into_iter()
 1312            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1313                LanguageServerState::Running {
 1314                    adapter, server, ..
 1315                } => Some((adapter, server)),
 1316                _ => None,
 1317            })
 1318    }
 1319
 1320    async fn execute_code_action_kind_locally(
 1321        lsp_store: WeakEntity<LspStore>,
 1322        mut buffers: Vec<Entity<Buffer>>,
 1323        kind: CodeActionKind,
 1324        push_to_history: bool,
 1325        cx: &mut AsyncApp,
 1326    ) -> anyhow::Result<ProjectTransaction> {
 1327        // Do not allow multiple concurrent code actions requests for the
 1328        // same buffer.
 1329        lsp_store.update(cx, |this, cx| {
 1330            let this = this.as_local_mut().unwrap();
 1331            buffers.retain(|buffer| {
 1332                this.buffers_being_formatted
 1333                    .insert(buffer.read(cx).remote_id())
 1334            });
 1335        })?;
 1336        let _cleanup = defer({
 1337            let this = lsp_store.clone();
 1338            let mut cx = cx.clone();
 1339            let buffers = &buffers;
 1340            move || {
 1341                this.update(&mut cx, |this, cx| {
 1342                    let this = this.as_local_mut().unwrap();
 1343                    for buffer in buffers {
 1344                        this.buffers_being_formatted
 1345                            .remove(&buffer.read(cx).remote_id());
 1346                    }
 1347                })
 1348                .ok();
 1349            }
 1350        });
 1351        let mut project_transaction = ProjectTransaction::default();
 1352
 1353        for buffer in &buffers {
 1354            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1355                buffer.update(cx, |buffer, cx| {
 1356                    lsp_store
 1357                        .as_local()
 1358                        .unwrap()
 1359                        .language_servers_for_buffer(buffer, cx)
 1360                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1361                        .collect::<Vec<_>>()
 1362                })
 1363            })?;
 1364            for (_, language_server) in adapters_and_servers.iter() {
 1365                let actions = Self::get_server_code_actions_from_action_kinds(
 1366                    &lsp_store,
 1367                    language_server.server_id(),
 1368                    vec![kind.clone()],
 1369                    buffer,
 1370                    cx,
 1371                )
 1372                .await?;
 1373                Self::execute_code_actions_on_server(
 1374                    &lsp_store,
 1375                    language_server,
 1376                    actions,
 1377                    push_to_history,
 1378                    &mut project_transaction,
 1379                    cx,
 1380                )
 1381                .await?;
 1382            }
 1383        }
 1384        Ok(project_transaction)
 1385    }
 1386
 1387    async fn format_locally(
 1388        lsp_store: WeakEntity<LspStore>,
 1389        mut buffers: Vec<FormattableBuffer>,
 1390        push_to_history: bool,
 1391        trigger: FormatTrigger,
 1392        logger: zlog::Logger,
 1393        cx: &mut AsyncApp,
 1394    ) -> anyhow::Result<ProjectTransaction> {
 1395        // Do not allow multiple concurrent formatting requests for the
 1396        // same buffer.
 1397        lsp_store.update(cx, |this, cx| {
 1398            let this = this.as_local_mut().unwrap();
 1399            buffers.retain(|buffer| {
 1400                this.buffers_being_formatted
 1401                    .insert(buffer.handle.read(cx).remote_id())
 1402            });
 1403        })?;
 1404
 1405        let _cleanup = defer({
 1406            let this = lsp_store.clone();
 1407            let mut cx = cx.clone();
 1408            let buffers = &buffers;
 1409            move || {
 1410                this.update(&mut cx, |this, cx| {
 1411                    let this = this.as_local_mut().unwrap();
 1412                    for buffer in buffers {
 1413                        this.buffers_being_formatted
 1414                            .remove(&buffer.handle.read(cx).remote_id());
 1415                    }
 1416                })
 1417                .ok();
 1418            }
 1419        });
 1420
 1421        let mut project_transaction = ProjectTransaction::default();
 1422
 1423        for buffer in &buffers {
 1424            zlog::debug!(
 1425                logger =>
 1426                "formatting buffer '{:?}'",
 1427                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1428            );
 1429            // Create an empty transaction to hold all of the formatting edits.
 1430            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1431                // ensure no transactions created while formatting are
 1432                // grouped with the previous transaction in the history
 1433                // based on the transaction group interval
 1434                buffer.finalize_last_transaction();
 1435                buffer
 1436                    .start_transaction()
 1437                    .context("transaction already open")?;
 1438                buffer.end_transaction(cx);
 1439                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1440                buffer.finalize_last_transaction();
 1441                anyhow::Ok(transaction_id)
 1442            })??;
 1443
 1444            let result = Self::format_buffer_locally(
 1445                lsp_store.clone(),
 1446                buffer,
 1447                formatting_transaction_id,
 1448                trigger,
 1449                logger,
 1450                cx,
 1451            )
 1452            .await;
 1453
 1454            buffer.handle.update(cx, |buffer, cx| {
 1455                let Some(formatting_transaction) =
 1456                    buffer.get_transaction(formatting_transaction_id).cloned()
 1457                else {
 1458                    zlog::warn!(logger => "no formatting transaction");
 1459                    return;
 1460                };
 1461                if formatting_transaction.edit_ids.is_empty() {
 1462                    zlog::debug!(logger => "no changes made while formatting");
 1463                    buffer.forget_transaction(formatting_transaction_id);
 1464                    return;
 1465                }
 1466                if !push_to_history {
 1467                    zlog::trace!(logger => "forgetting format transaction");
 1468                    buffer.forget_transaction(formatting_transaction.id);
 1469                }
 1470                project_transaction
 1471                    .0
 1472                    .insert(cx.entity(), formatting_transaction);
 1473            })?;
 1474
 1475            result?;
 1476        }
 1477
 1478        Ok(project_transaction)
 1479    }
 1480
 1481    async fn format_buffer_locally(
 1482        lsp_store: WeakEntity<LspStore>,
 1483        buffer: &FormattableBuffer,
 1484        formatting_transaction_id: clock::Lamport,
 1485        trigger: FormatTrigger,
 1486        logger: zlog::Logger,
 1487        cx: &mut AsyncApp,
 1488    ) -> Result<()> {
 1489        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1490            buffer.handle.update(cx, |buffer, cx| {
 1491                let adapters_and_servers = lsp_store
 1492                    .as_local()
 1493                    .unwrap()
 1494                    .language_servers_for_buffer(buffer, cx)
 1495                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1496                    .collect::<Vec<_>>();
 1497                let settings =
 1498                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1499                        .into_owned();
 1500                (adapters_and_servers, settings)
 1501            })
 1502        })?;
 1503
 1504        /// Apply edits to the buffer that will become part of the formatting transaction.
 1505        /// Fails if the buffer has been edited since the start of that transaction.
 1506        fn extend_formatting_transaction(
 1507            buffer: &FormattableBuffer,
 1508            formatting_transaction_id: text::TransactionId,
 1509            cx: &mut AsyncApp,
 1510            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1511        ) -> anyhow::Result<()> {
 1512            buffer.handle.update(cx, |buffer, cx| {
 1513                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1514                if last_transaction_id != Some(formatting_transaction_id) {
 1515                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1516                }
 1517                buffer.start_transaction();
 1518                operation(buffer, cx);
 1519                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1520                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1521                }
 1522                Ok(())
 1523            })?
 1524        }
 1525
 1526        // handle whitespace formatting
 1527        if settings.remove_trailing_whitespace_on_save {
 1528            zlog::trace!(logger => "removing trailing whitespace");
 1529            let diff = buffer
 1530                .handle
 1531                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1532                .await;
 1533            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1534                buffer.apply_diff(diff, cx);
 1535            })?;
 1536        }
 1537
 1538        if settings.ensure_final_newline_on_save {
 1539            zlog::trace!(logger => "ensuring final newline");
 1540            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1541                buffer.ensure_final_newline(cx);
 1542            })?;
 1543        }
 1544
 1545        // Formatter for `code_actions_on_format` that runs before
 1546        // the rest of the formatters
 1547        let mut code_actions_on_format_formatters = None;
 1548        let should_run_code_actions_on_format = !matches!(
 1549            (trigger, &settings.format_on_save),
 1550            (FormatTrigger::Save, &FormatOnSave::Off)
 1551        );
 1552        if should_run_code_actions_on_format {
 1553            let have_code_actions_to_run_on_format = settings
 1554                .code_actions_on_format
 1555                .values()
 1556                .any(|enabled| *enabled);
 1557            if have_code_actions_to_run_on_format {
 1558                zlog::trace!(logger => "going to run code actions on format");
 1559                code_actions_on_format_formatters = Some(
 1560                    settings
 1561                        .code_actions_on_format
 1562                        .iter()
 1563                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1564                        .cloned()
 1565                        .map(Formatter::CodeAction)
 1566                        .collect::<Vec<_>>(),
 1567                );
 1568            }
 1569        }
 1570
 1571        let formatters = match (trigger, &settings.format_on_save) {
 1572            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1573            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1574                settings.formatter.as_ref()
 1575            }
 1576        };
 1577
 1578        let formatters = code_actions_on_format_formatters
 1579            .iter()
 1580            .flatten()
 1581            .chain(formatters);
 1582
 1583        for formatter in formatters {
 1584            let formatter = if formatter == &Formatter::Auto {
 1585                if settings.prettier.allowed {
 1586                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1587                    &Formatter::Prettier
 1588                } else {
 1589                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1590                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1591                }
 1592            } else {
 1593                formatter
 1594            };
 1595            match formatter {
 1596                Formatter::Auto => unreachable!("Auto resolved above"),
 1597                Formatter::Prettier => {
 1598                    let logger = zlog::scoped!(logger => "prettier");
 1599                    zlog::trace!(logger => "formatting");
 1600                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1601
 1602                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1603                        lsp_store.prettier_store().unwrap().downgrade()
 1604                    })?;
 1605                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1606                        .await
 1607                        .transpose()?;
 1608                    let Some(diff) = diff else {
 1609                        zlog::trace!(logger => "No changes");
 1610                        continue;
 1611                    };
 1612
 1613                    extend_formatting_transaction(
 1614                        buffer,
 1615                        formatting_transaction_id,
 1616                        cx,
 1617                        |buffer, cx| {
 1618                            buffer.apply_diff(diff, cx);
 1619                        },
 1620                    )?;
 1621                }
 1622                Formatter::External { command, arguments } => {
 1623                    let logger = zlog::scoped!(logger => "command");
 1624                    zlog::trace!(logger => "formatting");
 1625                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1626
 1627                    let diff = Self::format_via_external_command(
 1628                        buffer,
 1629                        command.as_ref(),
 1630                        arguments.as_deref(),
 1631                        cx,
 1632                    )
 1633                    .await
 1634                    .with_context(|| {
 1635                        format!("Failed to format buffer via external command: {}", command)
 1636                    })?;
 1637                    let Some(diff) = diff else {
 1638                        zlog::trace!(logger => "No changes");
 1639                        continue;
 1640                    };
 1641
 1642                    extend_formatting_transaction(
 1643                        buffer,
 1644                        formatting_transaction_id,
 1645                        cx,
 1646                        |buffer, cx| {
 1647                            buffer.apply_diff(diff, cx);
 1648                        },
 1649                    )?;
 1650                }
 1651                Formatter::LanguageServer(specifier) => {
 1652                    let logger = zlog::scoped!(logger => "language-server");
 1653                    zlog::trace!(logger => "formatting");
 1654                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1655
 1656                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1657                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1658                        continue;
 1659                    };
 1660
 1661                    let language_server = match specifier {
 1662                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1663                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1664                                if adapter.name.0.as_ref() == name {
 1665                                    Some(server.clone())
 1666                                } else {
 1667                                    None
 1668                                }
 1669                            })
 1670                        }
 1671                        settings::LanguageServerFormatterSpecifier::Current => {
 1672                            adapters_and_servers.first().map(|e| e.1.clone())
 1673                        }
 1674                    };
 1675
 1676                    let Some(language_server) = language_server else {
 1677                        log::debug!(
 1678                            "No language server found to format buffer '{:?}'. Skipping",
 1679                            buffer_path_abs.as_path().to_string_lossy()
 1680                        );
 1681                        continue;
 1682                    };
 1683
 1684                    zlog::trace!(
 1685                        logger =>
 1686                        "Formatting buffer '{:?}' using language server '{:?}'",
 1687                        buffer_path_abs.as_path().to_string_lossy(),
 1688                        language_server.name()
 1689                    );
 1690
 1691                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1692                        zlog::trace!(logger => "formatting ranges");
 1693                        Self::format_ranges_via_lsp(
 1694                            &lsp_store,
 1695                            &buffer.handle,
 1696                            ranges,
 1697                            buffer_path_abs,
 1698                            &language_server,
 1699                            &settings,
 1700                            cx,
 1701                        )
 1702                        .await
 1703                        .context("Failed to format ranges via language server")?
 1704                    } else {
 1705                        zlog::trace!(logger => "formatting full");
 1706                        Self::format_via_lsp(
 1707                            &lsp_store,
 1708                            &buffer.handle,
 1709                            buffer_path_abs,
 1710                            &language_server,
 1711                            &settings,
 1712                            cx,
 1713                        )
 1714                        .await
 1715                        .context("failed to format via language server")?
 1716                    };
 1717
 1718                    if edits.is_empty() {
 1719                        zlog::trace!(logger => "No changes");
 1720                        continue;
 1721                    }
 1722                    extend_formatting_transaction(
 1723                        buffer,
 1724                        formatting_transaction_id,
 1725                        cx,
 1726                        |buffer, cx| {
 1727                            buffer.edit(edits, None, cx);
 1728                        },
 1729                    )?;
 1730                }
 1731                Formatter::CodeAction(code_action_name) => {
 1732                    let logger = zlog::scoped!(logger => "code-actions");
 1733                    zlog::trace!(logger => "formatting");
 1734                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1735
 1736                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1737                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1738                        continue;
 1739                    };
 1740
 1741                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1742                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1743
 1744                    let mut actions_and_servers = Vec::new();
 1745
 1746                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1747                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1748                            &lsp_store,
 1749                            language_server.server_id(),
 1750                            vec![code_action_kind.clone()],
 1751                            &buffer.handle,
 1752                            cx,
 1753                        )
 1754                        .await
 1755                        .with_context(|| {
 1756                            format!(
 1757                                "Failed to resolve code action {:?} with language server {}",
 1758                                code_action_kind,
 1759                                language_server.name()
 1760                            )
 1761                        });
 1762                        let Ok(actions) = actions_result else {
 1763                            // note: it may be better to set result to the error and break formatters here
 1764                            // but for now we try to execute the actions that we can resolve and skip the rest
 1765                            zlog::error!(
 1766                                logger =>
 1767                                "Failed to resolve code action {:?} with language server {}",
 1768                                code_action_kind,
 1769                                language_server.name()
 1770                            );
 1771                            continue;
 1772                        };
 1773                        for action in actions {
 1774                            actions_and_servers.push((action, index));
 1775                        }
 1776                    }
 1777
 1778                    if actions_and_servers.is_empty() {
 1779                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1780                        continue;
 1781                    }
 1782
 1783                    'actions: for (mut action, server_index) in actions_and_servers {
 1784                        let server = &adapters_and_servers[server_index].1;
 1785
 1786                        let describe_code_action = |action: &CodeAction| {
 1787                            format!(
 1788                                "code action '{}' with title \"{}\" on server {}",
 1789                                action
 1790                                    .lsp_action
 1791                                    .action_kind()
 1792                                    .unwrap_or("unknown".into())
 1793                                    .as_str(),
 1794                                action.lsp_action.title(),
 1795                                server.name(),
 1796                            )
 1797                        };
 1798
 1799                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1800
 1801                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1802                            zlog::error!(
 1803                                logger =>
 1804                                "Failed to resolve {}. Error: {}",
 1805                                describe_code_action(&action),
 1806                                err
 1807                            );
 1808                            continue;
 1809                        }
 1810
 1811                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1812                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1813                            // but filters out and logs warnings for code actions that require unreasonably
 1814                            // difficult handling on our part, such as:
 1815                            // - applying edits that call commands
 1816                            //   which can result in arbitrary workspace edits being sent from the server that
 1817                            //   have no way of being tied back to the command that initiated them (i.e. we
 1818                            //   can't know which edits are part of the format request, or if the server is done sending
 1819                            //   actions in response to the command)
 1820                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1821                            //   as we then would need to handle such changes correctly in the local history as well
 1822                            //   as the remote history through the ProjectTransaction
 1823                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1824                            // Supporting these actions is not impossible, but not supported as of yet.
 1825                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1826                                zlog::trace!(
 1827                                    logger =>
 1828                                    "No changes for code action. Skipping {}",
 1829                                    describe_code_action(&action),
 1830                                );
 1831                                continue;
 1832                            }
 1833
 1834                            let mut operations = Vec::new();
 1835                            if let Some(document_changes) = edit.document_changes {
 1836                                match document_changes {
 1837                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1838                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1839                                    ),
 1840                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1841                                }
 1842                            } else if let Some(changes) = edit.changes {
 1843                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1844                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1845                                        text_document:
 1846                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1847                                                uri,
 1848                                                version: None,
 1849                                            },
 1850                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1851                                    })
 1852                                }));
 1853                            }
 1854
 1855                            let mut edits = Vec::with_capacity(operations.len());
 1856
 1857                            if operations.is_empty() {
 1858                                zlog::trace!(
 1859                                    logger =>
 1860                                    "No changes for code action. Skipping {}",
 1861                                    describe_code_action(&action),
 1862                                );
 1863                                continue;
 1864                            }
 1865                            for operation in operations {
 1866                                let op = match operation {
 1867                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1868                                    lsp::DocumentChangeOperation::Op(_) => {
 1869                                        zlog::warn!(
 1870                                            logger =>
 1871                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1872                                            describe_code_action(&action),
 1873                                        );
 1874                                        continue 'actions;
 1875                                    }
 1876                                };
 1877                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1878                                    zlog::warn!(
 1879                                        logger =>
 1880                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1881                                        &op.text_document.uri,
 1882                                        describe_code_action(&action),
 1883                                    );
 1884                                    continue 'actions;
 1885                                };
 1886                                if &file_path != buffer_path_abs {
 1887                                    zlog::warn!(
 1888                                        logger =>
 1889                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1890                                        file_path,
 1891                                        buffer_path_abs,
 1892                                        describe_code_action(&action),
 1893                                    );
 1894                                    continue 'actions;
 1895                                }
 1896
 1897                                let mut lsp_edits = Vec::new();
 1898                                for edit in op.edits {
 1899                                    match edit {
 1900                                        Edit::Plain(edit) => {
 1901                                            if !lsp_edits.contains(&edit) {
 1902                                                lsp_edits.push(edit);
 1903                                            }
 1904                                        }
 1905                                        Edit::Annotated(edit) => {
 1906                                            if !lsp_edits.contains(&edit.text_edit) {
 1907                                                lsp_edits.push(edit.text_edit);
 1908                                            }
 1909                                        }
 1910                                        Edit::Snippet(_) => {
 1911                                            zlog::warn!(
 1912                                                logger =>
 1913                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1914                                                describe_code_action(&action),
 1915                                            );
 1916                                            continue 'actions;
 1917                                        }
 1918                                    }
 1919                                }
 1920                                let edits_result = lsp_store
 1921                                    .update(cx, |lsp_store, cx| {
 1922                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1923                                            &buffer.handle,
 1924                                            lsp_edits,
 1925                                            server.server_id(),
 1926                                            op.text_document.version,
 1927                                            cx,
 1928                                        )
 1929                                    })?
 1930                                    .await;
 1931                                let Ok(resolved_edits) = edits_result else {
 1932                                    zlog::warn!(
 1933                                        logger =>
 1934                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1935                                        buffer_path_abs.as_path(),
 1936                                        describe_code_action(&action),
 1937                                    );
 1938                                    continue 'actions;
 1939                                };
 1940                                edits.extend(resolved_edits);
 1941                            }
 1942
 1943                            if edits.is_empty() {
 1944                                zlog::warn!(logger => "No edits resolved from LSP");
 1945                                continue;
 1946                            }
 1947
 1948                            extend_formatting_transaction(
 1949                                buffer,
 1950                                formatting_transaction_id,
 1951                                cx,
 1952                                |buffer, cx| {
 1953                                    zlog::info!(
 1954                                        "Applying edits {edits:?}. Content: {:?}",
 1955                                        buffer.text()
 1956                                    );
 1957                                    buffer.edit(edits, None, cx);
 1958                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1959                                },
 1960                            )?;
 1961                        }
 1962
 1963                        if let Some(command) = action.lsp_action.command() {
 1964                            zlog::warn!(
 1965                                logger =>
 1966                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1967                                &command.command,
 1968                            );
 1969
 1970                            // bail early if command is invalid
 1971                            let server_capabilities = server.capabilities();
 1972                            let available_commands = server_capabilities
 1973                                .execute_command_provider
 1974                                .as_ref()
 1975                                .map(|options| options.commands.as_slice())
 1976                                .unwrap_or_default();
 1977                            if !available_commands.contains(&command.command) {
 1978                                zlog::warn!(
 1979                                    logger =>
 1980                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1981                                    command.command,
 1982                                    server.name(),
 1983                                );
 1984                                continue;
 1985                            }
 1986
 1987                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1988                            extend_formatting_transaction(
 1989                                buffer,
 1990                                formatting_transaction_id,
 1991                                cx,
 1992                                |_, _| {},
 1993                            )?;
 1994                            zlog::info!(logger => "Executing command {}", &command.command);
 1995
 1996                            lsp_store.update(cx, |this, _| {
 1997                                this.as_local_mut()
 1998                                    .unwrap()
 1999                                    .last_workspace_edits_by_language_server
 2000                                    .remove(&server.server_id());
 2001                            })?;
 2002
 2003                            let execute_command_result = server
 2004                                .request::<lsp::request::ExecuteCommand>(
 2005                                    lsp::ExecuteCommandParams {
 2006                                        command: command.command.clone(),
 2007                                        arguments: command.arguments.clone().unwrap_or_default(),
 2008                                        ..Default::default()
 2009                                    },
 2010                                )
 2011                                .await
 2012                                .into_response();
 2013
 2014                            if execute_command_result.is_err() {
 2015                                zlog::error!(
 2016                                    logger =>
 2017                                    "Failed to execute command '{}' as part of {}",
 2018                                    &command.command,
 2019                                    describe_code_action(&action),
 2020                                );
 2021                                continue 'actions;
 2022                            }
 2023
 2024                            let mut project_transaction_command =
 2025                                lsp_store.update(cx, |this, _| {
 2026                                    this.as_local_mut()
 2027                                        .unwrap()
 2028                                        .last_workspace_edits_by_language_server
 2029                                        .remove(&server.server_id())
 2030                                        .unwrap_or_default()
 2031                                })?;
 2032
 2033                            if let Some(transaction) =
 2034                                project_transaction_command.0.remove(&buffer.handle)
 2035                            {
 2036                                zlog::trace!(
 2037                                    logger =>
 2038                                    "Successfully captured {} edits that resulted from command {}",
 2039                                    transaction.edit_ids.len(),
 2040                                    &command.command,
 2041                                );
 2042                                let transaction_id_project_transaction = transaction.id;
 2043                                buffer.handle.update(cx, |buffer, _| {
 2044                                    // it may have been removed from history if push_to_history was
 2045                                    // false in deserialize_workspace_edit. If so push it so we
 2046                                    // can merge it with the format transaction
 2047                                    // and pop the combined transaction off the history stack
 2048                                    // later if push_to_history is false
 2049                                    if buffer.get_transaction(transaction.id).is_none() {
 2050                                        buffer.push_transaction(transaction, Instant::now());
 2051                                    }
 2052                                    buffer.merge_transactions(
 2053                                        transaction_id_project_transaction,
 2054                                        formatting_transaction_id,
 2055                                    );
 2056                                })?;
 2057                            }
 2058
 2059                            if !project_transaction_command.0.is_empty() {
 2060                                let mut extra_buffers = String::new();
 2061                                for buffer in project_transaction_command.0.keys() {
 2062                                    buffer
 2063                                        .read_with(cx, |b, cx| {
 2064                                            if let Some(path) = b.project_path(cx) {
 2065                                                if !extra_buffers.is_empty() {
 2066                                                    extra_buffers.push_str(", ");
 2067                                                }
 2068                                                extra_buffers.push_str(path.path.as_unix_str());
 2069                                            }
 2070                                        })
 2071                                        .ok();
 2072                                }
 2073                                zlog::warn!(
 2074                                    logger =>
 2075                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2076                                    &command.command,
 2077                                    extra_buffers,
 2078                                );
 2079                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2080                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2081                                // add it so it's included, and merge it into the format transaction when its created later
 2082                            }
 2083                        }
 2084                    }
 2085                }
 2086            }
 2087        }
 2088
 2089        Ok(())
 2090    }
 2091
 2092    pub async fn format_ranges_via_lsp(
 2093        this: &WeakEntity<LspStore>,
 2094        buffer_handle: &Entity<Buffer>,
 2095        ranges: &[Range<Anchor>],
 2096        abs_path: &Path,
 2097        language_server: &Arc<LanguageServer>,
 2098        settings: &LanguageSettings,
 2099        cx: &mut AsyncApp,
 2100    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2101        let capabilities = &language_server.capabilities();
 2102        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2103        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2104            anyhow::bail!(
 2105                "{} language server does not support range formatting",
 2106                language_server.name()
 2107            );
 2108        }
 2109
 2110        let uri = file_path_to_lsp_url(abs_path)?;
 2111        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2112
 2113        let lsp_edits = {
 2114            let mut lsp_ranges = Vec::new();
 2115            this.update(cx, |_this, cx| {
 2116                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2117                // not have been sent to the language server. This seems like a fairly systemic
 2118                // issue, though, the resolution probably is not specific to formatting.
 2119                //
 2120                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2121                // LSP.
 2122                let snapshot = buffer_handle.read(cx).snapshot();
 2123                for range in ranges {
 2124                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2125                }
 2126                anyhow::Ok(())
 2127            })??;
 2128
 2129            let mut edits = None;
 2130            for range in lsp_ranges {
 2131                if let Some(mut edit) = language_server
 2132                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2133                        text_document: text_document.clone(),
 2134                        range,
 2135                        options: lsp_command::lsp_formatting_options(settings),
 2136                        work_done_progress_params: Default::default(),
 2137                    })
 2138                    .await
 2139                    .into_response()?
 2140                {
 2141                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2142                }
 2143            }
 2144            edits
 2145        };
 2146
 2147        if let Some(lsp_edits) = lsp_edits {
 2148            this.update(cx, |this, cx| {
 2149                this.as_local_mut().unwrap().edits_from_lsp(
 2150                    buffer_handle,
 2151                    lsp_edits,
 2152                    language_server.server_id(),
 2153                    None,
 2154                    cx,
 2155                )
 2156            })?
 2157            .await
 2158        } else {
 2159            Ok(Vec::with_capacity(0))
 2160        }
 2161    }
 2162
 2163    async fn format_via_lsp(
 2164        this: &WeakEntity<LspStore>,
 2165        buffer: &Entity<Buffer>,
 2166        abs_path: &Path,
 2167        language_server: &Arc<LanguageServer>,
 2168        settings: &LanguageSettings,
 2169        cx: &mut AsyncApp,
 2170    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2171        let logger = zlog::scoped!("lsp_format");
 2172        zlog::debug!(logger => "Formatting via LSP");
 2173
 2174        let uri = file_path_to_lsp_url(abs_path)?;
 2175        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2176        let capabilities = &language_server.capabilities();
 2177
 2178        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2179        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2180
 2181        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2182            let _timer = zlog::time!(logger => "format-full");
 2183            language_server
 2184                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2185                    text_document,
 2186                    options: lsp_command::lsp_formatting_options(settings),
 2187                    work_done_progress_params: Default::default(),
 2188                })
 2189                .await
 2190                .into_response()?
 2191        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2192            let _timer = zlog::time!(logger => "format-range");
 2193            let buffer_start = lsp::Position::new(0, 0);
 2194            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2195            language_server
 2196                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2197                    text_document: text_document.clone(),
 2198                    range: lsp::Range::new(buffer_start, buffer_end),
 2199                    options: lsp_command::lsp_formatting_options(settings),
 2200                    work_done_progress_params: Default::default(),
 2201                })
 2202                .await
 2203                .into_response()?
 2204        } else {
 2205            None
 2206        };
 2207
 2208        if let Some(lsp_edits) = lsp_edits {
 2209            this.update(cx, |this, cx| {
 2210                this.as_local_mut().unwrap().edits_from_lsp(
 2211                    buffer,
 2212                    lsp_edits,
 2213                    language_server.server_id(),
 2214                    None,
 2215                    cx,
 2216                )
 2217            })?
 2218            .await
 2219        } else {
 2220            Ok(Vec::with_capacity(0))
 2221        }
 2222    }
 2223
 2224    async fn format_via_external_command(
 2225        buffer: &FormattableBuffer,
 2226        command: &str,
 2227        arguments: Option<&[String]>,
 2228        cx: &mut AsyncApp,
 2229    ) -> Result<Option<Diff>> {
 2230        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2231            let file = File::from_dyn(buffer.file())?;
 2232            let worktree = file.worktree.read(cx);
 2233            let mut worktree_path = worktree.abs_path().to_path_buf();
 2234            if worktree.root_entry()?.is_file() {
 2235                worktree_path.pop();
 2236            }
 2237            Some(worktree_path)
 2238        })?;
 2239
 2240        let mut child = util::command::new_smol_command(command);
 2241
 2242        if let Some(buffer_env) = buffer.env.as_ref() {
 2243            child.envs(buffer_env);
 2244        }
 2245
 2246        if let Some(working_dir_path) = working_dir_path {
 2247            child.current_dir(working_dir_path);
 2248        }
 2249
 2250        if let Some(arguments) = arguments {
 2251            child.args(arguments.iter().map(|arg| {
 2252                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2253                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2254                } else {
 2255                    arg.replace("{buffer_path}", "Untitled")
 2256                }
 2257            }));
 2258        }
 2259
 2260        let mut child = child
 2261            .stdin(smol::process::Stdio::piped())
 2262            .stdout(smol::process::Stdio::piped())
 2263            .stderr(smol::process::Stdio::piped())
 2264            .spawn()?;
 2265
 2266        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2267        let text = buffer
 2268            .handle
 2269            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2270        for chunk in text.chunks() {
 2271            stdin.write_all(chunk.as_bytes()).await?;
 2272        }
 2273        stdin.flush().await?;
 2274
 2275        let output = child.output().await?;
 2276        anyhow::ensure!(
 2277            output.status.success(),
 2278            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2279            output.status.code(),
 2280            String::from_utf8_lossy(&output.stdout),
 2281            String::from_utf8_lossy(&output.stderr),
 2282        );
 2283
 2284        let stdout = String::from_utf8(output.stdout)?;
 2285        Ok(Some(
 2286            buffer
 2287                .handle
 2288                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2289                .await,
 2290        ))
 2291    }
 2292
 2293    async fn try_resolve_code_action(
 2294        lang_server: &LanguageServer,
 2295        action: &mut CodeAction,
 2296    ) -> anyhow::Result<()> {
 2297        match &mut action.lsp_action {
 2298            LspAction::Action(lsp_action) => {
 2299                if !action.resolved
 2300                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2301                    && lsp_action.data.is_some()
 2302                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2303                {
 2304                    **lsp_action = lang_server
 2305                        .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2306                        .await
 2307                        .into_response()?;
 2308                }
 2309            }
 2310            LspAction::CodeLens(lens) => {
 2311                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2312                    *lens = lang_server
 2313                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2314                        .await
 2315                        .into_response()?;
 2316                }
 2317            }
 2318            LspAction::Command(_) => {}
 2319        }
 2320
 2321        action.resolved = true;
 2322        anyhow::Ok(())
 2323    }
 2324
 2325    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2326        let buffer = buffer_handle.read(cx);
 2327
 2328        let file = buffer.file().cloned();
 2329
 2330        let Some(file) = File::from_dyn(file.as_ref()) else {
 2331            return;
 2332        };
 2333        if !file.is_local() {
 2334            return;
 2335        }
 2336        let path = ProjectPath::from_file(file, cx);
 2337        let worktree_id = file.worktree_id(cx);
 2338        let language = buffer.language().cloned();
 2339
 2340        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2341            for (server_id, diagnostics) in
 2342                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2343            {
 2344                self.update_buffer_diagnostics(
 2345                    buffer_handle,
 2346                    server_id,
 2347                    None,
 2348                    None,
 2349                    None,
 2350                    Vec::new(),
 2351                    diagnostics,
 2352                    cx,
 2353                )
 2354                .log_err();
 2355            }
 2356        }
 2357        let Some(language) = language else {
 2358            return;
 2359        };
 2360        let Some(snapshot) = self
 2361            .worktree_store
 2362            .read(cx)
 2363            .worktree_for_id(worktree_id, cx)
 2364            .map(|worktree| worktree.read(cx).snapshot())
 2365        else {
 2366            return;
 2367        };
 2368        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2369
 2370        for server_id in
 2371            self.lsp_tree
 2372                .get(path, language.name(), language.manifest(), &delegate, cx)
 2373        {
 2374            let server = self
 2375                .language_servers
 2376                .get(&server_id)
 2377                .and_then(|server_state| {
 2378                    if let LanguageServerState::Running { server, .. } = server_state {
 2379                        Some(server.clone())
 2380                    } else {
 2381                        None
 2382                    }
 2383                });
 2384            let server = match server {
 2385                Some(server) => server,
 2386                None => continue,
 2387            };
 2388
 2389            buffer_handle.update(cx, |buffer, cx| {
 2390                buffer.set_completion_triggers(
 2391                    server.server_id(),
 2392                    server
 2393                        .capabilities()
 2394                        .completion_provider
 2395                        .as_ref()
 2396                        .and_then(|provider| {
 2397                            provider
 2398                                .trigger_characters
 2399                                .as_ref()
 2400                                .map(|characters| characters.iter().cloned().collect())
 2401                        })
 2402                        .unwrap_or_default(),
 2403                    cx,
 2404                );
 2405            });
 2406        }
 2407    }
 2408
 2409    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2410        buffer.update(cx, |buffer, cx| {
 2411            let Some(language) = buffer.language() else {
 2412                return;
 2413            };
 2414            let path = ProjectPath {
 2415                worktree_id: old_file.worktree_id(cx),
 2416                path: old_file.path.clone(),
 2417            };
 2418            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2419                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2420                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2421            }
 2422        });
 2423    }
 2424
 2425    fn update_buffer_diagnostics(
 2426        &mut self,
 2427        buffer: &Entity<Buffer>,
 2428        server_id: LanguageServerId,
 2429        registration_id: Option<Option<SharedString>>,
 2430        result_id: Option<SharedString>,
 2431        version: Option<i32>,
 2432        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2433        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2434        cx: &mut Context<LspStore>,
 2435    ) -> Result<()> {
 2436        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2437            Ordering::Equal
 2438                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2439                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2440                .then_with(|| a.severity.cmp(&b.severity))
 2441                .then_with(|| a.message.cmp(&b.message))
 2442        }
 2443
 2444        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2445        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2446        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2447
 2448        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2449            Ordering::Equal
 2450                .then_with(|| a.range.start.cmp(&b.range.start))
 2451                .then_with(|| b.range.end.cmp(&a.range.end))
 2452                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2453        });
 2454
 2455        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2456
 2457        let edits_since_save = std::cell::LazyCell::new(|| {
 2458            let saved_version = buffer.read(cx).saved_version();
 2459            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2460        });
 2461
 2462        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2463
 2464        for (new_diagnostic, entry) in diagnostics {
 2465            let start;
 2466            let end;
 2467            if new_diagnostic && entry.diagnostic.is_disk_based {
 2468                // Some diagnostics are based on files on disk instead of buffers'
 2469                // current contents. Adjust these diagnostics' ranges to reflect
 2470                // any unsaved edits.
 2471                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2472                // and were properly adjusted on reuse.
 2473                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2474                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2475            } else {
 2476                start = entry.range.start;
 2477                end = entry.range.end;
 2478            }
 2479
 2480            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2481                ..snapshot.clip_point_utf16(end, Bias::Right);
 2482
 2483            // Expand empty ranges by one codepoint
 2484            if range.start == range.end {
 2485                // This will be go to the next boundary when being clipped
 2486                range.end.column += 1;
 2487                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2488                if range.start == range.end && range.end.column > 0 {
 2489                    range.start.column -= 1;
 2490                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2491                }
 2492            }
 2493
 2494            sanitized_diagnostics.push(DiagnosticEntry {
 2495                range,
 2496                diagnostic: entry.diagnostic,
 2497            });
 2498        }
 2499        drop(edits_since_save);
 2500
 2501        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2502        buffer.update(cx, |buffer, cx| {
 2503            if let Some(registration_id) = registration_id {
 2504                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2505                    self.buffer_pull_diagnostics_result_ids
 2506                        .entry(server_id)
 2507                        .or_default()
 2508                        .entry(registration_id)
 2509                        .or_default()
 2510                        .insert(abs_path, result_id);
 2511                }
 2512            }
 2513
 2514            buffer.update_diagnostics(server_id, set, cx)
 2515        });
 2516
 2517        Ok(())
 2518    }
 2519
 2520    fn register_language_server_for_invisible_worktree(
 2521        &mut self,
 2522        worktree: &Entity<Worktree>,
 2523        language_server_id: LanguageServerId,
 2524        cx: &mut App,
 2525    ) {
 2526        let worktree = worktree.read(cx);
 2527        let worktree_id = worktree.id();
 2528        debug_assert!(!worktree.is_visible());
 2529        let Some(mut origin_seed) = self
 2530            .language_server_ids
 2531            .iter()
 2532            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2533        else {
 2534            return;
 2535        };
 2536        origin_seed.worktree_id = worktree_id;
 2537        self.language_server_ids
 2538            .entry(origin_seed)
 2539            .or_insert_with(|| UnifiedLanguageServer {
 2540                id: language_server_id,
 2541                project_roots: Default::default(),
 2542            });
 2543    }
 2544
 2545    fn register_buffer_with_language_servers(
 2546        &mut self,
 2547        buffer_handle: &Entity<Buffer>,
 2548        only_register_servers: HashSet<LanguageServerSelector>,
 2549        cx: &mut Context<LspStore>,
 2550    ) {
 2551        let buffer = buffer_handle.read(cx);
 2552        let buffer_id = buffer.remote_id();
 2553
 2554        let Some(file) = File::from_dyn(buffer.file()) else {
 2555            return;
 2556        };
 2557        if !file.is_local() {
 2558            return;
 2559        }
 2560
 2561        let abs_path = file.abs_path(cx);
 2562        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2563            return;
 2564        };
 2565        let initial_snapshot = buffer.text_snapshot();
 2566        let worktree_id = file.worktree_id(cx);
 2567
 2568        let Some(language) = buffer.language().cloned() else {
 2569            return;
 2570        };
 2571        let path: Arc<RelPath> = file
 2572            .path()
 2573            .parent()
 2574            .map(Arc::from)
 2575            .unwrap_or_else(|| file.path().clone());
 2576        let Some(worktree) = self
 2577            .worktree_store
 2578            .read(cx)
 2579            .worktree_for_id(worktree_id, cx)
 2580        else {
 2581            return;
 2582        };
 2583        let language_name = language.name();
 2584        let (reused, delegate, servers) = self
 2585            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2586            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2587            .unwrap_or_else(|| {
 2588                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2589                let delegate: Arc<dyn ManifestDelegate> =
 2590                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2591
 2592                let servers = self
 2593                    .lsp_tree
 2594                    .walk(
 2595                        ProjectPath { worktree_id, path },
 2596                        language.name(),
 2597                        language.manifest(),
 2598                        &delegate,
 2599                        cx,
 2600                    )
 2601                    .collect::<Vec<_>>();
 2602                (false, lsp_delegate, servers)
 2603            });
 2604        let servers_and_adapters = servers
 2605            .into_iter()
 2606            .filter_map(|server_node| {
 2607                if reused && server_node.server_id().is_none() {
 2608                    return None;
 2609                }
 2610                if !only_register_servers.is_empty() {
 2611                    if let Some(server_id) = server_node.server_id()
 2612                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2613                    {
 2614                        return None;
 2615                    }
 2616                    if let Some(name) = server_node.name()
 2617                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2618                    {
 2619                        return None;
 2620                    }
 2621                }
 2622
 2623                let server_id = server_node.server_id_or_init(|disposition| {
 2624                    let path = &disposition.path;
 2625
 2626                    {
 2627                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2628
 2629                        let server_id = self.get_or_insert_language_server(
 2630                            &worktree,
 2631                            delegate.clone(),
 2632                            disposition,
 2633                            &language_name,
 2634                            cx,
 2635                        );
 2636
 2637                        if let Some(state) = self.language_servers.get(&server_id)
 2638                            && let Ok(uri) = uri
 2639                        {
 2640                            state.add_workspace_folder(uri);
 2641                        };
 2642                        server_id
 2643                    }
 2644                })?;
 2645                let server_state = self.language_servers.get(&server_id)?;
 2646                if let LanguageServerState::Running {
 2647                    server, adapter, ..
 2648                } = server_state
 2649                {
 2650                    Some((server.clone(), adapter.clone()))
 2651                } else {
 2652                    None
 2653                }
 2654            })
 2655            .collect::<Vec<_>>();
 2656        for (server, adapter) in servers_and_adapters {
 2657            buffer_handle.update(cx, |buffer, cx| {
 2658                buffer.set_completion_triggers(
 2659                    server.server_id(),
 2660                    server
 2661                        .capabilities()
 2662                        .completion_provider
 2663                        .as_ref()
 2664                        .and_then(|provider| {
 2665                            provider
 2666                                .trigger_characters
 2667                                .as_ref()
 2668                                .map(|characters| characters.iter().cloned().collect())
 2669                        })
 2670                        .unwrap_or_default(),
 2671                    cx,
 2672                );
 2673            });
 2674
 2675            let snapshot = LspBufferSnapshot {
 2676                version: 0,
 2677                snapshot: initial_snapshot.clone(),
 2678            };
 2679
 2680            let mut registered = false;
 2681            self.buffer_snapshots
 2682                .entry(buffer_id)
 2683                .or_default()
 2684                .entry(server.server_id())
 2685                .or_insert_with(|| {
 2686                    registered = true;
 2687                    server.register_buffer(
 2688                        uri.clone(),
 2689                        adapter.language_id(&language.name()),
 2690                        0,
 2691                        initial_snapshot.text(),
 2692                    );
 2693
 2694                    vec![snapshot]
 2695                });
 2696
 2697            self.buffers_opened_in_servers
 2698                .entry(buffer_id)
 2699                .or_default()
 2700                .insert(server.server_id());
 2701            if registered {
 2702                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2703                    language_server_id: server.server_id(),
 2704                    name: None,
 2705                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2706                        proto::RegisteredForBuffer {
 2707                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2708                            buffer_id: buffer_id.to_proto(),
 2709                        },
 2710                    ),
 2711                });
 2712            }
 2713        }
 2714    }
 2715
 2716    fn reuse_existing_language_server<'lang_name>(
 2717        &self,
 2718        server_tree: &LanguageServerTree,
 2719        worktree: &Entity<Worktree>,
 2720        language_name: &'lang_name LanguageName,
 2721        cx: &mut App,
 2722    ) -> Option<(
 2723        Arc<LocalLspAdapterDelegate>,
 2724        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2725    )> {
 2726        if worktree.read(cx).is_visible() {
 2727            return None;
 2728        }
 2729
 2730        let worktree_store = self.worktree_store.read(cx);
 2731        let servers = server_tree
 2732            .instances
 2733            .iter()
 2734            .filter(|(worktree_id, _)| {
 2735                worktree_store
 2736                    .worktree_for_id(**worktree_id, cx)
 2737                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2738            })
 2739            .flat_map(|(worktree_id, servers)| {
 2740                servers
 2741                    .roots
 2742                    .iter()
 2743                    .flat_map(|(_, language_servers)| language_servers)
 2744                    .map(move |(_, (server_node, server_languages))| {
 2745                        (worktree_id, server_node, server_languages)
 2746                    })
 2747                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2748                    .map(|(worktree_id, server_node, _)| {
 2749                        (
 2750                            *worktree_id,
 2751                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2752                        )
 2753                    })
 2754            })
 2755            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2756                acc.entry(worktree_id)
 2757                    .or_insert_with(Vec::new)
 2758                    .push(server_node);
 2759                acc
 2760            })
 2761            .into_values()
 2762            .max_by_key(|servers| servers.len())?;
 2763
 2764        let worktree_id = worktree.read(cx).id();
 2765        let apply = move |tree: &mut LanguageServerTree| {
 2766            for server_node in &servers {
 2767                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2768            }
 2769            servers
 2770        };
 2771
 2772        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2773        Some((delegate, apply))
 2774    }
 2775
 2776    pub(crate) fn unregister_old_buffer_from_language_servers(
 2777        &mut self,
 2778        buffer: &Entity<Buffer>,
 2779        old_file: &File,
 2780        cx: &mut App,
 2781    ) {
 2782        let old_path = match old_file.as_local() {
 2783            Some(local) => local.abs_path(cx),
 2784            None => return,
 2785        };
 2786
 2787        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2788            debug_panic!("{old_path:?} is not parseable as an URI");
 2789            return;
 2790        };
 2791        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2792    }
 2793
 2794    pub(crate) fn unregister_buffer_from_language_servers(
 2795        &mut self,
 2796        buffer: &Entity<Buffer>,
 2797        file_url: &lsp::Uri,
 2798        cx: &mut App,
 2799    ) {
 2800        buffer.update(cx, |buffer, cx| {
 2801            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2802
 2803            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2804                if snapshots
 2805                    .as_mut()
 2806                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2807                {
 2808                    language_server.unregister_buffer(file_url.clone());
 2809                }
 2810            }
 2811        });
 2812    }
 2813
 2814    fn buffer_snapshot_for_lsp_version(
 2815        &mut self,
 2816        buffer: &Entity<Buffer>,
 2817        server_id: LanguageServerId,
 2818        version: Option<i32>,
 2819        cx: &App,
 2820    ) -> Result<TextBufferSnapshot> {
 2821        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2822
 2823        if let Some(version) = version {
 2824            let buffer_id = buffer.read(cx).remote_id();
 2825            let snapshots = if let Some(snapshots) = self
 2826                .buffer_snapshots
 2827                .get_mut(&buffer_id)
 2828                .and_then(|m| m.get_mut(&server_id))
 2829            {
 2830                snapshots
 2831            } else if version == 0 {
 2832                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2833                // We detect this case and treat it as if the version was `None`.
 2834                return Ok(buffer.read(cx).text_snapshot());
 2835            } else {
 2836                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2837            };
 2838
 2839            let found_snapshot = snapshots
 2840                    .binary_search_by_key(&version, |e| e.version)
 2841                    .map(|ix| snapshots[ix].snapshot.clone())
 2842                    .map_err(|_| {
 2843                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2844                    })?;
 2845
 2846            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2847            Ok(found_snapshot)
 2848        } else {
 2849            Ok((buffer.read(cx)).text_snapshot())
 2850        }
 2851    }
 2852
 2853    async fn get_server_code_actions_from_action_kinds(
 2854        lsp_store: &WeakEntity<LspStore>,
 2855        language_server_id: LanguageServerId,
 2856        code_action_kinds: Vec<lsp::CodeActionKind>,
 2857        buffer: &Entity<Buffer>,
 2858        cx: &mut AsyncApp,
 2859    ) -> Result<Vec<CodeAction>> {
 2860        let actions = lsp_store
 2861            .update(cx, move |this, cx| {
 2862                let request = GetCodeActions {
 2863                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 2864                    kinds: Some(code_action_kinds),
 2865                };
 2866                let server = LanguageServerToQuery::Other(language_server_id);
 2867                this.request_lsp(buffer.clone(), server, request, cx)
 2868            })?
 2869            .await?;
 2870        Ok(actions)
 2871    }
 2872
 2873    pub async fn execute_code_actions_on_server(
 2874        lsp_store: &WeakEntity<LspStore>,
 2875        language_server: &Arc<LanguageServer>,
 2876
 2877        actions: Vec<CodeAction>,
 2878        push_to_history: bool,
 2879        project_transaction: &mut ProjectTransaction,
 2880        cx: &mut AsyncApp,
 2881    ) -> anyhow::Result<()> {
 2882        for mut action in actions {
 2883            Self::try_resolve_code_action(language_server, &mut action)
 2884                .await
 2885                .context("resolving a formatting code action")?;
 2886
 2887            if let Some(edit) = action.lsp_action.edit() {
 2888                if edit.changes.is_none() && edit.document_changes.is_none() {
 2889                    continue;
 2890                }
 2891
 2892                let new = Self::deserialize_workspace_edit(
 2893                    lsp_store.upgrade().context("project dropped")?,
 2894                    edit.clone(),
 2895                    push_to_history,
 2896                    language_server.clone(),
 2897                    cx,
 2898                )
 2899                .await?;
 2900                project_transaction.0.extend(new.0);
 2901            }
 2902
 2903            if let Some(command) = action.lsp_action.command() {
 2904                let server_capabilities = language_server.capabilities();
 2905                let available_commands = server_capabilities
 2906                    .execute_command_provider
 2907                    .as_ref()
 2908                    .map(|options| options.commands.as_slice())
 2909                    .unwrap_or_default();
 2910                if available_commands.contains(&command.command) {
 2911                    lsp_store.update(cx, |lsp_store, _| {
 2912                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2913                            mode.last_workspace_edits_by_language_server
 2914                                .remove(&language_server.server_id());
 2915                        }
 2916                    })?;
 2917
 2918                    language_server
 2919                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2920                            command: command.command.clone(),
 2921                            arguments: command.arguments.clone().unwrap_or_default(),
 2922                            ..Default::default()
 2923                        })
 2924                        .await
 2925                        .into_response()
 2926                        .context("execute command")?;
 2927
 2928                    lsp_store.update(cx, |this, _| {
 2929                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2930                            project_transaction.0.extend(
 2931                                mode.last_workspace_edits_by_language_server
 2932                                    .remove(&language_server.server_id())
 2933                                    .unwrap_or_default()
 2934                                    .0,
 2935                            )
 2936                        }
 2937                    })?;
 2938                } else {
 2939                    log::warn!(
 2940                        "Cannot execute a command {} not listed in the language server capabilities",
 2941                        command.command
 2942                    )
 2943                }
 2944            }
 2945        }
 2946        Ok(())
 2947    }
 2948
 2949    pub async fn deserialize_text_edits(
 2950        this: Entity<LspStore>,
 2951        buffer_to_edit: Entity<Buffer>,
 2952        edits: Vec<lsp::TextEdit>,
 2953        push_to_history: bool,
 2954        _: Arc<CachedLspAdapter>,
 2955        language_server: Arc<LanguageServer>,
 2956        cx: &mut AsyncApp,
 2957    ) -> Result<Option<Transaction>> {
 2958        let edits = this
 2959            .update(cx, |this, cx| {
 2960                this.as_local_mut().unwrap().edits_from_lsp(
 2961                    &buffer_to_edit,
 2962                    edits,
 2963                    language_server.server_id(),
 2964                    None,
 2965                    cx,
 2966                )
 2967            })?
 2968            .await?;
 2969
 2970        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2971            buffer.finalize_last_transaction();
 2972            buffer.start_transaction();
 2973            for (range, text) in edits {
 2974                buffer.edit([(range, text)], None, cx);
 2975            }
 2976
 2977            if buffer.end_transaction(cx).is_some() {
 2978                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2979                if !push_to_history {
 2980                    buffer.forget_transaction(transaction.id);
 2981                }
 2982                Some(transaction)
 2983            } else {
 2984                None
 2985            }
 2986        })?;
 2987
 2988        Ok(transaction)
 2989    }
 2990
 2991    #[allow(clippy::type_complexity)]
 2992    pub(crate) fn edits_from_lsp(
 2993        &mut self,
 2994        buffer: &Entity<Buffer>,
 2995        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2996        server_id: LanguageServerId,
 2997        version: Option<i32>,
 2998        cx: &mut Context<LspStore>,
 2999    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3000        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3001        cx.background_spawn(async move {
 3002            let snapshot = snapshot?;
 3003            let mut lsp_edits = lsp_edits
 3004                .into_iter()
 3005                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3006                .collect::<Vec<_>>();
 3007
 3008            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 3009
 3010            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3011            let mut edits = Vec::new();
 3012            while let Some((range, mut new_text)) = lsp_edits.next() {
 3013                // Clip invalid ranges provided by the language server.
 3014                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3015                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3016
 3017                // Combine any LSP edits that are adjacent.
 3018                //
 3019                // Also, combine LSP edits that are separated from each other by only
 3020                // a newline. This is important because for some code actions,
 3021                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3022                // are separated by unchanged newline characters.
 3023                //
 3024                // In order for the diffing logic below to work properly, any edits that
 3025                // cancel each other out must be combined into one.
 3026                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3027                    if next_range.start.0 > range.end {
 3028                        if next_range.start.0.row > range.end.row + 1
 3029                            || next_range.start.0.column > 0
 3030                            || snapshot.clip_point_utf16(
 3031                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3032                                Bias::Left,
 3033                            ) > range.end
 3034                        {
 3035                            break;
 3036                        }
 3037                        new_text.push('\n');
 3038                    }
 3039                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3040                    new_text.push_str(next_text);
 3041                    lsp_edits.next();
 3042                }
 3043
 3044                // For multiline edits, perform a diff of the old and new text so that
 3045                // we can identify the changes more precisely, preserving the locations
 3046                // of any anchors positioned in the unchanged regions.
 3047                if range.end.row > range.start.row {
 3048                    let offset = range.start.to_offset(&snapshot);
 3049                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3050                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3051                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3052                        (
 3053                            snapshot.anchor_after(offset + range.start)
 3054                                ..snapshot.anchor_before(offset + range.end),
 3055                            replacement,
 3056                        )
 3057                    }));
 3058                } else if range.end == range.start {
 3059                    let anchor = snapshot.anchor_after(range.start);
 3060                    edits.push((anchor..anchor, new_text.into()));
 3061                } else {
 3062                    let edit_start = snapshot.anchor_after(range.start);
 3063                    let edit_end = snapshot.anchor_before(range.end);
 3064                    edits.push((edit_start..edit_end, new_text.into()));
 3065                }
 3066            }
 3067
 3068            Ok(edits)
 3069        })
 3070    }
 3071
 3072    pub(crate) async fn deserialize_workspace_edit(
 3073        this: Entity<LspStore>,
 3074        edit: lsp::WorkspaceEdit,
 3075        push_to_history: bool,
 3076        language_server: Arc<LanguageServer>,
 3077        cx: &mut AsyncApp,
 3078    ) -> Result<ProjectTransaction> {
 3079        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 3080
 3081        let mut operations = Vec::new();
 3082        if let Some(document_changes) = edit.document_changes {
 3083            match document_changes {
 3084                lsp::DocumentChanges::Edits(edits) => {
 3085                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3086                }
 3087                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3088            }
 3089        } else if let Some(changes) = edit.changes {
 3090            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3091                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3092                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3093                        uri,
 3094                        version: None,
 3095                    },
 3096                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3097                })
 3098            }));
 3099        }
 3100
 3101        let mut project_transaction = ProjectTransaction::default();
 3102        for operation in operations {
 3103            match operation {
 3104                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3105                    let abs_path = op
 3106                        .uri
 3107                        .to_file_path()
 3108                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3109
 3110                    if let Some(parent_path) = abs_path.parent() {
 3111                        fs.create_dir(parent_path).await?;
 3112                    }
 3113                    if abs_path.ends_with("/") {
 3114                        fs.create_dir(&abs_path).await?;
 3115                    } else {
 3116                        fs.create_file(
 3117                            &abs_path,
 3118                            op.options
 3119                                .map(|options| fs::CreateOptions {
 3120                                    overwrite: options.overwrite.unwrap_or(false),
 3121                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3122                                })
 3123                                .unwrap_or_default(),
 3124                        )
 3125                        .await?;
 3126                    }
 3127                }
 3128
 3129                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3130                    let source_abs_path = op
 3131                        .old_uri
 3132                        .to_file_path()
 3133                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3134                    let target_abs_path = op
 3135                        .new_uri
 3136                        .to_file_path()
 3137                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3138
 3139                    let options = fs::RenameOptions {
 3140                        overwrite: op
 3141                            .options
 3142                            .as_ref()
 3143                            .and_then(|options| options.overwrite)
 3144                            .unwrap_or(false),
 3145                        ignore_if_exists: op
 3146                            .options
 3147                            .as_ref()
 3148                            .and_then(|options| options.ignore_if_exists)
 3149                            .unwrap_or(false),
 3150                        create_parents: true,
 3151                    };
 3152
 3153                    fs.rename(&source_abs_path, &target_abs_path, options)
 3154                        .await?;
 3155                }
 3156
 3157                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3158                    let abs_path = op
 3159                        .uri
 3160                        .to_file_path()
 3161                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3162                    let options = op
 3163                        .options
 3164                        .map(|options| fs::RemoveOptions {
 3165                            recursive: options.recursive.unwrap_or(false),
 3166                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3167                        })
 3168                        .unwrap_or_default();
 3169                    if abs_path.ends_with("/") {
 3170                        fs.remove_dir(&abs_path, options).await?;
 3171                    } else {
 3172                        fs.remove_file(&abs_path, options).await?;
 3173                    }
 3174                }
 3175
 3176                lsp::DocumentChangeOperation::Edit(op) => {
 3177                    let buffer_to_edit = this
 3178                        .update(cx, |this, cx| {
 3179                            this.open_local_buffer_via_lsp(
 3180                                op.text_document.uri.clone(),
 3181                                language_server.server_id(),
 3182                                cx,
 3183                            )
 3184                        })?
 3185                        .await?;
 3186
 3187                    let edits = this
 3188                        .update(cx, |this, cx| {
 3189                            let path = buffer_to_edit.read(cx).project_path(cx);
 3190                            let active_entry = this.active_entry;
 3191                            let is_active_entry = path.is_some_and(|project_path| {
 3192                                this.worktree_store
 3193                                    .read(cx)
 3194                                    .entry_for_path(&project_path, cx)
 3195                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3196                            });
 3197                            let local = this.as_local_mut().unwrap();
 3198
 3199                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3200                            for edit in op.edits {
 3201                                match edit {
 3202                                    Edit::Plain(edit) => {
 3203                                        if !edits.contains(&edit) {
 3204                                            edits.push(edit)
 3205                                        }
 3206                                    }
 3207                                    Edit::Annotated(edit) => {
 3208                                        if !edits.contains(&edit.text_edit) {
 3209                                            edits.push(edit.text_edit)
 3210                                        }
 3211                                    }
 3212                                    Edit::Snippet(edit) => {
 3213                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3214                                        else {
 3215                                            continue;
 3216                                        };
 3217
 3218                                        if is_active_entry {
 3219                                            snippet_edits.push((edit.range, snippet));
 3220                                        } else {
 3221                                            // Since this buffer is not focused, apply a normal edit.
 3222                                            let new_edit = TextEdit {
 3223                                                range: edit.range,
 3224                                                new_text: snippet.text,
 3225                                            };
 3226                                            if !edits.contains(&new_edit) {
 3227                                                edits.push(new_edit);
 3228                                            }
 3229                                        }
 3230                                    }
 3231                                }
 3232                            }
 3233                            if !snippet_edits.is_empty() {
 3234                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3235                                let version = if let Some(buffer_version) = op.text_document.version
 3236                                {
 3237                                    local
 3238                                        .buffer_snapshot_for_lsp_version(
 3239                                            &buffer_to_edit,
 3240                                            language_server.server_id(),
 3241                                            Some(buffer_version),
 3242                                            cx,
 3243                                        )
 3244                                        .ok()
 3245                                        .map(|snapshot| snapshot.version)
 3246                                } else {
 3247                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3248                                };
 3249
 3250                                let most_recent_edit =
 3251                                    version.and_then(|version| version.most_recent());
 3252                                // Check if the edit that triggered that edit has been made by this participant.
 3253
 3254                                if let Some(most_recent_edit) = most_recent_edit {
 3255                                    cx.emit(LspStoreEvent::SnippetEdit {
 3256                                        buffer_id,
 3257                                        edits: snippet_edits,
 3258                                        most_recent_edit,
 3259                                    });
 3260                                }
 3261                            }
 3262
 3263                            local.edits_from_lsp(
 3264                                &buffer_to_edit,
 3265                                edits,
 3266                                language_server.server_id(),
 3267                                op.text_document.version,
 3268                                cx,
 3269                            )
 3270                        })?
 3271                        .await?;
 3272
 3273                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3274                        buffer.finalize_last_transaction();
 3275                        buffer.start_transaction();
 3276                        for (range, text) in edits {
 3277                            buffer.edit([(range, text)], None, cx);
 3278                        }
 3279
 3280                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3281                            if push_to_history {
 3282                                buffer.finalize_last_transaction();
 3283                                buffer.get_transaction(transaction_id).cloned()
 3284                            } else {
 3285                                buffer.forget_transaction(transaction_id)
 3286                            }
 3287                        })
 3288                    })?;
 3289                    if let Some(transaction) = transaction {
 3290                        project_transaction.0.insert(buffer_to_edit, transaction);
 3291                    }
 3292                }
 3293            }
 3294        }
 3295
 3296        Ok(project_transaction)
 3297    }
 3298
 3299    async fn on_lsp_workspace_edit(
 3300        this: WeakEntity<LspStore>,
 3301        params: lsp::ApplyWorkspaceEditParams,
 3302        server_id: LanguageServerId,
 3303        cx: &mut AsyncApp,
 3304    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3305        let this = this.upgrade().context("project project closed")?;
 3306        let language_server = this
 3307            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3308            .context("language server not found")?;
 3309        let transaction = Self::deserialize_workspace_edit(
 3310            this.clone(),
 3311            params.edit,
 3312            true,
 3313            language_server.clone(),
 3314            cx,
 3315        )
 3316        .await
 3317        .log_err();
 3318        this.update(cx, |this, cx| {
 3319            if let Some(transaction) = transaction {
 3320                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3321
 3322                this.as_local_mut()
 3323                    .unwrap()
 3324                    .last_workspace_edits_by_language_server
 3325                    .insert(server_id, transaction);
 3326            }
 3327        })?;
 3328        Ok(lsp::ApplyWorkspaceEditResponse {
 3329            applied: true,
 3330            failed_change: None,
 3331            failure_reason: None,
 3332        })
 3333    }
 3334
 3335    fn remove_worktree(
 3336        &mut self,
 3337        id_to_remove: WorktreeId,
 3338        cx: &mut Context<LspStore>,
 3339    ) -> Vec<LanguageServerId> {
 3340        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3341        self.diagnostics.remove(&id_to_remove);
 3342        self.prettier_store.update(cx, |prettier_store, cx| {
 3343            prettier_store.remove_worktree(id_to_remove, cx);
 3344        });
 3345
 3346        let mut servers_to_remove = BTreeSet::default();
 3347        let mut servers_to_preserve = HashSet::default();
 3348        for (seed, state) in &self.language_server_ids {
 3349            if seed.worktree_id == id_to_remove {
 3350                servers_to_remove.insert(state.id);
 3351            } else {
 3352                servers_to_preserve.insert(state.id);
 3353            }
 3354        }
 3355        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3356        self.language_server_ids
 3357            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3358        for server_id_to_remove in &servers_to_remove {
 3359            self.language_server_watched_paths
 3360                .remove(server_id_to_remove);
 3361            self.language_server_paths_watched_for_rename
 3362                .remove(server_id_to_remove);
 3363            self.last_workspace_edits_by_language_server
 3364                .remove(server_id_to_remove);
 3365            self.language_servers.remove(server_id_to_remove);
 3366            self.buffer_pull_diagnostics_result_ids
 3367                .remove(server_id_to_remove);
 3368            self.workspace_pull_diagnostics_result_ids
 3369                .remove(server_id_to_remove);
 3370            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3371                buffer_servers.remove(server_id_to_remove);
 3372            }
 3373            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3374        }
 3375        servers_to_remove.into_iter().collect()
 3376    }
 3377
 3378    fn rebuild_watched_paths_inner<'a>(
 3379        &'a self,
 3380        language_server_id: LanguageServerId,
 3381        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3382        cx: &mut Context<LspStore>,
 3383    ) -> LanguageServerWatchedPathsBuilder {
 3384        let worktrees = self
 3385            .worktree_store
 3386            .read(cx)
 3387            .worktrees()
 3388            .filter_map(|worktree| {
 3389                self.language_servers_for_worktree(worktree.read(cx).id())
 3390                    .find(|server| server.server_id() == language_server_id)
 3391                    .map(|_| worktree)
 3392            })
 3393            .collect::<Vec<_>>();
 3394
 3395        let mut worktree_globs = HashMap::default();
 3396        let mut abs_globs = HashMap::default();
 3397        log::trace!(
 3398            "Processing new watcher paths for language server with id {}",
 3399            language_server_id
 3400        );
 3401
 3402        for watcher in watchers {
 3403            if let Some((worktree, literal_prefix, pattern)) =
 3404                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3405            {
 3406                worktree.update(cx, |worktree, _| {
 3407                    if let Some((tree, glob)) =
 3408                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3409                    {
 3410                        tree.add_path_prefix_to_scan(literal_prefix);
 3411                        worktree_globs
 3412                            .entry(tree.id())
 3413                            .or_insert_with(GlobSetBuilder::new)
 3414                            .add(glob);
 3415                    }
 3416                });
 3417            } else {
 3418                let (path, pattern) = match &watcher.glob_pattern {
 3419                    lsp::GlobPattern::String(s) => {
 3420                        let watcher_path = SanitizedPath::new(s);
 3421                        let path = glob_literal_prefix(watcher_path.as_path());
 3422                        let pattern = watcher_path
 3423                            .as_path()
 3424                            .strip_prefix(&path)
 3425                            .map(|p| p.to_string_lossy().into_owned())
 3426                            .unwrap_or_else(|e| {
 3427                                debug_panic!(
 3428                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3429                                    s,
 3430                                    path.display(),
 3431                                    e
 3432                                );
 3433                                watcher_path.as_path().to_string_lossy().into_owned()
 3434                            });
 3435                        (path, pattern)
 3436                    }
 3437                    lsp::GlobPattern::Relative(rp) => {
 3438                        let Ok(mut base_uri) = match &rp.base_uri {
 3439                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3440                            lsp::OneOf::Right(base_uri) => base_uri,
 3441                        }
 3442                        .to_file_path() else {
 3443                            continue;
 3444                        };
 3445
 3446                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3447                        let pattern = Path::new(&rp.pattern)
 3448                            .strip_prefix(&path)
 3449                            .map(|p| p.to_string_lossy().into_owned())
 3450                            .unwrap_or_else(|e| {
 3451                                debug_panic!(
 3452                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3453                                    rp.pattern,
 3454                                    path.display(),
 3455                                    e
 3456                                );
 3457                                rp.pattern.clone()
 3458                            });
 3459                        base_uri.push(path);
 3460                        (base_uri, pattern)
 3461                    }
 3462                };
 3463
 3464                if let Some(glob) = Glob::new(&pattern).log_err() {
 3465                    if !path
 3466                        .components()
 3467                        .any(|c| matches!(c, path::Component::Normal(_)))
 3468                    {
 3469                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3470                        // rather than adding a new watcher for `/`.
 3471                        for worktree in &worktrees {
 3472                            worktree_globs
 3473                                .entry(worktree.read(cx).id())
 3474                                .or_insert_with(GlobSetBuilder::new)
 3475                                .add(glob.clone());
 3476                        }
 3477                    } else {
 3478                        abs_globs
 3479                            .entry(path.into())
 3480                            .or_insert_with(GlobSetBuilder::new)
 3481                            .add(glob);
 3482                    }
 3483                }
 3484            }
 3485        }
 3486
 3487        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3488        for (worktree_id, builder) in worktree_globs {
 3489            if let Ok(globset) = builder.build() {
 3490                watch_builder.watch_worktree(worktree_id, globset);
 3491            }
 3492        }
 3493        for (abs_path, builder) in abs_globs {
 3494            if let Ok(globset) = builder.build() {
 3495                watch_builder.watch_abs_path(abs_path, globset);
 3496            }
 3497        }
 3498        watch_builder
 3499    }
 3500
 3501    fn worktree_and_path_for_file_watcher(
 3502        worktrees: &[Entity<Worktree>],
 3503        watcher: &FileSystemWatcher,
 3504        cx: &App,
 3505    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3506        worktrees.iter().find_map(|worktree| {
 3507            let tree = worktree.read(cx);
 3508            let worktree_root_path = tree.abs_path();
 3509            let path_style = tree.path_style();
 3510            match &watcher.glob_pattern {
 3511                lsp::GlobPattern::String(s) => {
 3512                    let watcher_path = SanitizedPath::new(s);
 3513                    let relative = watcher_path
 3514                        .as_path()
 3515                        .strip_prefix(&worktree_root_path)
 3516                        .ok()?;
 3517                    let literal_prefix = glob_literal_prefix(relative);
 3518                    Some((
 3519                        worktree.clone(),
 3520                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3521                        relative.to_string_lossy().into_owned(),
 3522                    ))
 3523                }
 3524                lsp::GlobPattern::Relative(rp) => {
 3525                    let base_uri = match &rp.base_uri {
 3526                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3527                        lsp::OneOf::Right(base_uri) => base_uri,
 3528                    }
 3529                    .to_file_path()
 3530                    .ok()?;
 3531                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3532                    let mut literal_prefix = relative.to_owned();
 3533                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3534                    Some((
 3535                        worktree.clone(),
 3536                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3537                        rp.pattern.clone(),
 3538                    ))
 3539                }
 3540            }
 3541        })
 3542    }
 3543
 3544    fn rebuild_watched_paths(
 3545        &mut self,
 3546        language_server_id: LanguageServerId,
 3547        cx: &mut Context<LspStore>,
 3548    ) {
 3549        let Some(registrations) = self
 3550            .language_server_dynamic_registrations
 3551            .get(&language_server_id)
 3552        else {
 3553            return;
 3554        };
 3555
 3556        let watch_builder = self.rebuild_watched_paths_inner(
 3557            language_server_id,
 3558            registrations.did_change_watched_files.values().flatten(),
 3559            cx,
 3560        );
 3561        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3562        self.language_server_watched_paths
 3563            .insert(language_server_id, watcher);
 3564
 3565        cx.notify();
 3566    }
 3567
 3568    fn on_lsp_did_change_watched_files(
 3569        &mut self,
 3570        language_server_id: LanguageServerId,
 3571        registration_id: &str,
 3572        params: DidChangeWatchedFilesRegistrationOptions,
 3573        cx: &mut Context<LspStore>,
 3574    ) {
 3575        let registrations = self
 3576            .language_server_dynamic_registrations
 3577            .entry(language_server_id)
 3578            .or_default();
 3579
 3580        registrations
 3581            .did_change_watched_files
 3582            .insert(registration_id.to_string(), params.watchers);
 3583
 3584        self.rebuild_watched_paths(language_server_id, cx);
 3585    }
 3586
 3587    fn on_lsp_unregister_did_change_watched_files(
 3588        &mut self,
 3589        language_server_id: LanguageServerId,
 3590        registration_id: &str,
 3591        cx: &mut Context<LspStore>,
 3592    ) {
 3593        let registrations = self
 3594            .language_server_dynamic_registrations
 3595            .entry(language_server_id)
 3596            .or_default();
 3597
 3598        if registrations
 3599            .did_change_watched_files
 3600            .remove(registration_id)
 3601            .is_some()
 3602        {
 3603            log::info!(
 3604                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3605                language_server_id,
 3606                registration_id
 3607            );
 3608        } else {
 3609            log::warn!(
 3610                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3611                language_server_id,
 3612                registration_id
 3613            );
 3614        }
 3615
 3616        self.rebuild_watched_paths(language_server_id, cx);
 3617    }
 3618
 3619    async fn initialization_options_for_adapter(
 3620        adapter: Arc<dyn LspAdapter>,
 3621        delegate: &Arc<dyn LspAdapterDelegate>,
 3622    ) -> Result<Option<serde_json::Value>> {
 3623        let Some(mut initialization_config) =
 3624            adapter.clone().initialization_options(delegate).await?
 3625        else {
 3626            return Ok(None);
 3627        };
 3628
 3629        for other_adapter in delegate.registered_lsp_adapters() {
 3630            if other_adapter.name() == adapter.name() {
 3631                continue;
 3632            }
 3633            if let Ok(Some(target_config)) = other_adapter
 3634                .clone()
 3635                .additional_initialization_options(adapter.name(), delegate)
 3636                .await
 3637            {
 3638                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3639            }
 3640        }
 3641
 3642        Ok(Some(initialization_config))
 3643    }
 3644
 3645    async fn workspace_configuration_for_adapter(
 3646        adapter: Arc<dyn LspAdapter>,
 3647        delegate: &Arc<dyn LspAdapterDelegate>,
 3648        toolchain: Option<Toolchain>,
 3649        requested_uri: Option<Uri>,
 3650        cx: &mut AsyncApp,
 3651    ) -> Result<serde_json::Value> {
 3652        let mut workspace_config = adapter
 3653            .clone()
 3654            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3655            .await?;
 3656
 3657        for other_adapter in delegate.registered_lsp_adapters() {
 3658            if other_adapter.name() == adapter.name() {
 3659                continue;
 3660            }
 3661            if let Ok(Some(target_config)) = other_adapter
 3662                .clone()
 3663                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3664                .await
 3665            {
 3666                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3667            }
 3668        }
 3669
 3670        Ok(workspace_config)
 3671    }
 3672
 3673    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3674        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3675            Some(server.clone())
 3676        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3677            Some(Arc::clone(server))
 3678        } else {
 3679            None
 3680        }
 3681    }
 3682}
 3683
 3684fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3685    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3686        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3687            language_server_id: server.server_id(),
 3688            name: Some(server.name()),
 3689            message: proto::update_language_server::Variant::MetadataUpdated(
 3690                proto::ServerMetadataUpdated {
 3691                    capabilities: Some(capabilities),
 3692                    binary: Some(proto::LanguageServerBinaryInfo {
 3693                        path: server.binary().path.to_string_lossy().into_owned(),
 3694                        arguments: server
 3695                            .binary()
 3696                            .arguments
 3697                            .iter()
 3698                            .map(|arg| arg.to_string_lossy().into_owned())
 3699                            .collect(),
 3700                    }),
 3701                    configuration: serde_json::to_string(server.configuration()).ok(),
 3702                    workspace_folders: server
 3703                        .workspace_folders()
 3704                        .iter()
 3705                        .map(|uri| uri.to_string())
 3706                        .collect(),
 3707                },
 3708            ),
 3709        });
 3710    }
 3711}
 3712
 3713#[derive(Debug)]
 3714pub struct FormattableBuffer {
 3715    handle: Entity<Buffer>,
 3716    abs_path: Option<PathBuf>,
 3717    env: Option<HashMap<String, String>>,
 3718    ranges: Option<Vec<Range<Anchor>>>,
 3719}
 3720
 3721pub struct RemoteLspStore {
 3722    upstream_client: Option<AnyProtoClient>,
 3723    upstream_project_id: u64,
 3724}
 3725
 3726pub(crate) enum LspStoreMode {
 3727    Local(LocalLspStore),   // ssh host and collab host
 3728    Remote(RemoteLspStore), // collab guest
 3729}
 3730
 3731impl LspStoreMode {
 3732    fn is_local(&self) -> bool {
 3733        matches!(self, LspStoreMode::Local(_))
 3734    }
 3735}
 3736
 3737pub struct LspStore {
 3738    mode: LspStoreMode,
 3739    last_formatting_failure: Option<String>,
 3740    downstream_client: Option<(AnyProtoClient, u64)>,
 3741    nonce: u128,
 3742    buffer_store: Entity<BufferStore>,
 3743    worktree_store: Entity<WorktreeStore>,
 3744    pub languages: Arc<LanguageRegistry>,
 3745    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3746    active_entry: Option<ProjectEntryId>,
 3747    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3748    _maintain_buffer_languages: Task<()>,
 3749    diagnostic_summaries:
 3750        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3751    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3752    lsp_data: HashMap<BufferId, BufferLspData>,
 3753    next_hint_id: Arc<AtomicUsize>,
 3754}
 3755
 3756#[derive(Debug)]
 3757pub struct BufferLspData {
 3758    buffer_version: Global,
 3759    document_colors: Option<DocumentColorData>,
 3760    code_lens: Option<CodeLensData>,
 3761    inlay_hints: BufferInlayHints,
 3762    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3763    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3764}
 3765
 3766#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3767struct LspKey {
 3768    request_type: TypeId,
 3769    server_queried: Option<LanguageServerId>,
 3770}
 3771
 3772impl BufferLspData {
 3773    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3774        Self {
 3775            buffer_version: buffer.read(cx).version(),
 3776            document_colors: None,
 3777            code_lens: None,
 3778            inlay_hints: BufferInlayHints::new(buffer, cx),
 3779            lsp_requests: HashMap::default(),
 3780            chunk_lsp_requests: HashMap::default(),
 3781        }
 3782    }
 3783
 3784    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3785        if let Some(document_colors) = &mut self.document_colors {
 3786            document_colors.colors.remove(&for_server);
 3787            document_colors.cache_version += 1;
 3788        }
 3789
 3790        if let Some(code_lens) = &mut self.code_lens {
 3791            code_lens.lens.remove(&for_server);
 3792        }
 3793
 3794        self.inlay_hints.remove_server_data(for_server);
 3795    }
 3796
 3797    #[cfg(any(test, feature = "test-support"))]
 3798    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3799        &self.inlay_hints
 3800    }
 3801}
 3802
 3803#[derive(Debug, Default, Clone)]
 3804pub struct DocumentColors {
 3805    pub colors: HashSet<DocumentColor>,
 3806    pub cache_version: Option<usize>,
 3807}
 3808
 3809type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3810type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3811
 3812#[derive(Debug, Default)]
 3813struct DocumentColorData {
 3814    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3815    cache_version: usize,
 3816    colors_update: Option<(Global, DocumentColorTask)>,
 3817}
 3818
 3819#[derive(Debug, Default)]
 3820struct CodeLensData {
 3821    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3822    update: Option<(Global, CodeLensTask)>,
 3823}
 3824
 3825#[derive(Debug)]
 3826pub enum LspStoreEvent {
 3827    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3828    LanguageServerRemoved(LanguageServerId),
 3829    LanguageServerUpdate {
 3830        language_server_id: LanguageServerId,
 3831        name: Option<LanguageServerName>,
 3832        message: proto::update_language_server::Variant,
 3833    },
 3834    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3835    LanguageServerPrompt(LanguageServerPromptRequest),
 3836    LanguageDetected {
 3837        buffer: Entity<Buffer>,
 3838        new_language: Option<Arc<Language>>,
 3839    },
 3840    Notification(String),
 3841    RefreshInlayHints {
 3842        server_id: LanguageServerId,
 3843        request_id: Option<usize>,
 3844    },
 3845    RefreshCodeLens,
 3846    DiagnosticsUpdated {
 3847        server_id: LanguageServerId,
 3848        paths: Vec<ProjectPath>,
 3849    },
 3850    DiskBasedDiagnosticsStarted {
 3851        language_server_id: LanguageServerId,
 3852    },
 3853    DiskBasedDiagnosticsFinished {
 3854        language_server_id: LanguageServerId,
 3855    },
 3856    SnippetEdit {
 3857        buffer_id: BufferId,
 3858        edits: Vec<(lsp::Range, Snippet)>,
 3859        most_recent_edit: clock::Lamport,
 3860    },
 3861    WorkspaceEditApplied(ProjectTransaction),
 3862}
 3863
 3864#[derive(Clone, Debug, Serialize)]
 3865pub struct LanguageServerStatus {
 3866    pub name: LanguageServerName,
 3867    pub server_version: Option<SharedString>,
 3868    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3869    pub has_pending_diagnostic_updates: bool,
 3870    pub progress_tokens: HashSet<ProgressToken>,
 3871    pub worktree: Option<WorktreeId>,
 3872    pub binary: Option<LanguageServerBinary>,
 3873    pub configuration: Option<Value>,
 3874    pub workspace_folders: BTreeSet<Uri>,
 3875}
 3876
 3877#[derive(Clone, Debug)]
 3878struct CoreSymbol {
 3879    pub language_server_name: LanguageServerName,
 3880    pub source_worktree_id: WorktreeId,
 3881    pub source_language_server_id: LanguageServerId,
 3882    pub path: SymbolLocation,
 3883    pub name: String,
 3884    pub kind: lsp::SymbolKind,
 3885    pub range: Range<Unclipped<PointUtf16>>,
 3886}
 3887
 3888#[derive(Clone, Debug, PartialEq, Eq)]
 3889pub enum SymbolLocation {
 3890    InProject(ProjectPath),
 3891    OutsideProject {
 3892        abs_path: Arc<Path>,
 3893        signature: [u8; 32],
 3894    },
 3895}
 3896
 3897impl SymbolLocation {
 3898    fn file_name(&self) -> Option<&str> {
 3899        match self {
 3900            Self::InProject(path) => path.path.file_name(),
 3901            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3902        }
 3903    }
 3904}
 3905
 3906impl LspStore {
 3907    pub fn init(client: &AnyProtoClient) {
 3908        client.add_entity_request_handler(Self::handle_lsp_query);
 3909        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3910        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3911        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3912        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3913        client.add_entity_message_handler(Self::handle_start_language_server);
 3914        client.add_entity_message_handler(Self::handle_update_language_server);
 3915        client.add_entity_message_handler(Self::handle_language_server_log);
 3916        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3917        client.add_entity_request_handler(Self::handle_format_buffers);
 3918        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3919        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3920        client.add_entity_request_handler(Self::handle_apply_code_action);
 3921        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3922        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3923        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3924        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3925        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3926        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3927        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3928        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3929        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3930        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3931        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3932        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3933        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3934        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3935        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3936        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3937        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3938
 3939        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3940        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3941        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3942        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3943        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3944        client.add_entity_request_handler(
 3945            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3946        );
 3947        client.add_entity_request_handler(
 3948            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3949        );
 3950        client.add_entity_request_handler(
 3951            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3952        );
 3953    }
 3954
 3955    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3956        match &self.mode {
 3957            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3958            _ => None,
 3959        }
 3960    }
 3961
 3962    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3963        match &self.mode {
 3964            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3965            _ => None,
 3966        }
 3967    }
 3968
 3969    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3970        match &mut self.mode {
 3971            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3972            _ => None,
 3973        }
 3974    }
 3975
 3976    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3977        match &self.mode {
 3978            LspStoreMode::Remote(RemoteLspStore {
 3979                upstream_client: Some(upstream_client),
 3980                upstream_project_id,
 3981                ..
 3982            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3983
 3984            LspStoreMode::Remote(RemoteLspStore {
 3985                upstream_client: None,
 3986                ..
 3987            }) => None,
 3988            LspStoreMode::Local(_) => None,
 3989        }
 3990    }
 3991
 3992    pub fn new_local(
 3993        buffer_store: Entity<BufferStore>,
 3994        worktree_store: Entity<WorktreeStore>,
 3995        prettier_store: Entity<PrettierStore>,
 3996        toolchain_store: Entity<LocalToolchainStore>,
 3997        environment: Entity<ProjectEnvironment>,
 3998        manifest_tree: Entity<ManifestTree>,
 3999        languages: Arc<LanguageRegistry>,
 4000        http_client: Arc<dyn HttpClient>,
 4001        fs: Arc<dyn Fs>,
 4002        cx: &mut Context<Self>,
 4003    ) -> Self {
 4004        let yarn = YarnPathStore::new(fs.clone(), cx);
 4005        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4006            .detach();
 4007        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4008            .detach();
 4009        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4010            .detach();
 4011        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4012            .detach();
 4013        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4014            .detach();
 4015        subscribe_to_binary_statuses(&languages, cx).detach();
 4016
 4017        let _maintain_workspace_config = {
 4018            let (sender, receiver) = watch::channel();
 4019            (Self::maintain_workspace_config(receiver, cx), sender)
 4020        };
 4021
 4022        Self {
 4023            mode: LspStoreMode::Local(LocalLspStore {
 4024                weak: cx.weak_entity(),
 4025                worktree_store: worktree_store.clone(),
 4026
 4027                supplementary_language_servers: Default::default(),
 4028                languages: languages.clone(),
 4029                language_server_ids: Default::default(),
 4030                language_servers: Default::default(),
 4031                last_workspace_edits_by_language_server: Default::default(),
 4032                language_server_watched_paths: Default::default(),
 4033                language_server_paths_watched_for_rename: Default::default(),
 4034                language_server_dynamic_registrations: Default::default(),
 4035                buffers_being_formatted: Default::default(),
 4036                buffer_snapshots: Default::default(),
 4037                prettier_store,
 4038                environment,
 4039                http_client,
 4040                fs,
 4041                yarn,
 4042                next_diagnostic_group_id: Default::default(),
 4043                diagnostics: Default::default(),
 4044                _subscription: cx.on_app_quit(|this, cx| {
 4045                    this.as_local_mut()
 4046                        .unwrap()
 4047                        .shutdown_language_servers_on_quit(cx)
 4048                }),
 4049                lsp_tree: LanguageServerTree::new(
 4050                    manifest_tree,
 4051                    languages.clone(),
 4052                    toolchain_store.clone(),
 4053                ),
 4054                toolchain_store,
 4055                registered_buffers: HashMap::default(),
 4056                buffers_opened_in_servers: HashMap::default(),
 4057                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4058                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4059                restricted_worktrees_tasks: HashMap::default(),
 4060                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4061                    .manifest_file_names(),
 4062            }),
 4063            last_formatting_failure: None,
 4064            downstream_client: None,
 4065            buffer_store,
 4066            worktree_store,
 4067            languages: languages.clone(),
 4068            language_server_statuses: Default::default(),
 4069            nonce: StdRng::from_os_rng().random(),
 4070            diagnostic_summaries: HashMap::default(),
 4071            lsp_server_capabilities: HashMap::default(),
 4072            lsp_data: HashMap::default(),
 4073            next_hint_id: Arc::default(),
 4074            active_entry: None,
 4075            _maintain_workspace_config,
 4076            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4077        }
 4078    }
 4079
 4080    fn send_lsp_proto_request<R: LspCommand>(
 4081        &self,
 4082        buffer: Entity<Buffer>,
 4083        client: AnyProtoClient,
 4084        upstream_project_id: u64,
 4085        request: R,
 4086        cx: &mut Context<LspStore>,
 4087    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4088        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4089            return Task::ready(Ok(R::Response::default()));
 4090        }
 4091        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4092        cx.spawn(async move |this, cx| {
 4093            let response = client.request(message).await?;
 4094            let this = this.upgrade().context("project dropped")?;
 4095            request
 4096                .response_from_proto(response, this, buffer, cx.clone())
 4097                .await
 4098        })
 4099    }
 4100
 4101    pub(super) fn new_remote(
 4102        buffer_store: Entity<BufferStore>,
 4103        worktree_store: Entity<WorktreeStore>,
 4104        languages: Arc<LanguageRegistry>,
 4105        upstream_client: AnyProtoClient,
 4106        project_id: u64,
 4107        cx: &mut Context<Self>,
 4108    ) -> Self {
 4109        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4110            .detach();
 4111        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4112            .detach();
 4113        subscribe_to_binary_statuses(&languages, cx).detach();
 4114        let _maintain_workspace_config = {
 4115            let (sender, receiver) = watch::channel();
 4116            (Self::maintain_workspace_config(receiver, cx), sender)
 4117        };
 4118        Self {
 4119            mode: LspStoreMode::Remote(RemoteLspStore {
 4120                upstream_client: Some(upstream_client),
 4121                upstream_project_id: project_id,
 4122            }),
 4123            downstream_client: None,
 4124            last_formatting_failure: None,
 4125            buffer_store,
 4126            worktree_store,
 4127            languages: languages.clone(),
 4128            language_server_statuses: Default::default(),
 4129            nonce: StdRng::from_os_rng().random(),
 4130            diagnostic_summaries: HashMap::default(),
 4131            lsp_server_capabilities: HashMap::default(),
 4132            next_hint_id: Arc::default(),
 4133            lsp_data: HashMap::default(),
 4134            active_entry: None,
 4135
 4136            _maintain_workspace_config,
 4137            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4138        }
 4139    }
 4140
 4141    fn on_buffer_store_event(
 4142        &mut self,
 4143        _: Entity<BufferStore>,
 4144        event: &BufferStoreEvent,
 4145        cx: &mut Context<Self>,
 4146    ) {
 4147        match event {
 4148            BufferStoreEvent::BufferAdded(buffer) => {
 4149                self.on_buffer_added(buffer, cx).log_err();
 4150            }
 4151            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4152                let buffer_id = buffer.read(cx).remote_id();
 4153                if let Some(local) = self.as_local_mut()
 4154                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4155                {
 4156                    local.reset_buffer(buffer, old_file, cx);
 4157
 4158                    if local.registered_buffers.contains_key(&buffer_id) {
 4159                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4160                    }
 4161                }
 4162
 4163                self.detect_language_for_buffer(buffer, cx);
 4164                if let Some(local) = self.as_local_mut() {
 4165                    local.initialize_buffer(buffer, cx);
 4166                    if local.registered_buffers.contains_key(&buffer_id) {
 4167                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4168                    }
 4169                }
 4170            }
 4171            _ => {}
 4172        }
 4173    }
 4174
 4175    fn on_worktree_store_event(
 4176        &mut self,
 4177        _: Entity<WorktreeStore>,
 4178        event: &WorktreeStoreEvent,
 4179        cx: &mut Context<Self>,
 4180    ) {
 4181        match event {
 4182            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4183                if !worktree.read(cx).is_local() {
 4184                    return;
 4185                }
 4186                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4187                    worktree::Event::UpdatedEntries(changes) => {
 4188                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4189                    }
 4190                    worktree::Event::UpdatedGitRepositories(_)
 4191                    | worktree::Event::DeletedEntry(_) => {}
 4192                })
 4193                .detach()
 4194            }
 4195            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4196            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4197                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4198            }
 4199            WorktreeStoreEvent::WorktreeReleased(..)
 4200            | WorktreeStoreEvent::WorktreeOrderChanged
 4201            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4202            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4203            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4204        }
 4205    }
 4206
 4207    fn on_prettier_store_event(
 4208        &mut self,
 4209        _: Entity<PrettierStore>,
 4210        event: &PrettierStoreEvent,
 4211        cx: &mut Context<Self>,
 4212    ) {
 4213        match event {
 4214            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4215                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4216            }
 4217            PrettierStoreEvent::LanguageServerAdded {
 4218                new_server_id,
 4219                name,
 4220                prettier_server,
 4221            } => {
 4222                self.register_supplementary_language_server(
 4223                    *new_server_id,
 4224                    name.clone(),
 4225                    prettier_server.clone(),
 4226                    cx,
 4227                );
 4228            }
 4229        }
 4230    }
 4231
 4232    fn on_toolchain_store_event(
 4233        &mut self,
 4234        _: Entity<LocalToolchainStore>,
 4235        event: &ToolchainStoreEvent,
 4236        _: &mut Context<Self>,
 4237    ) {
 4238        if let ToolchainStoreEvent::ToolchainActivated = event {
 4239            self.request_workspace_config_refresh()
 4240        }
 4241    }
 4242
 4243    fn request_workspace_config_refresh(&mut self) {
 4244        *self._maintain_workspace_config.1.borrow_mut() = ();
 4245    }
 4246
 4247    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4248        self.as_local().map(|local| local.prettier_store.clone())
 4249    }
 4250
 4251    fn on_buffer_event(
 4252        &mut self,
 4253        buffer: Entity<Buffer>,
 4254        event: &language::BufferEvent,
 4255        cx: &mut Context<Self>,
 4256    ) {
 4257        match event {
 4258            language::BufferEvent::Edited => {
 4259                self.on_buffer_edited(buffer, cx);
 4260            }
 4261
 4262            language::BufferEvent::Saved => {
 4263                self.on_buffer_saved(buffer, cx);
 4264            }
 4265
 4266            _ => {}
 4267        }
 4268    }
 4269
 4270    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4271        buffer
 4272            .read(cx)
 4273            .set_language_registry(self.languages.clone());
 4274
 4275        cx.subscribe(buffer, |this, buffer, event, cx| {
 4276            this.on_buffer_event(buffer, event, cx);
 4277        })
 4278        .detach();
 4279
 4280        self.detect_language_for_buffer(buffer, cx);
 4281        if let Some(local) = self.as_local_mut() {
 4282            local.initialize_buffer(buffer, cx);
 4283        }
 4284
 4285        Ok(())
 4286    }
 4287
 4288    pub(crate) fn register_buffer_with_language_servers(
 4289        &mut self,
 4290        buffer: &Entity<Buffer>,
 4291        only_register_servers: HashSet<LanguageServerSelector>,
 4292        ignore_refcounts: bool,
 4293        cx: &mut Context<Self>,
 4294    ) -> OpenLspBufferHandle {
 4295        let buffer_id = buffer.read(cx).remote_id();
 4296        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4297        if let Some(local) = self.as_local_mut() {
 4298            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4299            if !ignore_refcounts {
 4300                *refcount += 1;
 4301            }
 4302
 4303            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4304            // 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
 4305            // 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
 4306            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4307            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4308                return handle;
 4309            };
 4310            if !file.is_local() {
 4311                return handle;
 4312            }
 4313
 4314            if ignore_refcounts || *refcount == 1 {
 4315                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4316            }
 4317            if !ignore_refcounts {
 4318                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4319                    let refcount = {
 4320                        let local = lsp_store.as_local_mut().unwrap();
 4321                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4322                            debug_panic!("bad refcounting");
 4323                            return;
 4324                        };
 4325
 4326                        *refcount -= 1;
 4327                        *refcount
 4328                    };
 4329                    if refcount == 0 {
 4330                        lsp_store.lsp_data.remove(&buffer_id);
 4331                        let local = lsp_store.as_local_mut().unwrap();
 4332                        local.registered_buffers.remove(&buffer_id);
 4333
 4334                        local.buffers_opened_in_servers.remove(&buffer_id);
 4335                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4336                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4337
 4338                            let buffer_abs_path = file.abs_path(cx);
 4339                            for (_, buffer_pull_diagnostics_result_ids) in
 4340                                &mut local.buffer_pull_diagnostics_result_ids
 4341                            {
 4342                                buffer_pull_diagnostics_result_ids.retain(
 4343                                    |_, buffer_result_ids| {
 4344                                        buffer_result_ids.remove(&buffer_abs_path);
 4345                                        !buffer_result_ids.is_empty()
 4346                                    },
 4347                                );
 4348                            }
 4349
 4350                            let diagnostic_updates = local
 4351                                .language_servers
 4352                                .keys()
 4353                                .cloned()
 4354                                .map(|server_id| DocumentDiagnosticsUpdate {
 4355                                    diagnostics: DocumentDiagnostics {
 4356                                        document_abs_path: buffer_abs_path.clone(),
 4357                                        version: None,
 4358                                        diagnostics: Vec::new(),
 4359                                    },
 4360                                    result_id: None,
 4361                                    registration_id: None,
 4362                                    server_id: server_id,
 4363                                    disk_based_sources: Cow::Borrowed(&[]),
 4364                                })
 4365                                .collect::<Vec<_>>();
 4366
 4367                            lsp_store
 4368                                .merge_diagnostic_entries(
 4369                                    diagnostic_updates,
 4370                                    |_, diagnostic, _| {
 4371                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4372                                    },
 4373                                    cx,
 4374                                )
 4375                                .context("Clearing diagnostics for the closed buffer")
 4376                                .log_err();
 4377                        }
 4378                    }
 4379                })
 4380                .detach();
 4381            }
 4382        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4383            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4384            cx.background_spawn(async move {
 4385                upstream_client
 4386                    .request(proto::RegisterBufferWithLanguageServers {
 4387                        project_id: upstream_project_id,
 4388                        buffer_id,
 4389                        only_servers: only_register_servers
 4390                            .into_iter()
 4391                            .map(|selector| {
 4392                                let selector = match selector {
 4393                                    LanguageServerSelector::Id(language_server_id) => {
 4394                                        proto::language_server_selector::Selector::ServerId(
 4395                                            language_server_id.to_proto(),
 4396                                        )
 4397                                    }
 4398                                    LanguageServerSelector::Name(language_server_name) => {
 4399                                        proto::language_server_selector::Selector::Name(
 4400                                            language_server_name.to_string(),
 4401                                        )
 4402                                    }
 4403                                };
 4404                                proto::LanguageServerSelector {
 4405                                    selector: Some(selector),
 4406                                }
 4407                            })
 4408                            .collect(),
 4409                    })
 4410                    .await
 4411            })
 4412            .detach();
 4413        } else {
 4414            // Our remote connection got closed
 4415        }
 4416        handle
 4417    }
 4418
 4419    fn maintain_buffer_languages(
 4420        languages: Arc<LanguageRegistry>,
 4421        cx: &mut Context<Self>,
 4422    ) -> Task<()> {
 4423        let mut subscription = languages.subscribe();
 4424        let mut prev_reload_count = languages.reload_count();
 4425        cx.spawn(async move |this, cx| {
 4426            while let Some(()) = subscription.next().await {
 4427                if let Some(this) = this.upgrade() {
 4428                    // If the language registry has been reloaded, then remove and
 4429                    // re-assign the languages on all open buffers.
 4430                    let reload_count = languages.reload_count();
 4431                    if reload_count > prev_reload_count {
 4432                        prev_reload_count = reload_count;
 4433                        this.update(cx, |this, cx| {
 4434                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4435                                for buffer in buffer_store.buffers() {
 4436                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4437                                    {
 4438                                        buffer.update(cx, |buffer, cx| {
 4439                                            buffer.set_language_async(None, cx)
 4440                                        });
 4441                                        if let Some(local) = this.as_local_mut() {
 4442                                            local.reset_buffer(&buffer, &f, cx);
 4443
 4444                                            if local
 4445                                                .registered_buffers
 4446                                                .contains_key(&buffer.read(cx).remote_id())
 4447                                                && let Some(file_url) =
 4448                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4449                                            {
 4450                                                local.unregister_buffer_from_language_servers(
 4451                                                    &buffer, &file_url, cx,
 4452                                                );
 4453                                            }
 4454                                        }
 4455                                    }
 4456                                }
 4457                            });
 4458                        })
 4459                        .ok();
 4460                    }
 4461
 4462                    this.update(cx, |this, cx| {
 4463                        let mut plain_text_buffers = Vec::new();
 4464                        let mut buffers_with_unknown_injections = Vec::new();
 4465                        for handle in this.buffer_store.read(cx).buffers() {
 4466                            let buffer = handle.read(cx);
 4467                            if buffer.language().is_none()
 4468                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4469                            {
 4470                                plain_text_buffers.push(handle);
 4471                            } else if buffer.contains_unknown_injections() {
 4472                                buffers_with_unknown_injections.push(handle);
 4473                            }
 4474                        }
 4475
 4476                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4477                        // and reused later in the invisible worktrees.
 4478                        plain_text_buffers.sort_by_key(|buffer| {
 4479                            Reverse(
 4480                                File::from_dyn(buffer.read(cx).file())
 4481                                    .map(|file| file.worktree.read(cx).is_visible()),
 4482                            )
 4483                        });
 4484
 4485                        for buffer in plain_text_buffers {
 4486                            this.detect_language_for_buffer(&buffer, cx);
 4487                            if let Some(local) = this.as_local_mut() {
 4488                                local.initialize_buffer(&buffer, cx);
 4489                                if local
 4490                                    .registered_buffers
 4491                                    .contains_key(&buffer.read(cx).remote_id())
 4492                                {
 4493                                    local.register_buffer_with_language_servers(
 4494                                        &buffer,
 4495                                        HashSet::default(),
 4496                                        cx,
 4497                                    );
 4498                                }
 4499                            }
 4500                        }
 4501
 4502                        for buffer in buffers_with_unknown_injections {
 4503                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4504                        }
 4505                    })
 4506                    .ok();
 4507                }
 4508            }
 4509        })
 4510    }
 4511
 4512    fn detect_language_for_buffer(
 4513        &mut self,
 4514        buffer_handle: &Entity<Buffer>,
 4515        cx: &mut Context<Self>,
 4516    ) -> Option<language::AvailableLanguage> {
 4517        // If the buffer has a language, set it and start the language server if we haven't already.
 4518        let buffer = buffer_handle.read(cx);
 4519        let file = buffer.file()?;
 4520
 4521        let content = buffer.as_rope();
 4522        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4523        if let Some(available_language) = &available_language {
 4524            if let Some(Ok(Ok(new_language))) = self
 4525                .languages
 4526                .load_language(available_language)
 4527                .now_or_never()
 4528            {
 4529                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4530            }
 4531        } else {
 4532            cx.emit(LspStoreEvent::LanguageDetected {
 4533                buffer: buffer_handle.clone(),
 4534                new_language: None,
 4535            });
 4536        }
 4537
 4538        available_language
 4539    }
 4540
 4541    pub(crate) fn set_language_for_buffer(
 4542        &mut self,
 4543        buffer_entity: &Entity<Buffer>,
 4544        new_language: Arc<Language>,
 4545        cx: &mut Context<Self>,
 4546    ) {
 4547        let buffer = buffer_entity.read(cx);
 4548        let buffer_file = buffer.file().cloned();
 4549        let buffer_id = buffer.remote_id();
 4550        if let Some(local_store) = self.as_local_mut()
 4551            && local_store.registered_buffers.contains_key(&buffer_id)
 4552            && let Some(abs_path) =
 4553                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4554            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4555        {
 4556            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4557        }
 4558        buffer_entity.update(cx, |buffer, cx| {
 4559            if buffer
 4560                .language()
 4561                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4562            {
 4563                buffer.set_language_async(Some(new_language.clone()), cx);
 4564            }
 4565        });
 4566
 4567        let settings =
 4568            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4569        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4570
 4571        let worktree_id = if let Some(file) = buffer_file {
 4572            let worktree = file.worktree.clone();
 4573
 4574            if let Some(local) = self.as_local_mut()
 4575                && local.registered_buffers.contains_key(&buffer_id)
 4576            {
 4577                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4578            }
 4579            Some(worktree.read(cx).id())
 4580        } else {
 4581            None
 4582        };
 4583
 4584        if settings.prettier.allowed
 4585            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4586        {
 4587            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4588            if let Some(prettier_store) = prettier_store {
 4589                prettier_store.update(cx, |prettier_store, cx| {
 4590                    prettier_store.install_default_prettier(
 4591                        worktree_id,
 4592                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4593                        cx,
 4594                    )
 4595                })
 4596            }
 4597        }
 4598
 4599        cx.emit(LspStoreEvent::LanguageDetected {
 4600            buffer: buffer_entity.clone(),
 4601            new_language: Some(new_language),
 4602        })
 4603    }
 4604
 4605    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4606        self.buffer_store.clone()
 4607    }
 4608
 4609    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4610        self.active_entry = active_entry;
 4611    }
 4612
 4613    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4614        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4615            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4616        {
 4617            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4618                summaries
 4619                    .iter()
 4620                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4621            });
 4622            if let Some(summary) = summaries.next() {
 4623                client
 4624                    .send(proto::UpdateDiagnosticSummary {
 4625                        project_id: downstream_project_id,
 4626                        worktree_id: worktree.id().to_proto(),
 4627                        summary: Some(summary),
 4628                        more_summaries: summaries.collect(),
 4629                    })
 4630                    .log_err();
 4631            }
 4632        }
 4633    }
 4634
 4635    fn is_capable_for_proto_request<R>(
 4636        &self,
 4637        buffer: &Entity<Buffer>,
 4638        request: &R,
 4639        cx: &App,
 4640    ) -> bool
 4641    where
 4642        R: LspCommand,
 4643    {
 4644        self.check_if_capable_for_proto_request(
 4645            buffer,
 4646            |capabilities| {
 4647                request.check_capabilities(AdapterServerCapabilities {
 4648                    server_capabilities: capabilities.clone(),
 4649                    code_action_kinds: None,
 4650                })
 4651            },
 4652            cx,
 4653        )
 4654    }
 4655
 4656    fn check_if_capable_for_proto_request<F>(
 4657        &self,
 4658        buffer: &Entity<Buffer>,
 4659        check: F,
 4660        cx: &App,
 4661    ) -> bool
 4662    where
 4663        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4664    {
 4665        let Some(language) = buffer.read(cx).language().cloned() else {
 4666            return false;
 4667        };
 4668        let registered_language_servers = self
 4669            .languages
 4670            .lsp_adapters(&language.name())
 4671            .into_iter()
 4672            .map(|lsp_adapter| lsp_adapter.name())
 4673            .collect::<HashSet<_>>();
 4674        self.language_server_statuses
 4675            .iter()
 4676            .filter_map(|(server_id, server_status)| {
 4677                // Include servers that are either registered for this language OR
 4678                // available to be loaded (for SSH remote mode where adapters like
 4679                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4680                // but only loaded on the server side)
 4681                let is_relevant = registered_language_servers.contains(&server_status.name)
 4682                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4683                is_relevant.then_some(server_id)
 4684            })
 4685            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4686            .any(check)
 4687    }
 4688
 4689    fn all_capable_for_proto_request<F>(
 4690        &self,
 4691        buffer: &Entity<Buffer>,
 4692        mut check: F,
 4693        cx: &App,
 4694    ) -> Vec<lsp::LanguageServerId>
 4695    where
 4696        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4697    {
 4698        let Some(language) = buffer.read(cx).language().cloned() else {
 4699            return Vec::default();
 4700        };
 4701        let registered_language_servers = self
 4702            .languages
 4703            .lsp_adapters(&language.name())
 4704            .into_iter()
 4705            .map(|lsp_adapter| lsp_adapter.name())
 4706            .collect::<HashSet<_>>();
 4707        self.language_server_statuses
 4708            .iter()
 4709            .filter_map(|(server_id, server_status)| {
 4710                // Include servers that are either registered for this language OR
 4711                // available to be loaded (for SSH remote mode where adapters like
 4712                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4713                // but only loaded on the server side)
 4714                let is_relevant = registered_language_servers.contains(&server_status.name)
 4715                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4716                is_relevant.then_some((server_id, &server_status.name))
 4717            })
 4718            .filter_map(|(server_id, server_name)| {
 4719                self.lsp_server_capabilities
 4720                    .get(server_id)
 4721                    .map(|c| (server_id, server_name, c))
 4722            })
 4723            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4724            .map(|(server_id, _, _)| *server_id)
 4725            .collect()
 4726    }
 4727
 4728    pub fn request_lsp<R>(
 4729        &mut self,
 4730        buffer: Entity<Buffer>,
 4731        server: LanguageServerToQuery,
 4732        request: R,
 4733        cx: &mut Context<Self>,
 4734    ) -> Task<Result<R::Response>>
 4735    where
 4736        R: LspCommand,
 4737        <R::LspRequest as lsp::request::Request>::Result: Send,
 4738        <R::LspRequest as lsp::request::Request>::Params: Send,
 4739    {
 4740        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4741            return self.send_lsp_proto_request(
 4742                buffer,
 4743                upstream_client,
 4744                upstream_project_id,
 4745                request,
 4746                cx,
 4747            );
 4748        }
 4749
 4750        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4751            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4752                local
 4753                    .language_servers_for_buffer(buffer, cx)
 4754                    .find(|(_, server)| {
 4755                        request.check_capabilities(server.adapter_server_capabilities())
 4756                    })
 4757                    .map(|(_, server)| server.clone())
 4758            }),
 4759            LanguageServerToQuery::Other(id) => self
 4760                .language_server_for_local_buffer(buffer, id, cx)
 4761                .and_then(|(_, server)| {
 4762                    request
 4763                        .check_capabilities(server.adapter_server_capabilities())
 4764                        .then(|| Arc::clone(server))
 4765                }),
 4766        }) else {
 4767            return Task::ready(Ok(Default::default()));
 4768        };
 4769
 4770        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4771
 4772        let Some(file) = file else {
 4773            return Task::ready(Ok(Default::default()));
 4774        };
 4775
 4776        let lsp_params = match request.to_lsp_params_or_response(
 4777            &file.abs_path(cx),
 4778            buffer.read(cx),
 4779            &language_server,
 4780            cx,
 4781        ) {
 4782            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4783            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4784            Err(err) => {
 4785                let message = format!(
 4786                    "{} via {} failed: {}",
 4787                    request.display_name(),
 4788                    language_server.name(),
 4789                    err
 4790                );
 4791                // rust-analyzer likes to error with this when its still loading up
 4792                if !message.ends_with("content modified") {
 4793                    log::warn!("{message}");
 4794                }
 4795                return Task::ready(Err(anyhow!(message)));
 4796            }
 4797        };
 4798
 4799        let status = request.status();
 4800        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4801            return Task::ready(Ok(Default::default()));
 4802        }
 4803        cx.spawn(async move |this, cx| {
 4804            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4805
 4806            let id = lsp_request.id();
 4807            let _cleanup = if status.is_some() {
 4808                cx.update(|cx| {
 4809                    this.update(cx, |this, cx| {
 4810                        this.on_lsp_work_start(
 4811                            language_server.server_id(),
 4812                            ProgressToken::Number(id),
 4813                            LanguageServerProgress {
 4814                                is_disk_based_diagnostics_progress: false,
 4815                                is_cancellable: false,
 4816                                title: None,
 4817                                message: status.clone(),
 4818                                percentage: None,
 4819                                last_update_at: cx.background_executor().now(),
 4820                            },
 4821                            cx,
 4822                        );
 4823                    })
 4824                })
 4825                .log_err();
 4826
 4827                Some(defer(|| {
 4828                    cx.update(|cx| {
 4829                        this.update(cx, |this, cx| {
 4830                            this.on_lsp_work_end(
 4831                                language_server.server_id(),
 4832                                ProgressToken::Number(id),
 4833                                cx,
 4834                            );
 4835                        })
 4836                    })
 4837                    .log_err();
 4838                }))
 4839            } else {
 4840                None
 4841            };
 4842
 4843            let result = lsp_request.await.into_response();
 4844
 4845            let response = result.map_err(|err| {
 4846                let message = format!(
 4847                    "{} via {} failed: {}",
 4848                    request.display_name(),
 4849                    language_server.name(),
 4850                    err
 4851                );
 4852                // rust-analyzer likes to error with this when its still loading up
 4853                if !message.ends_with("content modified") {
 4854                    log::warn!("{message}");
 4855                }
 4856                anyhow::anyhow!(message)
 4857            })?;
 4858
 4859            request
 4860                .response_from_lsp(
 4861                    response,
 4862                    this.upgrade().context("no app context")?,
 4863                    buffer,
 4864                    language_server.server_id(),
 4865                    cx.clone(),
 4866                )
 4867                .await
 4868        })
 4869    }
 4870
 4871    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4872        let mut language_formatters_to_check = Vec::new();
 4873        for buffer in self.buffer_store.read(cx).buffers() {
 4874            let buffer = buffer.read(cx);
 4875            let buffer_file = File::from_dyn(buffer.file());
 4876            let buffer_language = buffer.language();
 4877            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4878            if buffer_language.is_some() {
 4879                language_formatters_to_check.push((
 4880                    buffer_file.map(|f| f.worktree_id(cx)),
 4881                    settings.into_owned(),
 4882                ));
 4883            }
 4884        }
 4885
 4886        self.request_workspace_config_refresh();
 4887
 4888        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4889            prettier_store.update(cx, |prettier_store, cx| {
 4890                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4891            })
 4892        }
 4893
 4894        cx.notify();
 4895    }
 4896
 4897    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4898        let buffer_store = self.buffer_store.clone();
 4899        let Some(local) = self.as_local_mut() else {
 4900            return;
 4901        };
 4902        let mut adapters = BTreeMap::default();
 4903        let get_adapter = {
 4904            let languages = local.languages.clone();
 4905            let environment = local.environment.clone();
 4906            let weak = local.weak.clone();
 4907            let worktree_store = local.worktree_store.clone();
 4908            let http_client = local.http_client.clone();
 4909            let fs = local.fs.clone();
 4910            move |worktree_id, cx: &mut App| {
 4911                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4912                Some(LocalLspAdapterDelegate::new(
 4913                    languages.clone(),
 4914                    &environment,
 4915                    weak.clone(),
 4916                    &worktree,
 4917                    http_client.clone(),
 4918                    fs.clone(),
 4919                    cx,
 4920                ))
 4921            }
 4922        };
 4923
 4924        let mut messages_to_report = Vec::new();
 4925        let (new_tree, to_stop) = {
 4926            let mut rebase = local.lsp_tree.rebase();
 4927            let buffers = buffer_store
 4928                .read(cx)
 4929                .buffers()
 4930                .filter_map(|buffer| {
 4931                    let raw_buffer = buffer.read(cx);
 4932                    if !local
 4933                        .registered_buffers
 4934                        .contains_key(&raw_buffer.remote_id())
 4935                    {
 4936                        return None;
 4937                    }
 4938                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4939                    let language = raw_buffer.language().cloned()?;
 4940                    Some((file, language, raw_buffer.remote_id()))
 4941                })
 4942                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4943            for (file, language, buffer_id) in buffers {
 4944                let worktree_id = file.worktree_id(cx);
 4945                let Some(worktree) = local
 4946                    .worktree_store
 4947                    .read(cx)
 4948                    .worktree_for_id(worktree_id, cx)
 4949                else {
 4950                    continue;
 4951                };
 4952
 4953                if let Some((_, apply)) = local.reuse_existing_language_server(
 4954                    rebase.server_tree(),
 4955                    &worktree,
 4956                    &language.name(),
 4957                    cx,
 4958                ) {
 4959                    (apply)(rebase.server_tree());
 4960                } else if let Some(lsp_delegate) = adapters
 4961                    .entry(worktree_id)
 4962                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4963                    .clone()
 4964                {
 4965                    let delegate =
 4966                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4967                    let path = file
 4968                        .path()
 4969                        .parent()
 4970                        .map(Arc::from)
 4971                        .unwrap_or_else(|| file.path().clone());
 4972                    let worktree_path = ProjectPath { worktree_id, path };
 4973                    let abs_path = file.abs_path(cx);
 4974                    let nodes = rebase
 4975                        .walk(
 4976                            worktree_path,
 4977                            language.name(),
 4978                            language.manifest(),
 4979                            delegate.clone(),
 4980                            cx,
 4981                        )
 4982                        .collect::<Vec<_>>();
 4983                    for node in nodes {
 4984                        let server_id = node.server_id_or_init(|disposition| {
 4985                            let path = &disposition.path;
 4986                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4987                            let key = LanguageServerSeed {
 4988                                worktree_id,
 4989                                name: disposition.server_name.clone(),
 4990                                settings: disposition.settings.clone(),
 4991                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4992                                    path.worktree_id,
 4993                                    &path.path,
 4994                                    language.name(),
 4995                                ),
 4996                            };
 4997                            local.language_server_ids.remove(&key);
 4998
 4999                            let server_id = local.get_or_insert_language_server(
 5000                                &worktree,
 5001                                lsp_delegate.clone(),
 5002                                disposition,
 5003                                &language.name(),
 5004                                cx,
 5005                            );
 5006                            if let Some(state) = local.language_servers.get(&server_id)
 5007                                && let Ok(uri) = uri
 5008                            {
 5009                                state.add_workspace_folder(uri);
 5010                            };
 5011                            server_id
 5012                        });
 5013
 5014                        if let Some(language_server_id) = server_id {
 5015                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5016                                language_server_id,
 5017                                name: node.name(),
 5018                                message:
 5019                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5020                                        proto::RegisteredForBuffer {
 5021                                            buffer_abs_path: abs_path
 5022                                                .to_string_lossy()
 5023                                                .into_owned(),
 5024                                            buffer_id: buffer_id.to_proto(),
 5025                                        },
 5026                                    ),
 5027                            });
 5028                        }
 5029                    }
 5030                } else {
 5031                    continue;
 5032                }
 5033            }
 5034            rebase.finish()
 5035        };
 5036        for message in messages_to_report {
 5037            cx.emit(message);
 5038        }
 5039        local.lsp_tree = new_tree;
 5040        for (id, _) in to_stop {
 5041            self.stop_local_language_server(id, cx).detach();
 5042        }
 5043    }
 5044
 5045    pub fn apply_code_action(
 5046        &self,
 5047        buffer_handle: Entity<Buffer>,
 5048        mut action: CodeAction,
 5049        push_to_history: bool,
 5050        cx: &mut Context<Self>,
 5051    ) -> Task<Result<ProjectTransaction>> {
 5052        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5053            let request = proto::ApplyCodeAction {
 5054                project_id,
 5055                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5056                action: Some(Self::serialize_code_action(&action)),
 5057            };
 5058            let buffer_store = self.buffer_store();
 5059            cx.spawn(async move |_, cx| {
 5060                let response = upstream_client
 5061                    .request(request)
 5062                    .await?
 5063                    .transaction
 5064                    .context("missing transaction")?;
 5065
 5066                buffer_store
 5067                    .update(cx, |buffer_store, cx| {
 5068                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5069                    })?
 5070                    .await
 5071            })
 5072        } else if self.mode.is_local() {
 5073            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 5074                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5075                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 5076            }) else {
 5077                return Task::ready(Ok(ProjectTransaction::default()));
 5078            };
 5079            cx.spawn(async move |this,  cx| {
 5080                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 5081                    .await
 5082                    .context("resolving a code action")?;
 5083                if let Some(edit) = action.lsp_action.edit()
 5084                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5085                        return LocalLspStore::deserialize_workspace_edit(
 5086                            this.upgrade().context("no app present")?,
 5087                            edit.clone(),
 5088                            push_to_history,
 5089
 5090                            lang_server.clone(),
 5091                            cx,
 5092                        )
 5093                        .await;
 5094                    }
 5095
 5096                if let Some(command) = action.lsp_action.command() {
 5097                    let server_capabilities = lang_server.capabilities();
 5098                    let available_commands = server_capabilities
 5099                        .execute_command_provider
 5100                        .as_ref()
 5101                        .map(|options| options.commands.as_slice())
 5102                        .unwrap_or_default();
 5103                    if available_commands.contains(&command.command) {
 5104                        this.update(cx, |this, _| {
 5105                            this.as_local_mut()
 5106                                .unwrap()
 5107                                .last_workspace_edits_by_language_server
 5108                                .remove(&lang_server.server_id());
 5109                        })?;
 5110
 5111                        let _result = lang_server
 5112                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5113                                command: command.command.clone(),
 5114                                arguments: command.arguments.clone().unwrap_or_default(),
 5115                                ..lsp::ExecuteCommandParams::default()
 5116                            })
 5117                            .await.into_response()
 5118                            .context("execute command")?;
 5119
 5120                        return this.update(cx, |this, _| {
 5121                            this.as_local_mut()
 5122                                .unwrap()
 5123                                .last_workspace_edits_by_language_server
 5124                                .remove(&lang_server.server_id())
 5125                                .unwrap_or_default()
 5126                        });
 5127                    } else {
 5128                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5129                    }
 5130                }
 5131
 5132                Ok(ProjectTransaction::default())
 5133            })
 5134        } else {
 5135            Task::ready(Err(anyhow!("no upstream client and not local")))
 5136        }
 5137    }
 5138
 5139    pub fn apply_code_action_kind(
 5140        &mut self,
 5141        buffers: HashSet<Entity<Buffer>>,
 5142        kind: CodeActionKind,
 5143        push_to_history: bool,
 5144        cx: &mut Context<Self>,
 5145    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5146        if self.as_local().is_some() {
 5147            cx.spawn(async move |lsp_store, cx| {
 5148                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5149                let result = LocalLspStore::execute_code_action_kind_locally(
 5150                    lsp_store.clone(),
 5151                    buffers,
 5152                    kind,
 5153                    push_to_history,
 5154                    cx,
 5155                )
 5156                .await;
 5157                lsp_store.update(cx, |lsp_store, _| {
 5158                    lsp_store.update_last_formatting_failure(&result);
 5159                })?;
 5160                result
 5161            })
 5162        } else if let Some((client, project_id)) = self.upstream_client() {
 5163            let buffer_store = self.buffer_store();
 5164            cx.spawn(async move |lsp_store, cx| {
 5165                let result = client
 5166                    .request(proto::ApplyCodeActionKind {
 5167                        project_id,
 5168                        kind: kind.as_str().to_owned(),
 5169                        buffer_ids: buffers
 5170                            .iter()
 5171                            .map(|buffer| {
 5172                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5173                            })
 5174                            .collect::<Result<_>>()?,
 5175                    })
 5176                    .await
 5177                    .and_then(|result| result.transaction.context("missing transaction"));
 5178                lsp_store.update(cx, |lsp_store, _| {
 5179                    lsp_store.update_last_formatting_failure(&result);
 5180                })?;
 5181
 5182                let transaction_response = result?;
 5183                buffer_store
 5184                    .update(cx, |buffer_store, cx| {
 5185                        buffer_store.deserialize_project_transaction(
 5186                            transaction_response,
 5187                            push_to_history,
 5188                            cx,
 5189                        )
 5190                    })?
 5191                    .await
 5192            })
 5193        } else {
 5194            Task::ready(Ok(ProjectTransaction::default()))
 5195        }
 5196    }
 5197
 5198    pub fn resolved_hint(
 5199        &mut self,
 5200        buffer_id: BufferId,
 5201        id: InlayId,
 5202        cx: &mut Context<Self>,
 5203    ) -> Option<ResolvedHint> {
 5204        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5205
 5206        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5207        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5208        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5209        let (server_id, resolve_data) = match &hint.resolve_state {
 5210            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5211            ResolveState::Resolving => {
 5212                return Some(ResolvedHint::Resolving(
 5213                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5214                ));
 5215            }
 5216            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5217        };
 5218
 5219        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5220        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5221        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5222            id,
 5223            cx.spawn(async move |lsp_store, cx| {
 5224                let resolved_hint = resolve_task.await;
 5225                lsp_store
 5226                    .update(cx, |lsp_store, _| {
 5227                        if let Some(old_inlay_hint) = lsp_store
 5228                            .lsp_data
 5229                            .get_mut(&buffer_id)
 5230                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5231                        {
 5232                            match resolved_hint {
 5233                                Ok(resolved_hint) => {
 5234                                    *old_inlay_hint = resolved_hint;
 5235                                }
 5236                                Err(e) => {
 5237                                    old_inlay_hint.resolve_state =
 5238                                        ResolveState::CanResolve(server_id, resolve_data);
 5239                                    log::error!("Inlay hint resolve failed: {e:#}");
 5240                                }
 5241                            }
 5242                        }
 5243                    })
 5244                    .ok();
 5245            })
 5246            .shared(),
 5247        );
 5248        debug_assert!(
 5249            previous_task.is_none(),
 5250            "Did not change hint's resolve state after spawning its resolve"
 5251        );
 5252        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5253        None
 5254    }
 5255
 5256    fn resolve_inlay_hint(
 5257        &self,
 5258        mut hint: InlayHint,
 5259        buffer: Entity<Buffer>,
 5260        server_id: LanguageServerId,
 5261        cx: &mut Context<Self>,
 5262    ) -> Task<anyhow::Result<InlayHint>> {
 5263        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5264            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5265            {
 5266                hint.resolve_state = ResolveState::Resolved;
 5267                return Task::ready(Ok(hint));
 5268            }
 5269            let request = proto::ResolveInlayHint {
 5270                project_id,
 5271                buffer_id: buffer.read(cx).remote_id().into(),
 5272                language_server_id: server_id.0 as u64,
 5273                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5274            };
 5275            cx.background_spawn(async move {
 5276                let response = upstream_client
 5277                    .request(request)
 5278                    .await
 5279                    .context("inlay hints proto request")?;
 5280                match response.hint {
 5281                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5282                        .context("inlay hints proto resolve response conversion"),
 5283                    None => Ok(hint),
 5284                }
 5285            })
 5286        } else {
 5287            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5288                self.language_server_for_local_buffer(buffer, server_id, cx)
 5289                    .map(|(_, server)| server.clone())
 5290            }) else {
 5291                return Task::ready(Ok(hint));
 5292            };
 5293            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5294                return Task::ready(Ok(hint));
 5295            }
 5296            let buffer_snapshot = buffer.read(cx).snapshot();
 5297            cx.spawn(async move |_, cx| {
 5298                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5299                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5300                );
 5301                let resolved_hint = resolve_task
 5302                    .await
 5303                    .into_response()
 5304                    .context("inlay hint resolve LSP request")?;
 5305                let resolved_hint = InlayHints::lsp_to_project_hint(
 5306                    resolved_hint,
 5307                    &buffer,
 5308                    server_id,
 5309                    ResolveState::Resolved,
 5310                    false,
 5311                    cx,
 5312                )
 5313                .await?;
 5314                Ok(resolved_hint)
 5315            })
 5316        }
 5317    }
 5318
 5319    pub fn resolve_color_presentation(
 5320        &mut self,
 5321        mut color: DocumentColor,
 5322        buffer: Entity<Buffer>,
 5323        server_id: LanguageServerId,
 5324        cx: &mut Context<Self>,
 5325    ) -> Task<Result<DocumentColor>> {
 5326        if color.resolved {
 5327            return Task::ready(Ok(color));
 5328        }
 5329
 5330        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5331            let start = color.lsp_range.start;
 5332            let end = color.lsp_range.end;
 5333            let request = proto::GetColorPresentation {
 5334                project_id,
 5335                server_id: server_id.to_proto(),
 5336                buffer_id: buffer.read(cx).remote_id().into(),
 5337                color: Some(proto::ColorInformation {
 5338                    red: color.color.red,
 5339                    green: color.color.green,
 5340                    blue: color.color.blue,
 5341                    alpha: color.color.alpha,
 5342                    lsp_range_start: Some(proto::PointUtf16 {
 5343                        row: start.line,
 5344                        column: start.character,
 5345                    }),
 5346                    lsp_range_end: Some(proto::PointUtf16 {
 5347                        row: end.line,
 5348                        column: end.character,
 5349                    }),
 5350                }),
 5351            };
 5352            cx.background_spawn(async move {
 5353                let response = upstream_client
 5354                    .request(request)
 5355                    .await
 5356                    .context("color presentation proto request")?;
 5357                color.resolved = true;
 5358                color.color_presentations = response
 5359                    .presentations
 5360                    .into_iter()
 5361                    .map(|presentation| ColorPresentation {
 5362                        label: SharedString::from(presentation.label),
 5363                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5364                        additional_text_edits: presentation
 5365                            .additional_text_edits
 5366                            .into_iter()
 5367                            .filter_map(deserialize_lsp_edit)
 5368                            .collect(),
 5369                    })
 5370                    .collect();
 5371                Ok(color)
 5372            })
 5373        } else {
 5374            let path = match buffer
 5375                .update(cx, |buffer, cx| {
 5376                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5377                })
 5378                .context("buffer with the missing path")
 5379            {
 5380                Ok(path) => path,
 5381                Err(e) => return Task::ready(Err(e)),
 5382            };
 5383            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5384                self.language_server_for_local_buffer(buffer, server_id, cx)
 5385                    .map(|(_, server)| server.clone())
 5386            }) else {
 5387                return Task::ready(Ok(color));
 5388            };
 5389            cx.background_spawn(async move {
 5390                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5391                    lsp::ColorPresentationParams {
 5392                        text_document: make_text_document_identifier(&path)?,
 5393                        color: color.color,
 5394                        range: color.lsp_range,
 5395                        work_done_progress_params: Default::default(),
 5396                        partial_result_params: Default::default(),
 5397                    },
 5398                );
 5399                color.color_presentations = resolve_task
 5400                    .await
 5401                    .into_response()
 5402                    .context("color presentation resolve LSP request")?
 5403                    .into_iter()
 5404                    .map(|presentation| ColorPresentation {
 5405                        label: SharedString::from(presentation.label),
 5406                        text_edit: presentation.text_edit,
 5407                        additional_text_edits: presentation
 5408                            .additional_text_edits
 5409                            .unwrap_or_default(),
 5410                    })
 5411                    .collect();
 5412                color.resolved = true;
 5413                Ok(color)
 5414            })
 5415        }
 5416    }
 5417
 5418    pub(crate) fn linked_edits(
 5419        &mut self,
 5420        buffer: &Entity<Buffer>,
 5421        position: Anchor,
 5422        cx: &mut Context<Self>,
 5423    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5424        let snapshot = buffer.read(cx).snapshot();
 5425        let scope = snapshot.language_scope_at(position);
 5426        let Some(server_id) = self
 5427            .as_local()
 5428            .and_then(|local| {
 5429                buffer.update(cx, |buffer, cx| {
 5430                    local
 5431                        .language_servers_for_buffer(buffer, cx)
 5432                        .filter(|(_, server)| {
 5433                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5434                        })
 5435                        .filter(|(adapter, _)| {
 5436                            scope
 5437                                .as_ref()
 5438                                .map(|scope| scope.language_allowed(&adapter.name))
 5439                                .unwrap_or(true)
 5440                        })
 5441                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5442                        .next()
 5443                })
 5444            })
 5445            .or_else(|| {
 5446                self.upstream_client()
 5447                    .is_some()
 5448                    .then_some(LanguageServerToQuery::FirstCapable)
 5449            })
 5450            .filter(|_| {
 5451                maybe!({
 5452                    let language = buffer.read(cx).language_at(position)?;
 5453                    Some(
 5454                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5455                            .linked_edits,
 5456                    )
 5457                }) == Some(true)
 5458            })
 5459        else {
 5460            return Task::ready(Ok(Vec::new()));
 5461        };
 5462
 5463        self.request_lsp(
 5464            buffer.clone(),
 5465            server_id,
 5466            LinkedEditingRange { position },
 5467            cx,
 5468        )
 5469    }
 5470
 5471    fn apply_on_type_formatting(
 5472        &mut self,
 5473        buffer: Entity<Buffer>,
 5474        position: Anchor,
 5475        trigger: String,
 5476        cx: &mut Context<Self>,
 5477    ) -> Task<Result<Option<Transaction>>> {
 5478        if let Some((client, project_id)) = self.upstream_client() {
 5479            if !self.check_if_capable_for_proto_request(
 5480                &buffer,
 5481                |capabilities| {
 5482                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5483                },
 5484                cx,
 5485            ) {
 5486                return Task::ready(Ok(None));
 5487            }
 5488            let request = proto::OnTypeFormatting {
 5489                project_id,
 5490                buffer_id: buffer.read(cx).remote_id().into(),
 5491                position: Some(serialize_anchor(&position)),
 5492                trigger,
 5493                version: serialize_version(&buffer.read(cx).version()),
 5494            };
 5495            cx.background_spawn(async move {
 5496                client
 5497                    .request(request)
 5498                    .await?
 5499                    .transaction
 5500                    .map(language::proto::deserialize_transaction)
 5501                    .transpose()
 5502            })
 5503        } else if let Some(local) = self.as_local_mut() {
 5504            let buffer_id = buffer.read(cx).remote_id();
 5505            local.buffers_being_formatted.insert(buffer_id);
 5506            cx.spawn(async move |this, cx| {
 5507                let _cleanup = defer({
 5508                    let this = this.clone();
 5509                    let mut cx = cx.clone();
 5510                    move || {
 5511                        this.update(&mut cx, |this, _| {
 5512                            if let Some(local) = this.as_local_mut() {
 5513                                local.buffers_being_formatted.remove(&buffer_id);
 5514                            }
 5515                        })
 5516                        .ok();
 5517                    }
 5518                });
 5519
 5520                buffer
 5521                    .update(cx, |buffer, _| {
 5522                        buffer.wait_for_edits(Some(position.timestamp))
 5523                    })?
 5524                    .await?;
 5525                this.update(cx, |this, cx| {
 5526                    let position = position.to_point_utf16(buffer.read(cx));
 5527                    this.on_type_format(buffer, position, trigger, false, cx)
 5528                })?
 5529                .await
 5530            })
 5531        } else {
 5532            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5533        }
 5534    }
 5535
 5536    pub fn on_type_format<T: ToPointUtf16>(
 5537        &mut self,
 5538        buffer: Entity<Buffer>,
 5539        position: T,
 5540        trigger: String,
 5541        push_to_history: bool,
 5542        cx: &mut Context<Self>,
 5543    ) -> Task<Result<Option<Transaction>>> {
 5544        let position = position.to_point_utf16(buffer.read(cx));
 5545        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5546    }
 5547
 5548    fn on_type_format_impl(
 5549        &mut self,
 5550        buffer: Entity<Buffer>,
 5551        position: PointUtf16,
 5552        trigger: String,
 5553        push_to_history: bool,
 5554        cx: &mut Context<Self>,
 5555    ) -> Task<Result<Option<Transaction>>> {
 5556        let options = buffer.update(cx, |buffer, cx| {
 5557            lsp_command::lsp_formatting_options(
 5558                language_settings(
 5559                    buffer.language_at(position).map(|l| l.name()),
 5560                    buffer.file(),
 5561                    cx,
 5562                )
 5563                .as_ref(),
 5564            )
 5565        });
 5566
 5567        cx.spawn(async move |this, cx| {
 5568            if let Some(waiter) =
 5569                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5570            {
 5571                waiter.await?;
 5572            }
 5573            cx.update(|cx| {
 5574                this.update(cx, |this, cx| {
 5575                    this.request_lsp(
 5576                        buffer.clone(),
 5577                        LanguageServerToQuery::FirstCapable,
 5578                        OnTypeFormatting {
 5579                            position,
 5580                            trigger,
 5581                            options,
 5582                            push_to_history,
 5583                        },
 5584                        cx,
 5585                    )
 5586                })
 5587            })??
 5588            .await
 5589        })
 5590    }
 5591
 5592    pub fn definitions(
 5593        &mut self,
 5594        buffer: &Entity<Buffer>,
 5595        position: PointUtf16,
 5596        cx: &mut Context<Self>,
 5597    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5598        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5599            let request = GetDefinitions { position };
 5600            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5601                return Task::ready(Ok(None));
 5602            }
 5603            let request_task = upstream_client.request_lsp(
 5604                project_id,
 5605                None,
 5606                LSP_REQUEST_TIMEOUT,
 5607                cx.background_executor().clone(),
 5608                request.to_proto(project_id, buffer.read(cx)),
 5609            );
 5610            let buffer = buffer.clone();
 5611            cx.spawn(async move |weak_lsp_store, cx| {
 5612                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5613                    return Ok(None);
 5614                };
 5615                let Some(responses) = request_task.await? else {
 5616                    return Ok(None);
 5617                };
 5618                let actions = join_all(responses.payload.into_iter().map(|response| {
 5619                    GetDefinitions { position }.response_from_proto(
 5620                        response.response,
 5621                        lsp_store.clone(),
 5622                        buffer.clone(),
 5623                        cx.clone(),
 5624                    )
 5625                }))
 5626                .await;
 5627
 5628                Ok(Some(
 5629                    actions
 5630                        .into_iter()
 5631                        .collect::<Result<Vec<Vec<_>>>>()?
 5632                        .into_iter()
 5633                        .flatten()
 5634                        .dedup()
 5635                        .collect(),
 5636                ))
 5637            })
 5638        } else {
 5639            let definitions_task = self.request_multiple_lsp_locally(
 5640                buffer,
 5641                Some(position),
 5642                GetDefinitions { position },
 5643                cx,
 5644            );
 5645            cx.background_spawn(async move {
 5646                Ok(Some(
 5647                    definitions_task
 5648                        .await
 5649                        .into_iter()
 5650                        .flat_map(|(_, definitions)| definitions)
 5651                        .dedup()
 5652                        .collect(),
 5653                ))
 5654            })
 5655        }
 5656    }
 5657
 5658    pub fn declarations(
 5659        &mut self,
 5660        buffer: &Entity<Buffer>,
 5661        position: PointUtf16,
 5662        cx: &mut Context<Self>,
 5663    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5664        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5665            let request = GetDeclarations { position };
 5666            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5667                return Task::ready(Ok(None));
 5668            }
 5669            let request_task = upstream_client.request_lsp(
 5670                project_id,
 5671                None,
 5672                LSP_REQUEST_TIMEOUT,
 5673                cx.background_executor().clone(),
 5674                request.to_proto(project_id, buffer.read(cx)),
 5675            );
 5676            let buffer = buffer.clone();
 5677            cx.spawn(async move |weak_lsp_store, cx| {
 5678                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5679                    return Ok(None);
 5680                };
 5681                let Some(responses) = request_task.await? else {
 5682                    return Ok(None);
 5683                };
 5684                let actions = join_all(responses.payload.into_iter().map(|response| {
 5685                    GetDeclarations { position }.response_from_proto(
 5686                        response.response,
 5687                        lsp_store.clone(),
 5688                        buffer.clone(),
 5689                        cx.clone(),
 5690                    )
 5691                }))
 5692                .await;
 5693
 5694                Ok(Some(
 5695                    actions
 5696                        .into_iter()
 5697                        .collect::<Result<Vec<Vec<_>>>>()?
 5698                        .into_iter()
 5699                        .flatten()
 5700                        .dedup()
 5701                        .collect(),
 5702                ))
 5703            })
 5704        } else {
 5705            let declarations_task = self.request_multiple_lsp_locally(
 5706                buffer,
 5707                Some(position),
 5708                GetDeclarations { position },
 5709                cx,
 5710            );
 5711            cx.background_spawn(async move {
 5712                Ok(Some(
 5713                    declarations_task
 5714                        .await
 5715                        .into_iter()
 5716                        .flat_map(|(_, declarations)| declarations)
 5717                        .dedup()
 5718                        .collect(),
 5719                ))
 5720            })
 5721        }
 5722    }
 5723
 5724    pub fn type_definitions(
 5725        &mut self,
 5726        buffer: &Entity<Buffer>,
 5727        position: PointUtf16,
 5728        cx: &mut Context<Self>,
 5729    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5730        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5731            let request = GetTypeDefinitions { position };
 5732            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5733                return Task::ready(Ok(None));
 5734            }
 5735            let request_task = upstream_client.request_lsp(
 5736                project_id,
 5737                None,
 5738                LSP_REQUEST_TIMEOUT,
 5739                cx.background_executor().clone(),
 5740                request.to_proto(project_id, buffer.read(cx)),
 5741            );
 5742            let buffer = buffer.clone();
 5743            cx.spawn(async move |weak_lsp_store, cx| {
 5744                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5745                    return Ok(None);
 5746                };
 5747                let Some(responses) = request_task.await? else {
 5748                    return Ok(None);
 5749                };
 5750                let actions = join_all(responses.payload.into_iter().map(|response| {
 5751                    GetTypeDefinitions { position }.response_from_proto(
 5752                        response.response,
 5753                        lsp_store.clone(),
 5754                        buffer.clone(),
 5755                        cx.clone(),
 5756                    )
 5757                }))
 5758                .await;
 5759
 5760                Ok(Some(
 5761                    actions
 5762                        .into_iter()
 5763                        .collect::<Result<Vec<Vec<_>>>>()?
 5764                        .into_iter()
 5765                        .flatten()
 5766                        .dedup()
 5767                        .collect(),
 5768                ))
 5769            })
 5770        } else {
 5771            let type_definitions_task = self.request_multiple_lsp_locally(
 5772                buffer,
 5773                Some(position),
 5774                GetTypeDefinitions { position },
 5775                cx,
 5776            );
 5777            cx.background_spawn(async move {
 5778                Ok(Some(
 5779                    type_definitions_task
 5780                        .await
 5781                        .into_iter()
 5782                        .flat_map(|(_, type_definitions)| type_definitions)
 5783                        .dedup()
 5784                        .collect(),
 5785                ))
 5786            })
 5787        }
 5788    }
 5789
 5790    pub fn implementations(
 5791        &mut self,
 5792        buffer: &Entity<Buffer>,
 5793        position: PointUtf16,
 5794        cx: &mut Context<Self>,
 5795    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5796        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5797            let request = GetImplementations { position };
 5798            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5799                return Task::ready(Ok(None));
 5800            }
 5801            let request_task = upstream_client.request_lsp(
 5802                project_id,
 5803                None,
 5804                LSP_REQUEST_TIMEOUT,
 5805                cx.background_executor().clone(),
 5806                request.to_proto(project_id, buffer.read(cx)),
 5807            );
 5808            let buffer = buffer.clone();
 5809            cx.spawn(async move |weak_lsp_store, cx| {
 5810                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5811                    return Ok(None);
 5812                };
 5813                let Some(responses) = request_task.await? else {
 5814                    return Ok(None);
 5815                };
 5816                let actions = join_all(responses.payload.into_iter().map(|response| {
 5817                    GetImplementations { position }.response_from_proto(
 5818                        response.response,
 5819                        lsp_store.clone(),
 5820                        buffer.clone(),
 5821                        cx.clone(),
 5822                    )
 5823                }))
 5824                .await;
 5825
 5826                Ok(Some(
 5827                    actions
 5828                        .into_iter()
 5829                        .collect::<Result<Vec<Vec<_>>>>()?
 5830                        .into_iter()
 5831                        .flatten()
 5832                        .dedup()
 5833                        .collect(),
 5834                ))
 5835            })
 5836        } else {
 5837            let implementations_task = self.request_multiple_lsp_locally(
 5838                buffer,
 5839                Some(position),
 5840                GetImplementations { position },
 5841                cx,
 5842            );
 5843            cx.background_spawn(async move {
 5844                Ok(Some(
 5845                    implementations_task
 5846                        .await
 5847                        .into_iter()
 5848                        .flat_map(|(_, implementations)| implementations)
 5849                        .dedup()
 5850                        .collect(),
 5851                ))
 5852            })
 5853        }
 5854    }
 5855
 5856    pub fn references(
 5857        &mut self,
 5858        buffer: &Entity<Buffer>,
 5859        position: PointUtf16,
 5860        cx: &mut Context<Self>,
 5861    ) -> Task<Result<Option<Vec<Location>>>> {
 5862        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5863            let request = GetReferences { position };
 5864            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5865                return Task::ready(Ok(None));
 5866            }
 5867
 5868            let request_task = upstream_client.request_lsp(
 5869                project_id,
 5870                None,
 5871                LSP_REQUEST_TIMEOUT,
 5872                cx.background_executor().clone(),
 5873                request.to_proto(project_id, buffer.read(cx)),
 5874            );
 5875            let buffer = buffer.clone();
 5876            cx.spawn(async move |weak_lsp_store, cx| {
 5877                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5878                    return Ok(None);
 5879                };
 5880                let Some(responses) = request_task.await? else {
 5881                    return Ok(None);
 5882                };
 5883
 5884                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5885                    GetReferences { position }.response_from_proto(
 5886                        lsp_response.response,
 5887                        lsp_store.clone(),
 5888                        buffer.clone(),
 5889                        cx.clone(),
 5890                    )
 5891                }))
 5892                .await
 5893                .into_iter()
 5894                .collect::<Result<Vec<Vec<_>>>>()?
 5895                .into_iter()
 5896                .flatten()
 5897                .dedup()
 5898                .collect();
 5899                Ok(Some(locations))
 5900            })
 5901        } else {
 5902            let references_task = self.request_multiple_lsp_locally(
 5903                buffer,
 5904                Some(position),
 5905                GetReferences { position },
 5906                cx,
 5907            );
 5908            cx.background_spawn(async move {
 5909                Ok(Some(
 5910                    references_task
 5911                        .await
 5912                        .into_iter()
 5913                        .flat_map(|(_, references)| references)
 5914                        .dedup()
 5915                        .collect(),
 5916                ))
 5917            })
 5918        }
 5919    }
 5920
 5921    pub fn code_actions(
 5922        &mut self,
 5923        buffer: &Entity<Buffer>,
 5924        range: Range<Anchor>,
 5925        kinds: Option<Vec<CodeActionKind>>,
 5926        cx: &mut Context<Self>,
 5927    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5928        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5929            let request = GetCodeActions {
 5930                range: range.clone(),
 5931                kinds: kinds.clone(),
 5932            };
 5933            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5934                return Task::ready(Ok(None));
 5935            }
 5936            let request_task = upstream_client.request_lsp(
 5937                project_id,
 5938                None,
 5939                LSP_REQUEST_TIMEOUT,
 5940                cx.background_executor().clone(),
 5941                request.to_proto(project_id, buffer.read(cx)),
 5942            );
 5943            let buffer = buffer.clone();
 5944            cx.spawn(async move |weak_lsp_store, cx| {
 5945                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5946                    return Ok(None);
 5947                };
 5948                let Some(responses) = request_task.await? else {
 5949                    return Ok(None);
 5950                };
 5951                let actions = join_all(responses.payload.into_iter().map(|response| {
 5952                    GetCodeActions {
 5953                        range: range.clone(),
 5954                        kinds: kinds.clone(),
 5955                    }
 5956                    .response_from_proto(
 5957                        response.response,
 5958                        lsp_store.clone(),
 5959                        buffer.clone(),
 5960                        cx.clone(),
 5961                    )
 5962                }))
 5963                .await;
 5964
 5965                Ok(Some(
 5966                    actions
 5967                        .into_iter()
 5968                        .collect::<Result<Vec<Vec<_>>>>()?
 5969                        .into_iter()
 5970                        .flatten()
 5971                        .collect(),
 5972                ))
 5973            })
 5974        } else {
 5975            let all_actions_task = self.request_multiple_lsp_locally(
 5976                buffer,
 5977                Some(range.start),
 5978                GetCodeActions { range, kinds },
 5979                cx,
 5980            );
 5981            cx.background_spawn(async move {
 5982                Ok(Some(
 5983                    all_actions_task
 5984                        .await
 5985                        .into_iter()
 5986                        .flat_map(|(_, actions)| actions)
 5987                        .collect(),
 5988                ))
 5989            })
 5990        }
 5991    }
 5992
 5993    pub fn code_lens_actions(
 5994        &mut self,
 5995        buffer: &Entity<Buffer>,
 5996        cx: &mut Context<Self>,
 5997    ) -> CodeLensTask {
 5998        let version_queried_for = buffer.read(cx).version();
 5999        let buffer_id = buffer.read(cx).remote_id();
 6000        let existing_servers = self.as_local().map(|local| {
 6001            local
 6002                .buffers_opened_in_servers
 6003                .get(&buffer_id)
 6004                .cloned()
 6005                .unwrap_or_default()
 6006        });
 6007
 6008        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 6009            if let Some(cached_lens) = &lsp_data.code_lens {
 6010                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 6011                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 6012                        existing_servers != cached_lens.lens.keys().copied().collect()
 6013                    });
 6014                    if !has_different_servers {
 6015                        return Task::ready(Ok(Some(
 6016                            cached_lens.lens.values().flatten().cloned().collect(),
 6017                        )))
 6018                        .shared();
 6019                    }
 6020                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 6021                    if !version_queried_for.changed_since(updating_for) {
 6022                        return running_update.clone();
 6023                    }
 6024                }
 6025            }
 6026        }
 6027
 6028        let lens_lsp_data = self
 6029            .latest_lsp_data(buffer, cx)
 6030            .code_lens
 6031            .get_or_insert_default();
 6032        let buffer = buffer.clone();
 6033        let query_version_queried_for = version_queried_for.clone();
 6034        let new_task = cx
 6035            .spawn(async move |lsp_store, cx| {
 6036                cx.background_executor()
 6037                    .timer(Duration::from_millis(30))
 6038                    .await;
 6039                let fetched_lens = lsp_store
 6040                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 6041                    .map_err(Arc::new)?
 6042                    .await
 6043                    .context("fetching code lens")
 6044                    .map_err(Arc::new);
 6045                let fetched_lens = match fetched_lens {
 6046                    Ok(fetched_lens) => fetched_lens,
 6047                    Err(e) => {
 6048                        lsp_store
 6049                            .update(cx, |lsp_store, _| {
 6050                                if let Some(lens_lsp_data) = lsp_store
 6051                                    .lsp_data
 6052                                    .get_mut(&buffer_id)
 6053                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 6054                                {
 6055                                    lens_lsp_data.update = None;
 6056                                }
 6057                            })
 6058                            .ok();
 6059                        return Err(e);
 6060                    }
 6061                };
 6062
 6063                lsp_store
 6064                    .update(cx, |lsp_store, _| {
 6065                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 6066                        let code_lens = lsp_data.code_lens.as_mut()?;
 6067                        if let Some(fetched_lens) = fetched_lens {
 6068                            if lsp_data.buffer_version == query_version_queried_for {
 6069                                code_lens.lens.extend(fetched_lens);
 6070                            } else if !lsp_data
 6071                                .buffer_version
 6072                                .changed_since(&query_version_queried_for)
 6073                            {
 6074                                lsp_data.buffer_version = query_version_queried_for;
 6075                                code_lens.lens = fetched_lens;
 6076                            }
 6077                        }
 6078                        code_lens.update = None;
 6079                        Some(code_lens.lens.values().flatten().cloned().collect())
 6080                    })
 6081                    .map_err(Arc::new)
 6082            })
 6083            .shared();
 6084        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 6085        new_task
 6086    }
 6087
 6088    fn fetch_code_lens(
 6089        &mut self,
 6090        buffer: &Entity<Buffer>,
 6091        cx: &mut Context<Self>,
 6092    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 6093        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6094            let request = GetCodeLens;
 6095            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6096                return Task::ready(Ok(None));
 6097            }
 6098            let request_task = upstream_client.request_lsp(
 6099                project_id,
 6100                None,
 6101                LSP_REQUEST_TIMEOUT,
 6102                cx.background_executor().clone(),
 6103                request.to_proto(project_id, buffer.read(cx)),
 6104            );
 6105            let buffer = buffer.clone();
 6106            cx.spawn(async move |weak_lsp_store, cx| {
 6107                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6108                    return Ok(None);
 6109                };
 6110                let Some(responses) = request_task.await? else {
 6111                    return Ok(None);
 6112                };
 6113
 6114                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 6115                    let lsp_store = lsp_store.clone();
 6116                    let buffer = buffer.clone();
 6117                    let cx = cx.clone();
 6118                    async move {
 6119                        (
 6120                            LanguageServerId::from_proto(response.server_id),
 6121                            GetCodeLens
 6122                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6123                                .await,
 6124                        )
 6125                    }
 6126                }))
 6127                .await;
 6128
 6129                let mut has_errors = false;
 6130                let code_lens_actions = code_lens_actions
 6131                    .into_iter()
 6132                    .filter_map(|(server_id, code_lens)| match code_lens {
 6133                        Ok(code_lens) => Some((server_id, code_lens)),
 6134                        Err(e) => {
 6135                            has_errors = true;
 6136                            log::error!("{e:#}");
 6137                            None
 6138                        }
 6139                    })
 6140                    .collect::<HashMap<_, _>>();
 6141                anyhow::ensure!(
 6142                    !has_errors || !code_lens_actions.is_empty(),
 6143                    "Failed to fetch code lens"
 6144                );
 6145                Ok(Some(code_lens_actions))
 6146            })
 6147        } else {
 6148            let code_lens_actions_task =
 6149                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 6150            cx.background_spawn(async move {
 6151                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 6152            })
 6153        }
 6154    }
 6155
 6156    #[inline(never)]
 6157    pub fn completions(
 6158        &self,
 6159        buffer: &Entity<Buffer>,
 6160        position: PointUtf16,
 6161        context: CompletionContext,
 6162        cx: &mut Context<Self>,
 6163    ) -> Task<Result<Vec<CompletionResponse>>> {
 6164        let language_registry = self.languages.clone();
 6165
 6166        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6167            let snapshot = buffer.read(cx).snapshot();
 6168            let offset = position.to_offset(&snapshot);
 6169            let scope = snapshot.language_scope_at(offset);
 6170            let capable_lsps = self.all_capable_for_proto_request(
 6171                buffer,
 6172                |server_name, capabilities| {
 6173                    capabilities.completion_provider.is_some()
 6174                        && scope
 6175                            .as_ref()
 6176                            .map(|scope| scope.language_allowed(server_name))
 6177                            .unwrap_or(true)
 6178                },
 6179                cx,
 6180            );
 6181            if capable_lsps.is_empty() {
 6182                return Task::ready(Ok(Vec::new()));
 6183            }
 6184
 6185            let language = buffer.read(cx).language().cloned();
 6186
 6187            // In the future, we should provide project guests with the names of LSP adapters,
 6188            // so that they can use the correct LSP adapter when computing labels. For now,
 6189            // guests just use the first LSP adapter associated with the buffer's language.
 6190            let lsp_adapter = language.as_ref().and_then(|language| {
 6191                language_registry
 6192                    .lsp_adapters(&language.name())
 6193                    .first()
 6194                    .cloned()
 6195            });
 6196
 6197            let buffer = buffer.clone();
 6198
 6199            cx.spawn(async move |this, cx| {
 6200                let requests = join_all(
 6201                    capable_lsps
 6202                        .into_iter()
 6203                        .map(|id| {
 6204                            let request = GetCompletions {
 6205                                position,
 6206                                context: context.clone(),
 6207                                server_id: Some(id),
 6208                            };
 6209                            let buffer = buffer.clone();
 6210                            let language = language.clone();
 6211                            let lsp_adapter = lsp_adapter.clone();
 6212                            let upstream_client = upstream_client.clone();
 6213                            let response = this
 6214                                .update(cx, |this, cx| {
 6215                                    this.send_lsp_proto_request(
 6216                                        buffer,
 6217                                        upstream_client,
 6218                                        project_id,
 6219                                        request,
 6220                                        cx,
 6221                                    )
 6222                                })
 6223                                .log_err();
 6224                            async move {
 6225                                let response = response?.await.log_err()?;
 6226
 6227                                let completions = populate_labels_for_completions(
 6228                                    response.completions,
 6229                                    language,
 6230                                    lsp_adapter,
 6231                                )
 6232                                .await;
 6233
 6234                                Some(CompletionResponse {
 6235                                    completions,
 6236                                    display_options: CompletionDisplayOptions::default(),
 6237                                    is_incomplete: response.is_incomplete,
 6238                                })
 6239                            }
 6240                        })
 6241                        .collect::<Vec<_>>(),
 6242                );
 6243                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6244            })
 6245        } else if let Some(local) = self.as_local() {
 6246            let snapshot = buffer.read(cx).snapshot();
 6247            let offset = position.to_offset(&snapshot);
 6248            let scope = snapshot.language_scope_at(offset);
 6249            let language = snapshot.language().cloned();
 6250            let completion_settings = language_settings(
 6251                language.as_ref().map(|language| language.name()),
 6252                buffer.read(cx).file(),
 6253                cx,
 6254            )
 6255            .completions
 6256            .clone();
 6257            if !completion_settings.lsp {
 6258                return Task::ready(Ok(Vec::new()));
 6259            }
 6260
 6261            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6262                local
 6263                    .language_servers_for_buffer(buffer, cx)
 6264                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6265                    .filter(|(adapter, _)| {
 6266                        scope
 6267                            .as_ref()
 6268                            .map(|scope| scope.language_allowed(&adapter.name))
 6269                            .unwrap_or(true)
 6270                    })
 6271                    .map(|(_, server)| server.server_id())
 6272                    .collect()
 6273            });
 6274
 6275            let buffer = buffer.clone();
 6276            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6277            let lsp_timeout = if lsp_timeout > 0 {
 6278                Some(Duration::from_millis(lsp_timeout))
 6279            } else {
 6280                None
 6281            };
 6282            cx.spawn(async move |this,  cx| {
 6283                let mut tasks = Vec::with_capacity(server_ids.len());
 6284                this.update(cx, |lsp_store, cx| {
 6285                    for server_id in server_ids {
 6286                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6287                        let lsp_timeout = lsp_timeout
 6288                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6289                        let mut timeout = cx.background_spawn(async move {
 6290                            match lsp_timeout {
 6291                                Some(lsp_timeout) => {
 6292                                    lsp_timeout.await;
 6293                                    true
 6294                                },
 6295                                None => false,
 6296                            }
 6297                        }).fuse();
 6298                        let mut lsp_request = lsp_store.request_lsp(
 6299                            buffer.clone(),
 6300                            LanguageServerToQuery::Other(server_id),
 6301                            GetCompletions {
 6302                                position,
 6303                                context: context.clone(),
 6304                                server_id: Some(server_id),
 6305                            },
 6306                            cx,
 6307                        ).fuse();
 6308                        let new_task = cx.background_spawn(async move {
 6309                            select_biased! {
 6310                                response = lsp_request => anyhow::Ok(Some(response?)),
 6311                                timeout_happened = timeout => {
 6312                                    if timeout_happened {
 6313                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6314                                        Ok(None)
 6315                                    } else {
 6316                                        let completions = lsp_request.await?;
 6317                                        Ok(Some(completions))
 6318                                    }
 6319                                },
 6320                            }
 6321                        });
 6322                        tasks.push((lsp_adapter, new_task));
 6323                    }
 6324                })?;
 6325
 6326                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6327                    let completion_response = task.await.ok()??;
 6328                    let completions = populate_labels_for_completions(
 6329                            completion_response.completions,
 6330                            language.clone(),
 6331                            lsp_adapter,
 6332                        )
 6333                        .await;
 6334                    Some(CompletionResponse {
 6335                        completions,
 6336                        display_options: CompletionDisplayOptions::default(),
 6337                        is_incomplete: completion_response.is_incomplete,
 6338                    })
 6339                });
 6340
 6341                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6342
 6343                Ok(responses.into_iter().flatten().collect())
 6344            })
 6345        } else {
 6346            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6347        }
 6348    }
 6349
 6350    pub fn resolve_completions(
 6351        &self,
 6352        buffer: Entity<Buffer>,
 6353        completion_indices: Vec<usize>,
 6354        completions: Rc<RefCell<Box<[Completion]>>>,
 6355        cx: &mut Context<Self>,
 6356    ) -> Task<Result<bool>> {
 6357        let client = self.upstream_client();
 6358        let buffer_id = buffer.read(cx).remote_id();
 6359        let buffer_snapshot = buffer.read(cx).snapshot();
 6360
 6361        if !self.check_if_capable_for_proto_request(
 6362            &buffer,
 6363            GetCompletions::can_resolve_completions,
 6364            cx,
 6365        ) {
 6366            return Task::ready(Ok(false));
 6367        }
 6368        cx.spawn(async move |lsp_store, cx| {
 6369            let mut did_resolve = false;
 6370            if let Some((client, project_id)) = client {
 6371                for completion_index in completion_indices {
 6372                    let server_id = {
 6373                        let completion = &completions.borrow()[completion_index];
 6374                        completion.source.server_id()
 6375                    };
 6376                    if let Some(server_id) = server_id {
 6377                        if Self::resolve_completion_remote(
 6378                            project_id,
 6379                            server_id,
 6380                            buffer_id,
 6381                            completions.clone(),
 6382                            completion_index,
 6383                            client.clone(),
 6384                        )
 6385                        .await
 6386                        .log_err()
 6387                        .is_some()
 6388                        {
 6389                            did_resolve = true;
 6390                        }
 6391                    } else {
 6392                        resolve_word_completion(
 6393                            &buffer_snapshot,
 6394                            &mut completions.borrow_mut()[completion_index],
 6395                        );
 6396                    }
 6397                }
 6398            } else {
 6399                for completion_index in completion_indices {
 6400                    let server_id = {
 6401                        let completion = &completions.borrow()[completion_index];
 6402                        completion.source.server_id()
 6403                    };
 6404                    if let Some(server_id) = server_id {
 6405                        let server_and_adapter = lsp_store
 6406                            .read_with(cx, |lsp_store, _| {
 6407                                let server = lsp_store.language_server_for_id(server_id)?;
 6408                                let adapter =
 6409                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6410                                Some((server, adapter))
 6411                            })
 6412                            .ok()
 6413                            .flatten();
 6414                        let Some((server, adapter)) = server_and_adapter else {
 6415                            continue;
 6416                        };
 6417
 6418                        let resolved = Self::resolve_completion_local(
 6419                            server,
 6420                            completions.clone(),
 6421                            completion_index,
 6422                        )
 6423                        .await
 6424                        .log_err()
 6425                        .is_some();
 6426                        if resolved {
 6427                            Self::regenerate_completion_labels(
 6428                                adapter,
 6429                                &buffer_snapshot,
 6430                                completions.clone(),
 6431                                completion_index,
 6432                            )
 6433                            .await
 6434                            .log_err();
 6435                            did_resolve = true;
 6436                        }
 6437                    } else {
 6438                        resolve_word_completion(
 6439                            &buffer_snapshot,
 6440                            &mut completions.borrow_mut()[completion_index],
 6441                        );
 6442                    }
 6443                }
 6444            }
 6445
 6446            Ok(did_resolve)
 6447        })
 6448    }
 6449
 6450    async fn resolve_completion_local(
 6451        server: Arc<lsp::LanguageServer>,
 6452        completions: Rc<RefCell<Box<[Completion]>>>,
 6453        completion_index: usize,
 6454    ) -> Result<()> {
 6455        let server_id = server.server_id();
 6456        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6457            return Ok(());
 6458        }
 6459
 6460        let request = {
 6461            let completion = &completions.borrow()[completion_index];
 6462            match &completion.source {
 6463                CompletionSource::Lsp {
 6464                    lsp_completion,
 6465                    resolved,
 6466                    server_id: completion_server_id,
 6467                    ..
 6468                } => {
 6469                    if *resolved {
 6470                        return Ok(());
 6471                    }
 6472                    anyhow::ensure!(
 6473                        server_id == *completion_server_id,
 6474                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6475                    );
 6476                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6477                }
 6478                CompletionSource::BufferWord { .. }
 6479                | CompletionSource::Dap { .. }
 6480                | CompletionSource::Custom => {
 6481                    return Ok(());
 6482                }
 6483            }
 6484        };
 6485        let resolved_completion = request
 6486            .await
 6487            .into_response()
 6488            .context("resolve completion")?;
 6489
 6490        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6491        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6492
 6493        let mut completions = completions.borrow_mut();
 6494        let completion = &mut completions[completion_index];
 6495        if let CompletionSource::Lsp {
 6496            lsp_completion,
 6497            resolved,
 6498            server_id: completion_server_id,
 6499            ..
 6500        } = &mut completion.source
 6501        {
 6502            if *resolved {
 6503                return Ok(());
 6504            }
 6505            anyhow::ensure!(
 6506                server_id == *completion_server_id,
 6507                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6508            );
 6509            **lsp_completion = resolved_completion;
 6510            *resolved = true;
 6511        }
 6512        Ok(())
 6513    }
 6514
 6515    async fn regenerate_completion_labels(
 6516        adapter: Arc<CachedLspAdapter>,
 6517        snapshot: &BufferSnapshot,
 6518        completions: Rc<RefCell<Box<[Completion]>>>,
 6519        completion_index: usize,
 6520    ) -> Result<()> {
 6521        let completion_item = completions.borrow()[completion_index]
 6522            .source
 6523            .lsp_completion(true)
 6524            .map(Cow::into_owned);
 6525        if let Some(lsp_documentation) = completion_item
 6526            .as_ref()
 6527            .and_then(|completion_item| completion_item.documentation.clone())
 6528        {
 6529            let mut completions = completions.borrow_mut();
 6530            let completion = &mut completions[completion_index];
 6531            completion.documentation = Some(lsp_documentation.into());
 6532        } else {
 6533            let mut completions = completions.borrow_mut();
 6534            let completion = &mut completions[completion_index];
 6535            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6536        }
 6537
 6538        let mut new_label = match completion_item {
 6539            Some(completion_item) => {
 6540                // Some language servers always return `detail` lazily via resolve, regardless of
 6541                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6542                // See: https://github.com/yioneko/vtsls/issues/213
 6543                let language = snapshot.language();
 6544                match language {
 6545                    Some(language) => {
 6546                        adapter
 6547                            .labels_for_completions(
 6548                                std::slice::from_ref(&completion_item),
 6549                                language,
 6550                            )
 6551                            .await?
 6552                    }
 6553                    None => Vec::new(),
 6554                }
 6555                .pop()
 6556                .flatten()
 6557                .unwrap_or_else(|| {
 6558                    CodeLabel::fallback_for_completion(
 6559                        &completion_item,
 6560                        language.map(|language| language.as_ref()),
 6561                    )
 6562                })
 6563            }
 6564            None => CodeLabel::plain(
 6565                completions.borrow()[completion_index].new_text.clone(),
 6566                None,
 6567            ),
 6568        };
 6569        ensure_uniform_list_compatible_label(&mut new_label);
 6570
 6571        let mut completions = completions.borrow_mut();
 6572        let completion = &mut completions[completion_index];
 6573        if completion.label.filter_text() == new_label.filter_text() {
 6574            completion.label = new_label;
 6575        } else {
 6576            log::error!(
 6577                "Resolved completion changed display label from {} to {}. \
 6578                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6579                completion.label.text(),
 6580                new_label.text(),
 6581                completion.label.filter_text(),
 6582                new_label.filter_text()
 6583            );
 6584        }
 6585
 6586        Ok(())
 6587    }
 6588
 6589    async fn resolve_completion_remote(
 6590        project_id: u64,
 6591        server_id: LanguageServerId,
 6592        buffer_id: BufferId,
 6593        completions: Rc<RefCell<Box<[Completion]>>>,
 6594        completion_index: usize,
 6595        client: AnyProtoClient,
 6596    ) -> Result<()> {
 6597        let lsp_completion = {
 6598            let completion = &completions.borrow()[completion_index];
 6599            match &completion.source {
 6600                CompletionSource::Lsp {
 6601                    lsp_completion,
 6602                    resolved,
 6603                    server_id: completion_server_id,
 6604                    ..
 6605                } => {
 6606                    anyhow::ensure!(
 6607                        server_id == *completion_server_id,
 6608                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6609                    );
 6610                    if *resolved {
 6611                        return Ok(());
 6612                    }
 6613                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6614                }
 6615                CompletionSource::Custom
 6616                | CompletionSource::Dap { .. }
 6617                | CompletionSource::BufferWord { .. } => {
 6618                    return Ok(());
 6619                }
 6620            }
 6621        };
 6622        let request = proto::ResolveCompletionDocumentation {
 6623            project_id,
 6624            language_server_id: server_id.0 as u64,
 6625            lsp_completion,
 6626            buffer_id: buffer_id.into(),
 6627        };
 6628
 6629        let response = client
 6630            .request(request)
 6631            .await
 6632            .context("completion documentation resolve proto request")?;
 6633        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6634
 6635        let documentation = if response.documentation.is_empty() {
 6636            CompletionDocumentation::Undocumented
 6637        } else if response.documentation_is_markdown {
 6638            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6639        } else if response.documentation.lines().count() <= 1 {
 6640            CompletionDocumentation::SingleLine(response.documentation.into())
 6641        } else {
 6642            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6643        };
 6644
 6645        let mut completions = completions.borrow_mut();
 6646        let completion = &mut completions[completion_index];
 6647        completion.documentation = Some(documentation);
 6648        if let CompletionSource::Lsp {
 6649            insert_range,
 6650            lsp_completion,
 6651            resolved,
 6652            server_id: completion_server_id,
 6653            lsp_defaults: _,
 6654        } = &mut completion.source
 6655        {
 6656            let completion_insert_range = response
 6657                .old_insert_start
 6658                .and_then(deserialize_anchor)
 6659                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6660            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6661
 6662            if *resolved {
 6663                return Ok(());
 6664            }
 6665            anyhow::ensure!(
 6666                server_id == *completion_server_id,
 6667                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6668            );
 6669            **lsp_completion = resolved_lsp_completion;
 6670            *resolved = true;
 6671        }
 6672
 6673        let replace_range = response
 6674            .old_replace_start
 6675            .and_then(deserialize_anchor)
 6676            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6677        if let Some((old_replace_start, old_replace_end)) = replace_range
 6678            && !response.new_text.is_empty()
 6679        {
 6680            completion.new_text = response.new_text;
 6681            completion.replace_range = old_replace_start..old_replace_end;
 6682        }
 6683
 6684        Ok(())
 6685    }
 6686
 6687    pub fn apply_additional_edits_for_completion(
 6688        &self,
 6689        buffer_handle: Entity<Buffer>,
 6690        completions: Rc<RefCell<Box<[Completion]>>>,
 6691        completion_index: usize,
 6692        push_to_history: bool,
 6693        cx: &mut Context<Self>,
 6694    ) -> Task<Result<Option<Transaction>>> {
 6695        if let Some((client, project_id)) = self.upstream_client() {
 6696            let buffer = buffer_handle.read(cx);
 6697            let buffer_id = buffer.remote_id();
 6698            cx.spawn(async move |_, cx| {
 6699                let request = {
 6700                    let completion = completions.borrow()[completion_index].clone();
 6701                    proto::ApplyCompletionAdditionalEdits {
 6702                        project_id,
 6703                        buffer_id: buffer_id.into(),
 6704                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6705                            replace_range: completion.replace_range,
 6706                            new_text: completion.new_text,
 6707                            source: completion.source,
 6708                        })),
 6709                    }
 6710                };
 6711
 6712                if let Some(transaction) = client.request(request).await?.transaction {
 6713                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6714                    buffer_handle
 6715                        .update(cx, |buffer, _| {
 6716                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6717                        })?
 6718                        .await?;
 6719                    if push_to_history {
 6720                        buffer_handle.update(cx, |buffer, _| {
 6721                            buffer.push_transaction(transaction.clone(), Instant::now());
 6722                            buffer.finalize_last_transaction();
 6723                        })?;
 6724                    }
 6725                    Ok(Some(transaction))
 6726                } else {
 6727                    Ok(None)
 6728                }
 6729            })
 6730        } else {
 6731            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6732                let completion = &completions.borrow()[completion_index];
 6733                let server_id = completion.source.server_id()?;
 6734                Some(
 6735                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6736                        .1
 6737                        .clone(),
 6738                )
 6739            }) else {
 6740                return Task::ready(Ok(None));
 6741            };
 6742
 6743            cx.spawn(async move |this, cx| {
 6744                Self::resolve_completion_local(
 6745                    server.clone(),
 6746                    completions.clone(),
 6747                    completion_index,
 6748                )
 6749                .await
 6750                .context("resolving completion")?;
 6751                let completion = completions.borrow()[completion_index].clone();
 6752                let additional_text_edits = completion
 6753                    .source
 6754                    .lsp_completion(true)
 6755                    .as_ref()
 6756                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6757                if let Some(edits) = additional_text_edits {
 6758                    let edits = this
 6759                        .update(cx, |this, cx| {
 6760                            this.as_local_mut().unwrap().edits_from_lsp(
 6761                                &buffer_handle,
 6762                                edits,
 6763                                server.server_id(),
 6764                                None,
 6765                                cx,
 6766                            )
 6767                        })?
 6768                        .await?;
 6769
 6770                    buffer_handle.update(cx, |buffer, cx| {
 6771                        buffer.finalize_last_transaction();
 6772                        buffer.start_transaction();
 6773
 6774                        for (range, text) in edits {
 6775                            let primary = &completion.replace_range;
 6776
 6777                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6778                            // and the primary completion is just an insertion (empty range), then this is likely
 6779                            // an auto-import scenario and should not be considered overlapping
 6780                            // https://github.com/zed-industries/zed/issues/26136
 6781                            let is_file_start_auto_import = {
 6782                                let snapshot = buffer.snapshot();
 6783                                let primary_start_point = primary.start.to_point(&snapshot);
 6784                                let range_start_point = range.start.to_point(&snapshot);
 6785
 6786                                let result = primary_start_point.row == 0
 6787                                    && primary_start_point.column == 0
 6788                                    && range_start_point.row == 0
 6789                                    && range_start_point.column == 0;
 6790
 6791                                result
 6792                            };
 6793
 6794                            let has_overlap = if is_file_start_auto_import {
 6795                                false
 6796                            } else {
 6797                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6798                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6799                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6800                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6801                                let result = start_within || end_within;
 6802                                result
 6803                            };
 6804
 6805                            //Skip additional edits which overlap with the primary completion edit
 6806                            //https://github.com/zed-industries/zed/pull/1871
 6807                            if !has_overlap {
 6808                                buffer.edit([(range, text)], None, cx);
 6809                            }
 6810                        }
 6811
 6812                        let transaction = if buffer.end_transaction(cx).is_some() {
 6813                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6814                            if !push_to_history {
 6815                                buffer.forget_transaction(transaction.id);
 6816                            }
 6817                            Some(transaction)
 6818                        } else {
 6819                            None
 6820                        };
 6821                        Ok(transaction)
 6822                    })?
 6823                } else {
 6824                    Ok(None)
 6825                }
 6826            })
 6827        }
 6828    }
 6829
 6830    pub fn pull_diagnostics(
 6831        &mut self,
 6832        buffer: Entity<Buffer>,
 6833        cx: &mut Context<Self>,
 6834    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6835        let buffer_id = buffer.read(cx).remote_id();
 6836
 6837        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6838            let mut suitable_capabilities = None;
 6839            // Are we capable for proto request?
 6840            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6841                &buffer,
 6842                |capabilities| {
 6843                    if let Some(caps) = &capabilities.diagnostic_provider {
 6844                        suitable_capabilities = Some(caps.clone());
 6845                        true
 6846                    } else {
 6847                        false
 6848                    }
 6849                },
 6850                cx,
 6851            );
 6852            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6853            let Some(dynamic_caps) = suitable_capabilities else {
 6854                return Task::ready(Ok(None));
 6855            };
 6856            assert!(any_server_has_diagnostics_provider);
 6857
 6858            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6859            let request = GetDocumentDiagnostics {
 6860                previous_result_id: None,
 6861                identifier,
 6862                registration_id: None,
 6863            };
 6864            let request_task = client.request_lsp(
 6865                upstream_project_id,
 6866                None,
 6867                LSP_REQUEST_TIMEOUT,
 6868                cx.background_executor().clone(),
 6869                request.to_proto(upstream_project_id, buffer.read(cx)),
 6870            );
 6871            cx.background_spawn(async move {
 6872                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6873                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6874                // Do not attempt to further process the dummy responses here.
 6875                let _response = request_task.await?;
 6876                Ok(None)
 6877            })
 6878        } else {
 6879            let servers = buffer.update(cx, |buffer, cx| {
 6880                self.running_language_servers_for_local_buffer(buffer, cx)
 6881                    .map(|(_, server)| server.clone())
 6882                    .collect::<Vec<_>>()
 6883            });
 6884
 6885            let pull_diagnostics = servers
 6886                .into_iter()
 6887                .flat_map(|server| {
 6888                    let result = maybe!({
 6889                        let local = self.as_local()?;
 6890                        let server_id = server.server_id();
 6891                        let providers_with_identifiers = local
 6892                            .language_server_dynamic_registrations
 6893                            .get(&server_id)
 6894                            .into_iter()
 6895                            .flat_map(|registrations| registrations.diagnostics.clone())
 6896                            .collect::<Vec<_>>();
 6897                        Some(
 6898                            providers_with_identifiers
 6899                                .into_iter()
 6900                                .map(|(registration_id, dynamic_caps)| {
 6901                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6902                                    let registration_id = registration_id.map(SharedString::from);
 6903                                    let result_id = self.result_id_for_buffer_pull(
 6904                                        server_id,
 6905                                        buffer_id,
 6906                                        &registration_id,
 6907                                        cx,
 6908                                    );
 6909                                    self.request_lsp(
 6910                                        buffer.clone(),
 6911                                        LanguageServerToQuery::Other(server_id),
 6912                                        GetDocumentDiagnostics {
 6913                                            previous_result_id: result_id,
 6914                                            registration_id,
 6915                                            identifier,
 6916                                        },
 6917                                        cx,
 6918                                    )
 6919                                })
 6920                                .collect::<Vec<_>>(),
 6921                        )
 6922                    });
 6923
 6924                    result.unwrap_or_default()
 6925                })
 6926                .collect::<Vec<_>>();
 6927
 6928            cx.background_spawn(async move {
 6929                let mut responses = Vec::new();
 6930                for diagnostics in join_all(pull_diagnostics).await {
 6931                    responses.extend(diagnostics?);
 6932                }
 6933                Ok(Some(responses))
 6934            })
 6935        }
 6936    }
 6937
 6938    pub fn applicable_inlay_chunks(
 6939        &mut self,
 6940        buffer: &Entity<Buffer>,
 6941        ranges: &[Range<text::Anchor>],
 6942        cx: &mut Context<Self>,
 6943    ) -> Vec<Range<BufferRow>> {
 6944        let buffer_snapshot = buffer.read(cx).snapshot();
 6945        let ranges = ranges
 6946            .iter()
 6947            .map(|range| range.to_point(&buffer_snapshot))
 6948            .collect::<Vec<_>>();
 6949
 6950        self.latest_lsp_data(buffer, cx)
 6951            .inlay_hints
 6952            .applicable_chunks(ranges.as_slice())
 6953            .map(|chunk| chunk.row_range())
 6954            .collect()
 6955    }
 6956
 6957    pub fn invalidate_inlay_hints<'a>(
 6958        &'a mut self,
 6959        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6960    ) {
 6961        for buffer_id in for_buffers {
 6962            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6963                lsp_data.inlay_hints.clear();
 6964            }
 6965        }
 6966    }
 6967
 6968    pub fn inlay_hints(
 6969        &mut self,
 6970        invalidate: InvalidationStrategy,
 6971        buffer: Entity<Buffer>,
 6972        ranges: Vec<Range<text::Anchor>>,
 6973        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6974        cx: &mut Context<Self>,
 6975    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6976        let next_hint_id = self.next_hint_id.clone();
 6977        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6978        let query_version = lsp_data.buffer_version.clone();
 6979        let mut lsp_refresh_requested = false;
 6980        let for_server = if let InvalidationStrategy::RefreshRequested {
 6981            server_id,
 6982            request_id,
 6983        } = invalidate
 6984        {
 6985            let invalidated = lsp_data
 6986                .inlay_hints
 6987                .invalidate_for_server_refresh(server_id, request_id);
 6988            lsp_refresh_requested = invalidated;
 6989            Some(server_id)
 6990        } else {
 6991            None
 6992        };
 6993        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6994        let known_chunks = known_chunks
 6995            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6996            .map(|(_, known_chunks)| known_chunks)
 6997            .unwrap_or_default();
 6998
 6999        let buffer_snapshot = buffer.read(cx).snapshot();
 7000        let ranges = ranges
 7001            .iter()
 7002            .map(|range| range.to_point(&buffer_snapshot))
 7003            .collect::<Vec<_>>();
 7004
 7005        let mut hint_fetch_tasks = Vec::new();
 7006        let mut cached_inlay_hints = None;
 7007        let mut ranges_to_query = None;
 7008        let applicable_chunks = existing_inlay_hints
 7009            .applicable_chunks(ranges.as_slice())
 7010            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7011            .collect::<Vec<_>>();
 7012        if applicable_chunks.is_empty() {
 7013            return HashMap::default();
 7014        }
 7015
 7016        for row_chunk in applicable_chunks {
 7017            match (
 7018                existing_inlay_hints
 7019                    .cached_hints(&row_chunk)
 7020                    .filter(|_| !lsp_refresh_requested)
 7021                    .cloned(),
 7022                existing_inlay_hints
 7023                    .fetched_hints(&row_chunk)
 7024                    .as_ref()
 7025                    .filter(|_| !lsp_refresh_requested)
 7026                    .cloned(),
 7027            ) {
 7028                (None, None) => {
 7029                    let chunk_range = row_chunk.anchor_range();
 7030                    ranges_to_query
 7031                        .get_or_insert_with(Vec::new)
 7032                        .push((row_chunk, chunk_range));
 7033                }
 7034                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7035                (Some(cached_hints), None) => {
 7036                    for (server_id, cached_hints) in cached_hints {
 7037                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7038                            cached_inlay_hints
 7039                                .get_or_insert_with(HashMap::default)
 7040                                .entry(row_chunk.row_range())
 7041                                .or_insert_with(HashMap::default)
 7042                                .entry(server_id)
 7043                                .or_insert_with(Vec::new)
 7044                                .extend(cached_hints);
 7045                        }
 7046                    }
 7047                }
 7048                (Some(cached_hints), Some(fetched_hints)) => {
 7049                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7050                    for (server_id, cached_hints) in cached_hints {
 7051                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7052                            cached_inlay_hints
 7053                                .get_or_insert_with(HashMap::default)
 7054                                .entry(row_chunk.row_range())
 7055                                .or_insert_with(HashMap::default)
 7056                                .entry(server_id)
 7057                                .or_insert_with(Vec::new)
 7058                                .extend(cached_hints);
 7059                        }
 7060                    }
 7061                }
 7062            }
 7063        }
 7064
 7065        if hint_fetch_tasks.is_empty()
 7066            && ranges_to_query
 7067                .as_ref()
 7068                .is_none_or(|ranges| ranges.is_empty())
 7069            && let Some(cached_inlay_hints) = cached_inlay_hints
 7070        {
 7071            cached_inlay_hints
 7072                .into_iter()
 7073                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7074                .collect()
 7075        } else {
 7076            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7077                let next_hint_id = next_hint_id.clone();
 7078                let buffer = buffer.clone();
 7079                let query_version = query_version.clone();
 7080                let new_inlay_hints = cx
 7081                    .spawn(async move |lsp_store, cx| {
 7082                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7083                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7084                        })?;
 7085                        new_fetch_task
 7086                            .await
 7087                            .and_then(|new_hints_by_server| {
 7088                                lsp_store.update(cx, |lsp_store, cx| {
 7089                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7090                                    let update_cache = lsp_data.buffer_version == query_version;
 7091                                    if new_hints_by_server.is_empty() {
 7092                                        if update_cache {
 7093                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7094                                        }
 7095                                        HashMap::default()
 7096                                    } else {
 7097                                        new_hints_by_server
 7098                                            .into_iter()
 7099                                            .map(|(server_id, new_hints)| {
 7100                                                let new_hints = new_hints
 7101                                                    .into_iter()
 7102                                                    .map(|new_hint| {
 7103                                                        (
 7104                                                            InlayId::Hint(next_hint_id.fetch_add(
 7105                                                                1,
 7106                                                                atomic::Ordering::AcqRel,
 7107                                                            )),
 7108                                                            new_hint,
 7109                                                        )
 7110                                                    })
 7111                                                    .collect::<Vec<_>>();
 7112                                                if update_cache {
 7113                                                    lsp_data.inlay_hints.insert_new_hints(
 7114                                                        chunk,
 7115                                                        server_id,
 7116                                                        new_hints.clone(),
 7117                                                    );
 7118                                                }
 7119                                                (server_id, new_hints)
 7120                                            })
 7121                                            .collect()
 7122                                    }
 7123                                })
 7124                            })
 7125                            .map_err(Arc::new)
 7126                    })
 7127                    .shared();
 7128
 7129                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7130                *fetch_task = Some(new_inlay_hints.clone());
 7131                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7132            }
 7133
 7134            cached_inlay_hints
 7135                .unwrap_or_default()
 7136                .into_iter()
 7137                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7138                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7139                    (
 7140                        chunk.row_range(),
 7141                        cx.spawn(async move |_, _| {
 7142                            hints_fetch.await.map_err(|e| {
 7143                                if e.error_code() != ErrorCode::Internal {
 7144                                    anyhow!(e.error_code())
 7145                                } else {
 7146                                    anyhow!("{e:#}")
 7147                                }
 7148                            })
 7149                        }),
 7150                    )
 7151                }))
 7152                .collect()
 7153        }
 7154    }
 7155
 7156    fn fetch_inlay_hints(
 7157        &mut self,
 7158        for_server: Option<LanguageServerId>,
 7159        buffer: &Entity<Buffer>,
 7160        range: Range<Anchor>,
 7161        cx: &mut Context<Self>,
 7162    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7163        let request = InlayHints {
 7164            range: range.clone(),
 7165        };
 7166        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7167            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7168                return Task::ready(Ok(HashMap::default()));
 7169            }
 7170            let request_task = upstream_client.request_lsp(
 7171                project_id,
 7172                for_server.map(|id| id.to_proto()),
 7173                LSP_REQUEST_TIMEOUT,
 7174                cx.background_executor().clone(),
 7175                request.to_proto(project_id, buffer.read(cx)),
 7176            );
 7177            let buffer = buffer.clone();
 7178            cx.spawn(async move |weak_lsp_store, cx| {
 7179                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7180                    return Ok(HashMap::default());
 7181                };
 7182                let Some(responses) = request_task.await? else {
 7183                    return Ok(HashMap::default());
 7184                };
 7185
 7186                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7187                    let lsp_store = lsp_store.clone();
 7188                    let buffer = buffer.clone();
 7189                    let cx = cx.clone();
 7190                    let request = request.clone();
 7191                    async move {
 7192                        (
 7193                            LanguageServerId::from_proto(response.server_id),
 7194                            request
 7195                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7196                                .await,
 7197                        )
 7198                    }
 7199                }))
 7200                .await;
 7201
 7202                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot())?;
 7203                let mut has_errors = false;
 7204                let inlay_hints = inlay_hints
 7205                    .into_iter()
 7206                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7207                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7208                        Err(e) => {
 7209                            has_errors = true;
 7210                            log::error!("{e:#}");
 7211                            None
 7212                        }
 7213                    })
 7214                    .map(|(server_id, mut new_hints)| {
 7215                        new_hints.retain(|hint| {
 7216                            hint.position.is_valid(&buffer_snapshot)
 7217                                && range.start.is_valid(&buffer_snapshot)
 7218                                && range.end.is_valid(&buffer_snapshot)
 7219                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7220                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7221                        });
 7222                        (server_id, new_hints)
 7223                    })
 7224                    .collect::<HashMap<_, _>>();
 7225                anyhow::ensure!(
 7226                    !has_errors || !inlay_hints.is_empty(),
 7227                    "Failed to fetch inlay hints"
 7228                );
 7229                Ok(inlay_hints)
 7230            })
 7231        } else {
 7232            let inlay_hints_task = match for_server {
 7233                Some(server_id) => {
 7234                    let server_task = self.request_lsp(
 7235                        buffer.clone(),
 7236                        LanguageServerToQuery::Other(server_id),
 7237                        request,
 7238                        cx,
 7239                    );
 7240                    cx.background_spawn(async move {
 7241                        let mut responses = Vec::new();
 7242                        match server_task.await {
 7243                            Ok(response) => responses.push((server_id, response)),
 7244                            // rust-analyzer likes to error with this when its still loading up
 7245                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7246                            Err(e) => log::error!(
 7247                                "Error handling response for inlay hints request: {e:#}"
 7248                            ),
 7249                        }
 7250                        responses
 7251                    })
 7252                }
 7253                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7254            };
 7255            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7256            cx.background_spawn(async move {
 7257                Ok(inlay_hints_task
 7258                    .await
 7259                    .into_iter()
 7260                    .map(|(server_id, mut new_hints)| {
 7261                        new_hints.retain(|hint| {
 7262                            hint.position.is_valid(&buffer_snapshot)
 7263                                && range.start.is_valid(&buffer_snapshot)
 7264                                && range.end.is_valid(&buffer_snapshot)
 7265                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7266                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7267                        });
 7268                        (server_id, new_hints)
 7269                    })
 7270                    .collect())
 7271            })
 7272        }
 7273    }
 7274
 7275    fn diagnostic_registration_exists(
 7276        &self,
 7277        server_id: LanguageServerId,
 7278        registration_id: &Option<SharedString>,
 7279    ) -> bool {
 7280        let Some(local) = self.as_local() else {
 7281            return false;
 7282        };
 7283        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7284        else {
 7285            return false;
 7286        };
 7287        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7288        registrations.diagnostics.contains_key(&registration_key)
 7289    }
 7290
 7291    pub fn pull_diagnostics_for_buffer(
 7292        &mut self,
 7293        buffer: Entity<Buffer>,
 7294        cx: &mut Context<Self>,
 7295    ) -> Task<anyhow::Result<()>> {
 7296        let diagnostics = self.pull_diagnostics(buffer, cx);
 7297        cx.spawn(async move |lsp_store, cx| {
 7298            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7299                return Ok(());
 7300            };
 7301            lsp_store.update(cx, |lsp_store, cx| {
 7302                if lsp_store.as_local().is_none() {
 7303                    return;
 7304                }
 7305
 7306                let mut unchanged_buffers = HashMap::default();
 7307                let server_diagnostics_updates = diagnostics
 7308                    .into_iter()
 7309                    .filter_map(|diagnostics_set| match diagnostics_set {
 7310                        LspPullDiagnostics::Response {
 7311                            server_id,
 7312                            uri,
 7313                            diagnostics,
 7314                            registration_id,
 7315                        } => Some((server_id, uri, diagnostics, registration_id)),
 7316                        LspPullDiagnostics::Default => None,
 7317                    })
 7318                    .filter(|(server_id, _, _, registration_id)| {
 7319                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7320                    })
 7321                    .fold(
 7322                        HashMap::default(),
 7323                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7324                            let (result_id, diagnostics) = match diagnostics {
 7325                                PulledDiagnostics::Unchanged { result_id } => {
 7326                                    unchanged_buffers
 7327                                        .entry(new_registration_id.clone())
 7328                                        .or_insert_with(HashSet::default)
 7329                                        .insert(uri.clone());
 7330                                    (Some(result_id), Vec::new())
 7331                                }
 7332                                PulledDiagnostics::Changed {
 7333                                    result_id,
 7334                                    diagnostics,
 7335                                } => (result_id, diagnostics),
 7336                            };
 7337                            let disk_based_sources = Cow::Owned(
 7338                                lsp_store
 7339                                    .language_server_adapter_for_id(server_id)
 7340                                    .as_ref()
 7341                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7342                                    .unwrap_or(&[])
 7343                                    .to_vec(),
 7344                            );
 7345                            acc.entry(server_id)
 7346                                .or_insert_with(HashMap::default)
 7347                                .entry(new_registration_id.clone())
 7348                                .or_insert_with(Vec::new)
 7349                                .push(DocumentDiagnosticsUpdate {
 7350                                    server_id,
 7351                                    diagnostics: lsp::PublishDiagnosticsParams {
 7352                                        uri,
 7353                                        diagnostics,
 7354                                        version: None,
 7355                                    },
 7356                                    result_id,
 7357                                    disk_based_sources,
 7358                                    registration_id: new_registration_id,
 7359                                });
 7360                            acc
 7361                        },
 7362                    );
 7363
 7364                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7365                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7366                        lsp_store
 7367                            .merge_lsp_diagnostics(
 7368                                DiagnosticSourceKind::Pulled,
 7369                                diagnostic_updates,
 7370                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7371                                    DiagnosticSourceKind::Pulled => {
 7372                                        old_diagnostic.registration_id != registration_id
 7373                                            || unchanged_buffers
 7374                                                .get(&old_diagnostic.registration_id)
 7375                                                .is_some_and(|unchanged_buffers| {
 7376                                                    unchanged_buffers.contains(&document_uri)
 7377                                                })
 7378                                    }
 7379                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7380                                        true
 7381                                    }
 7382                                },
 7383                                cx,
 7384                            )
 7385                            .log_err();
 7386                    }
 7387                }
 7388            })
 7389        })
 7390    }
 7391
 7392    pub fn document_colors(
 7393        &mut self,
 7394        known_cache_version: Option<usize>,
 7395        buffer: Entity<Buffer>,
 7396        cx: &mut Context<Self>,
 7397    ) -> Option<DocumentColorTask> {
 7398        let version_queried_for = buffer.read(cx).version();
 7399        let buffer_id = buffer.read(cx).remote_id();
 7400
 7401        let current_language_servers = self.as_local().map(|local| {
 7402            local
 7403                .buffers_opened_in_servers
 7404                .get(&buffer_id)
 7405                .cloned()
 7406                .unwrap_or_default()
 7407        });
 7408
 7409        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7410            if let Some(cached_colors) = &lsp_data.document_colors {
 7411                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7412                    let has_different_servers =
 7413                        current_language_servers.is_some_and(|current_language_servers| {
 7414                            current_language_servers
 7415                                != cached_colors.colors.keys().copied().collect()
 7416                        });
 7417                    if !has_different_servers {
 7418                        let cache_version = cached_colors.cache_version;
 7419                        if Some(cache_version) == known_cache_version {
 7420                            return None;
 7421                        } else {
 7422                            return Some(
 7423                                Task::ready(Ok(DocumentColors {
 7424                                    colors: cached_colors
 7425                                        .colors
 7426                                        .values()
 7427                                        .flatten()
 7428                                        .cloned()
 7429                                        .collect(),
 7430                                    cache_version: Some(cache_version),
 7431                                }))
 7432                                .shared(),
 7433                            );
 7434                        }
 7435                    }
 7436                }
 7437            }
 7438        }
 7439
 7440        let color_lsp_data = self
 7441            .latest_lsp_data(&buffer, cx)
 7442            .document_colors
 7443            .get_or_insert_default();
 7444        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7445            && !version_queried_for.changed_since(updating_for)
 7446        {
 7447            return Some(running_update.clone());
 7448        }
 7449        let buffer_version_queried_for = version_queried_for.clone();
 7450        let new_task = cx
 7451            .spawn(async move |lsp_store, cx| {
 7452                cx.background_executor()
 7453                    .timer(Duration::from_millis(30))
 7454                    .await;
 7455                let fetched_colors = lsp_store
 7456                    .update(cx, |lsp_store, cx| {
 7457                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7458                    })?
 7459                    .await
 7460                    .context("fetching document colors")
 7461                    .map_err(Arc::new);
 7462                let fetched_colors = match fetched_colors {
 7463                    Ok(fetched_colors) => {
 7464                        if Some(true)
 7465                            == buffer
 7466                                .update(cx, |buffer, _| {
 7467                                    buffer.version() != buffer_version_queried_for
 7468                                })
 7469                                .ok()
 7470                        {
 7471                            return Ok(DocumentColors::default());
 7472                        }
 7473                        fetched_colors
 7474                    }
 7475                    Err(e) => {
 7476                        lsp_store
 7477                            .update(cx, |lsp_store, _| {
 7478                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7479                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7480                                        document_colors.colors_update = None;
 7481                                    }
 7482                                }
 7483                            })
 7484                            .ok();
 7485                        return Err(e);
 7486                    }
 7487                };
 7488
 7489                lsp_store
 7490                    .update(cx, |lsp_store, cx| {
 7491                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7492                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7493
 7494                        if let Some(fetched_colors) = fetched_colors {
 7495                            if lsp_data.buffer_version == buffer_version_queried_for {
 7496                                lsp_colors.colors.extend(fetched_colors);
 7497                                lsp_colors.cache_version += 1;
 7498                            } else if !lsp_data
 7499                                .buffer_version
 7500                                .changed_since(&buffer_version_queried_for)
 7501                            {
 7502                                lsp_data.buffer_version = buffer_version_queried_for;
 7503                                lsp_colors.colors = fetched_colors;
 7504                                lsp_colors.cache_version += 1;
 7505                            }
 7506                        }
 7507                        lsp_colors.colors_update = None;
 7508                        let colors = lsp_colors
 7509                            .colors
 7510                            .values()
 7511                            .flatten()
 7512                            .cloned()
 7513                            .collect::<HashSet<_>>();
 7514                        DocumentColors {
 7515                            colors,
 7516                            cache_version: Some(lsp_colors.cache_version),
 7517                        }
 7518                    })
 7519                    .map_err(Arc::new)
 7520            })
 7521            .shared();
 7522        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7523        Some(new_task)
 7524    }
 7525
 7526    fn fetch_document_colors_for_buffer(
 7527        &mut self,
 7528        buffer: &Entity<Buffer>,
 7529        cx: &mut Context<Self>,
 7530    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7531        if let Some((client, project_id)) = self.upstream_client() {
 7532            let request = GetDocumentColor {};
 7533            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7534                return Task::ready(Ok(None));
 7535            }
 7536
 7537            let request_task = client.request_lsp(
 7538                project_id,
 7539                None,
 7540                LSP_REQUEST_TIMEOUT,
 7541                cx.background_executor().clone(),
 7542                request.to_proto(project_id, buffer.read(cx)),
 7543            );
 7544            let buffer = buffer.clone();
 7545            cx.spawn(async move |lsp_store, cx| {
 7546                let Some(lsp_store) = lsp_store.upgrade() else {
 7547                    return Ok(None);
 7548                };
 7549                let colors = join_all(
 7550                    request_task
 7551                        .await
 7552                        .log_err()
 7553                        .flatten()
 7554                        .map(|response| response.payload)
 7555                        .unwrap_or_default()
 7556                        .into_iter()
 7557                        .map(|color_response| {
 7558                            let response = request.response_from_proto(
 7559                                color_response.response,
 7560                                lsp_store.clone(),
 7561                                buffer.clone(),
 7562                                cx.clone(),
 7563                            );
 7564                            async move {
 7565                                (
 7566                                    LanguageServerId::from_proto(color_response.server_id),
 7567                                    response.await.log_err().unwrap_or_default(),
 7568                                )
 7569                            }
 7570                        }),
 7571                )
 7572                .await
 7573                .into_iter()
 7574                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7575                    acc.entry(server_id)
 7576                        .or_insert_with(HashSet::default)
 7577                        .extend(colors);
 7578                    acc
 7579                });
 7580                Ok(Some(colors))
 7581            })
 7582        } else {
 7583            let document_colors_task =
 7584                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7585            cx.background_spawn(async move {
 7586                Ok(Some(
 7587                    document_colors_task
 7588                        .await
 7589                        .into_iter()
 7590                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7591                            acc.entry(server_id)
 7592                                .or_insert_with(HashSet::default)
 7593                                .extend(colors);
 7594                            acc
 7595                        })
 7596                        .into_iter()
 7597                        .collect(),
 7598                ))
 7599            })
 7600        }
 7601    }
 7602
 7603    pub fn signature_help<T: ToPointUtf16>(
 7604        &mut self,
 7605        buffer: &Entity<Buffer>,
 7606        position: T,
 7607        cx: &mut Context<Self>,
 7608    ) -> Task<Option<Vec<SignatureHelp>>> {
 7609        let position = position.to_point_utf16(buffer.read(cx));
 7610
 7611        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7612            let request = GetSignatureHelp { position };
 7613            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7614                return Task::ready(None);
 7615            }
 7616            let request_task = client.request_lsp(
 7617                upstream_project_id,
 7618                None,
 7619                LSP_REQUEST_TIMEOUT,
 7620                cx.background_executor().clone(),
 7621                request.to_proto(upstream_project_id, buffer.read(cx)),
 7622            );
 7623            let buffer = buffer.clone();
 7624            cx.spawn(async move |weak_lsp_store, cx| {
 7625                let lsp_store = weak_lsp_store.upgrade()?;
 7626                let signatures = join_all(
 7627                    request_task
 7628                        .await
 7629                        .log_err()
 7630                        .flatten()
 7631                        .map(|response| response.payload)
 7632                        .unwrap_or_default()
 7633                        .into_iter()
 7634                        .map(|response| {
 7635                            let response = GetSignatureHelp { position }.response_from_proto(
 7636                                response.response,
 7637                                lsp_store.clone(),
 7638                                buffer.clone(),
 7639                                cx.clone(),
 7640                            );
 7641                            async move { response.await.log_err().flatten() }
 7642                        }),
 7643                )
 7644                .await
 7645                .into_iter()
 7646                .flatten()
 7647                .collect();
 7648                Some(signatures)
 7649            })
 7650        } else {
 7651            let all_actions_task = self.request_multiple_lsp_locally(
 7652                buffer,
 7653                Some(position),
 7654                GetSignatureHelp { position },
 7655                cx,
 7656            );
 7657            cx.background_spawn(async move {
 7658                Some(
 7659                    all_actions_task
 7660                        .await
 7661                        .into_iter()
 7662                        .flat_map(|(_, actions)| actions)
 7663                        .collect::<Vec<_>>(),
 7664                )
 7665            })
 7666        }
 7667    }
 7668
 7669    pub fn hover(
 7670        &mut self,
 7671        buffer: &Entity<Buffer>,
 7672        position: PointUtf16,
 7673        cx: &mut Context<Self>,
 7674    ) -> Task<Option<Vec<Hover>>> {
 7675        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7676            let request = GetHover { position };
 7677            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7678                return Task::ready(None);
 7679            }
 7680            let request_task = client.request_lsp(
 7681                upstream_project_id,
 7682                None,
 7683                LSP_REQUEST_TIMEOUT,
 7684                cx.background_executor().clone(),
 7685                request.to_proto(upstream_project_id, buffer.read(cx)),
 7686            );
 7687            let buffer = buffer.clone();
 7688            cx.spawn(async move |weak_lsp_store, cx| {
 7689                let lsp_store = weak_lsp_store.upgrade()?;
 7690                let hovers = join_all(
 7691                    request_task
 7692                        .await
 7693                        .log_err()
 7694                        .flatten()
 7695                        .map(|response| response.payload)
 7696                        .unwrap_or_default()
 7697                        .into_iter()
 7698                        .map(|response| {
 7699                            let response = GetHover { position }.response_from_proto(
 7700                                response.response,
 7701                                lsp_store.clone(),
 7702                                buffer.clone(),
 7703                                cx.clone(),
 7704                            );
 7705                            async move {
 7706                                response
 7707                                    .await
 7708                                    .log_err()
 7709                                    .flatten()
 7710                                    .and_then(remove_empty_hover_blocks)
 7711                            }
 7712                        }),
 7713                )
 7714                .await
 7715                .into_iter()
 7716                .flatten()
 7717                .collect();
 7718                Some(hovers)
 7719            })
 7720        } else {
 7721            let all_actions_task = self.request_multiple_lsp_locally(
 7722                buffer,
 7723                Some(position),
 7724                GetHover { position },
 7725                cx,
 7726            );
 7727            cx.background_spawn(async move {
 7728                Some(
 7729                    all_actions_task
 7730                        .await
 7731                        .into_iter()
 7732                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7733                        .collect::<Vec<Hover>>(),
 7734                )
 7735            })
 7736        }
 7737    }
 7738
 7739    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7740        let language_registry = self.languages.clone();
 7741
 7742        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7743            let request = upstream_client.request(proto::GetProjectSymbols {
 7744                project_id: *project_id,
 7745                query: query.to_string(),
 7746            });
 7747            cx.foreground_executor().spawn(async move {
 7748                let response = request.await?;
 7749                let mut symbols = Vec::new();
 7750                let core_symbols = response
 7751                    .symbols
 7752                    .into_iter()
 7753                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7754                    .collect::<Vec<_>>();
 7755                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7756                    .await;
 7757                Ok(symbols)
 7758            })
 7759        } else if let Some(local) = self.as_local() {
 7760            struct WorkspaceSymbolsResult {
 7761                server_id: LanguageServerId,
 7762                lsp_adapter: Arc<CachedLspAdapter>,
 7763                worktree: WeakEntity<Worktree>,
 7764                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7765            }
 7766
 7767            let mut requests = Vec::new();
 7768            let mut requested_servers = BTreeSet::new();
 7769            for (seed, state) in local.language_server_ids.iter() {
 7770                let Some(worktree_handle) = self
 7771                    .worktree_store
 7772                    .read(cx)
 7773                    .worktree_for_id(seed.worktree_id, cx)
 7774                else {
 7775                    continue;
 7776                };
 7777                let worktree = worktree_handle.read(cx);
 7778                if !worktree.is_visible() {
 7779                    continue;
 7780                }
 7781
 7782                if !requested_servers.insert(state.id) {
 7783                    continue;
 7784                }
 7785
 7786                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7787                    Some(LanguageServerState::Running {
 7788                        adapter, server, ..
 7789                    }) => (adapter.clone(), server),
 7790
 7791                    _ => continue,
 7792                };
 7793                let supports_workspace_symbol_request =
 7794                    match server.capabilities().workspace_symbol_provider {
 7795                        Some(OneOf::Left(supported)) => supported,
 7796                        Some(OneOf::Right(_)) => true,
 7797                        None => false,
 7798                    };
 7799                if !supports_workspace_symbol_request {
 7800                    continue;
 7801                }
 7802                let worktree_handle = worktree_handle.clone();
 7803                let server_id = server.server_id();
 7804                requests.push(
 7805                        server
 7806                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7807                                lsp::WorkspaceSymbolParams {
 7808                                    query: query.to_string(),
 7809                                    ..Default::default()
 7810                                },
 7811                            )
 7812                            .map(move |response| {
 7813                                let lsp_symbols = response.into_response()
 7814                                    .context("workspace symbols request")
 7815                                    .log_err()
 7816                                    .flatten()
 7817                                    .map(|symbol_response| match symbol_response {
 7818                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7819                                            flat_responses.into_iter().map(|lsp_symbol| {
 7820                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7821                                            }).collect::<Vec<_>>()
 7822                                        }
 7823                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7824                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7825                                                let location = match lsp_symbol.location {
 7826                                                    OneOf::Left(location) => location,
 7827                                                    OneOf::Right(_) => {
 7828                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7829                                                        return None
 7830                                                    }
 7831                                                };
 7832                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7833                                            }).collect::<Vec<_>>()
 7834                                        }
 7835                                    }).unwrap_or_default();
 7836
 7837                                WorkspaceSymbolsResult {
 7838                                    server_id,
 7839                                    lsp_adapter,
 7840                                    worktree: worktree_handle.downgrade(),
 7841                                    lsp_symbols,
 7842                                }
 7843                            }),
 7844                    );
 7845            }
 7846
 7847            cx.spawn(async move |this, cx| {
 7848                let responses = futures::future::join_all(requests).await;
 7849                let this = match this.upgrade() {
 7850                    Some(this) => this,
 7851                    None => return Ok(Vec::new()),
 7852                };
 7853
 7854                let mut symbols = Vec::new();
 7855                for result in responses {
 7856                    let core_symbols = this.update(cx, |this, cx| {
 7857                        result
 7858                            .lsp_symbols
 7859                            .into_iter()
 7860                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7861                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7862                                let source_worktree = result.worktree.upgrade()?;
 7863                                let source_worktree_id = source_worktree.read(cx).id();
 7864
 7865                                let path = if let Some((tree, rel_path)) =
 7866                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7867                                {
 7868                                    let worktree_id = tree.read(cx).id();
 7869                                    SymbolLocation::InProject(ProjectPath {
 7870                                        worktree_id,
 7871                                        path: rel_path,
 7872                                    })
 7873                                } else {
 7874                                    SymbolLocation::OutsideProject {
 7875                                        signature: this.symbol_signature(&abs_path),
 7876                                        abs_path: abs_path.into(),
 7877                                    }
 7878                                };
 7879
 7880                                Some(CoreSymbol {
 7881                                    source_language_server_id: result.server_id,
 7882                                    language_server_name: result.lsp_adapter.name.clone(),
 7883                                    source_worktree_id,
 7884                                    path,
 7885                                    kind: symbol_kind,
 7886                                    name: symbol_name,
 7887                                    range: range_from_lsp(symbol_location.range),
 7888                                })
 7889                            })
 7890                            .collect()
 7891                    })?;
 7892
 7893                    populate_labels_for_symbols(
 7894                        core_symbols,
 7895                        &language_registry,
 7896                        Some(result.lsp_adapter),
 7897                        &mut symbols,
 7898                    )
 7899                    .await;
 7900                }
 7901
 7902                Ok(symbols)
 7903            })
 7904        } else {
 7905            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7906        }
 7907    }
 7908
 7909    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7910        let mut summary = DiagnosticSummary::default();
 7911        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7912            summary.error_count += path_summary.error_count;
 7913            summary.warning_count += path_summary.warning_count;
 7914        }
 7915        summary
 7916    }
 7917
 7918    /// Returns the diagnostic summary for a specific project path.
 7919    pub fn diagnostic_summary_for_path(
 7920        &self,
 7921        project_path: &ProjectPath,
 7922        _: &App,
 7923    ) -> DiagnosticSummary {
 7924        if let Some(summaries) = self
 7925            .diagnostic_summaries
 7926            .get(&project_path.worktree_id)
 7927            .and_then(|map| map.get(&project_path.path))
 7928        {
 7929            let (error_count, warning_count) = summaries.iter().fold(
 7930                (0, 0),
 7931                |(error_count, warning_count), (_language_server_id, summary)| {
 7932                    (
 7933                        error_count + summary.error_count,
 7934                        warning_count + summary.warning_count,
 7935                    )
 7936                },
 7937            );
 7938
 7939            DiagnosticSummary {
 7940                error_count,
 7941                warning_count,
 7942            }
 7943        } else {
 7944            DiagnosticSummary::default()
 7945        }
 7946    }
 7947
 7948    pub fn diagnostic_summaries<'a>(
 7949        &'a self,
 7950        include_ignored: bool,
 7951        cx: &'a App,
 7952    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7953        self.worktree_store
 7954            .read(cx)
 7955            .visible_worktrees(cx)
 7956            .filter_map(|worktree| {
 7957                let worktree = worktree.read(cx);
 7958                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7959            })
 7960            .flat_map(move |(worktree, summaries)| {
 7961                let worktree_id = worktree.id();
 7962                summaries
 7963                    .iter()
 7964                    .filter(move |(path, _)| {
 7965                        include_ignored
 7966                            || worktree
 7967                                .entry_for_path(path.as_ref())
 7968                                .is_some_and(|entry| !entry.is_ignored)
 7969                    })
 7970                    .flat_map(move |(path, summaries)| {
 7971                        summaries.iter().map(move |(server_id, summary)| {
 7972                            (
 7973                                ProjectPath {
 7974                                    worktree_id,
 7975                                    path: path.clone(),
 7976                                },
 7977                                *server_id,
 7978                                *summary,
 7979                            )
 7980                        })
 7981                    })
 7982            })
 7983    }
 7984
 7985    pub fn on_buffer_edited(
 7986        &mut self,
 7987        buffer: Entity<Buffer>,
 7988        cx: &mut Context<Self>,
 7989    ) -> Option<()> {
 7990        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7991            Some(
 7992                self.as_local()?
 7993                    .language_servers_for_buffer(buffer, cx)
 7994                    .map(|i| i.1.clone())
 7995                    .collect(),
 7996            )
 7997        })?;
 7998
 7999        let buffer = buffer.read(cx);
 8000        let file = File::from_dyn(buffer.file())?;
 8001        let abs_path = file.as_local()?.abs_path(cx);
 8002        let uri = lsp::Uri::from_file_path(&abs_path)
 8003            .ok()
 8004            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 8005            .log_err()?;
 8006        let next_snapshot = buffer.text_snapshot();
 8007        for language_server in language_servers {
 8008            let language_server = language_server.clone();
 8009
 8010            let buffer_snapshots = self
 8011                .as_local_mut()?
 8012                .buffer_snapshots
 8013                .get_mut(&buffer.remote_id())
 8014                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 8015            let previous_snapshot = buffer_snapshots.last()?;
 8016
 8017            let build_incremental_change = || {
 8018                buffer
 8019                    .edits_since::<Dimensions<PointUtf16, usize>>(
 8020                        previous_snapshot.snapshot.version(),
 8021                    )
 8022                    .map(|edit| {
 8023                        let edit_start = edit.new.start.0;
 8024                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 8025                        let new_text = next_snapshot
 8026                            .text_for_range(edit.new.start.1..edit.new.end.1)
 8027                            .collect();
 8028                        lsp::TextDocumentContentChangeEvent {
 8029                            range: Some(lsp::Range::new(
 8030                                point_to_lsp(edit_start),
 8031                                point_to_lsp(edit_end),
 8032                            )),
 8033                            range_length: None,
 8034                            text: new_text,
 8035                        }
 8036                    })
 8037                    .collect()
 8038            };
 8039
 8040            let document_sync_kind = language_server
 8041                .capabilities()
 8042                .text_document_sync
 8043                .as_ref()
 8044                .and_then(|sync| match sync {
 8045                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 8046                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 8047                });
 8048
 8049            let content_changes: Vec<_> = match document_sync_kind {
 8050                Some(lsp::TextDocumentSyncKind::FULL) => {
 8051                    vec![lsp::TextDocumentContentChangeEvent {
 8052                        range: None,
 8053                        range_length: None,
 8054                        text: next_snapshot.text(),
 8055                    }]
 8056                }
 8057                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8058                _ => {
 8059                    #[cfg(any(test, feature = "test-support"))]
 8060                    {
 8061                        build_incremental_change()
 8062                    }
 8063
 8064                    #[cfg(not(any(test, feature = "test-support")))]
 8065                    {
 8066                        continue;
 8067                    }
 8068                }
 8069            };
 8070
 8071            let next_version = previous_snapshot.version + 1;
 8072            buffer_snapshots.push(LspBufferSnapshot {
 8073                version: next_version,
 8074                snapshot: next_snapshot.clone(),
 8075            });
 8076
 8077            language_server
 8078                .notify::<lsp::notification::DidChangeTextDocument>(
 8079                    lsp::DidChangeTextDocumentParams {
 8080                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8081                            uri.clone(),
 8082                            next_version,
 8083                        ),
 8084                        content_changes,
 8085                    },
 8086                )
 8087                .ok();
 8088            self.pull_workspace_diagnostics(language_server.server_id());
 8089        }
 8090
 8091        None
 8092    }
 8093
 8094    pub fn on_buffer_saved(
 8095        &mut self,
 8096        buffer: Entity<Buffer>,
 8097        cx: &mut Context<Self>,
 8098    ) -> Option<()> {
 8099        let file = File::from_dyn(buffer.read(cx).file())?;
 8100        let worktree_id = file.worktree_id(cx);
 8101        let abs_path = file.as_local()?.abs_path(cx);
 8102        let text_document = lsp::TextDocumentIdentifier {
 8103            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8104        };
 8105        let local = self.as_local()?;
 8106
 8107        for server in local.language_servers_for_worktree(worktree_id) {
 8108            if let Some(include_text) = include_text(server.as_ref()) {
 8109                let text = if include_text {
 8110                    Some(buffer.read(cx).text())
 8111                } else {
 8112                    None
 8113                };
 8114                server
 8115                    .notify::<lsp::notification::DidSaveTextDocument>(
 8116                        lsp::DidSaveTextDocumentParams {
 8117                            text_document: text_document.clone(),
 8118                            text,
 8119                        },
 8120                    )
 8121                    .ok();
 8122            }
 8123        }
 8124
 8125        let language_servers = buffer.update(cx, |buffer, cx| {
 8126            local.language_server_ids_for_buffer(buffer, cx)
 8127        });
 8128        for language_server_id in language_servers {
 8129            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8130        }
 8131
 8132        None
 8133    }
 8134
 8135    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8136        maybe!(async move {
 8137            let mut refreshed_servers = HashSet::default();
 8138            let servers = lsp_store
 8139                .update(cx, |lsp_store, cx| {
 8140                    let local = lsp_store.as_local()?;
 8141
 8142                    let servers = local
 8143                        .language_server_ids
 8144                        .iter()
 8145                        .filter_map(|(seed, state)| {
 8146                            let worktree = lsp_store
 8147                                .worktree_store
 8148                                .read(cx)
 8149                                .worktree_for_id(seed.worktree_id, cx);
 8150                            let delegate: Arc<dyn LspAdapterDelegate> =
 8151                                worktree.map(|worktree| {
 8152                                    LocalLspAdapterDelegate::new(
 8153                                        local.languages.clone(),
 8154                                        &local.environment,
 8155                                        cx.weak_entity(),
 8156                                        &worktree,
 8157                                        local.http_client.clone(),
 8158                                        local.fs.clone(),
 8159                                        cx,
 8160                                    )
 8161                                })?;
 8162                            let server_id = state.id;
 8163
 8164                            let states = local.language_servers.get(&server_id)?;
 8165
 8166                            match states {
 8167                                LanguageServerState::Starting { .. } => None,
 8168                                LanguageServerState::Running {
 8169                                    adapter, server, ..
 8170                                } => {
 8171                                    let adapter = adapter.clone();
 8172                                    let server = server.clone();
 8173                                    refreshed_servers.insert(server.name());
 8174                                    let toolchain = seed.toolchain.clone();
 8175                                    Some(cx.spawn(async move |_, cx| {
 8176                                        let settings =
 8177                                            LocalLspStore::workspace_configuration_for_adapter(
 8178                                                adapter.adapter.clone(),
 8179                                                &delegate,
 8180                                                toolchain,
 8181                                                None,
 8182                                                cx,
 8183                                            )
 8184                                            .await
 8185                                            .ok()?;
 8186                                        server
 8187                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8188                                                lsp::DidChangeConfigurationParams { settings },
 8189                                            )
 8190                                            .ok()?;
 8191                                        Some(())
 8192                                    }))
 8193                                }
 8194                            }
 8195                        })
 8196                        .collect::<Vec<_>>();
 8197
 8198                    Some(servers)
 8199                })
 8200                .ok()
 8201                .flatten()?;
 8202
 8203            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8204            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8205            // to stop and unregister its language server wrapper.
 8206            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8207            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8208            let _: Vec<Option<()>> = join_all(servers).await;
 8209
 8210            Some(())
 8211        })
 8212        .await;
 8213    }
 8214
 8215    fn maintain_workspace_config(
 8216        external_refresh_requests: watch::Receiver<()>,
 8217        cx: &mut Context<Self>,
 8218    ) -> Task<Result<()>> {
 8219        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8220        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8221
 8222        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8223            *settings_changed_tx.borrow_mut() = ();
 8224        });
 8225
 8226        let mut joint_future =
 8227            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8228        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8229        // - 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).
 8230        // - 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.
 8231        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8232        // - 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,
 8233        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8234        cx.spawn(async move |this, cx| {
 8235            while let Some(()) = joint_future.next().await {
 8236                this.update(cx, |this, cx| {
 8237                    this.refresh_server_tree(cx);
 8238                })
 8239                .ok();
 8240
 8241                Self::refresh_workspace_configurations(&this, cx).await;
 8242            }
 8243
 8244            drop(settings_observation);
 8245            anyhow::Ok(())
 8246        })
 8247    }
 8248
 8249    pub fn running_language_servers_for_local_buffer<'a>(
 8250        &'a self,
 8251        buffer: &Buffer,
 8252        cx: &mut App,
 8253    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8254        let local = self.as_local();
 8255        let language_server_ids = local
 8256            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8257            .unwrap_or_default();
 8258
 8259        language_server_ids
 8260            .into_iter()
 8261            .filter_map(
 8262                move |server_id| match local?.language_servers.get(&server_id)? {
 8263                    LanguageServerState::Running {
 8264                        adapter, server, ..
 8265                    } => Some((adapter, server)),
 8266                    _ => None,
 8267                },
 8268            )
 8269    }
 8270
 8271    pub fn language_servers_for_local_buffer(
 8272        &self,
 8273        buffer: &Buffer,
 8274        cx: &mut App,
 8275    ) -> Vec<LanguageServerId> {
 8276        let local = self.as_local();
 8277        local
 8278            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8279            .unwrap_or_default()
 8280    }
 8281
 8282    pub fn language_server_for_local_buffer<'a>(
 8283        &'a self,
 8284        buffer: &'a Buffer,
 8285        server_id: LanguageServerId,
 8286        cx: &'a mut App,
 8287    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8288        self.as_local()?
 8289            .language_servers_for_buffer(buffer, cx)
 8290            .find(|(_, s)| s.server_id() == server_id)
 8291    }
 8292
 8293    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8294        self.diagnostic_summaries.remove(&id_to_remove);
 8295        if let Some(local) = self.as_local_mut() {
 8296            let to_remove = local.remove_worktree(id_to_remove, cx);
 8297            for server in to_remove {
 8298                self.language_server_statuses.remove(&server);
 8299            }
 8300        }
 8301    }
 8302
 8303    pub fn shared(
 8304        &mut self,
 8305        project_id: u64,
 8306        downstream_client: AnyProtoClient,
 8307        _: &mut Context<Self>,
 8308    ) {
 8309        self.downstream_client = Some((downstream_client.clone(), project_id));
 8310
 8311        for (server_id, status) in &self.language_server_statuses {
 8312            if let Some(server) = self.language_server_for_id(*server_id) {
 8313                downstream_client
 8314                    .send(proto::StartLanguageServer {
 8315                        project_id,
 8316                        server: Some(proto::LanguageServer {
 8317                            id: server_id.to_proto(),
 8318                            name: status.name.to_string(),
 8319                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8320                        }),
 8321                        capabilities: serde_json::to_string(&server.capabilities())
 8322                            .expect("serializing server LSP capabilities"),
 8323                    })
 8324                    .log_err();
 8325            }
 8326        }
 8327    }
 8328
 8329    pub fn disconnected_from_host(&mut self) {
 8330        self.downstream_client.take();
 8331    }
 8332
 8333    pub fn disconnected_from_ssh_remote(&mut self) {
 8334        if let LspStoreMode::Remote(RemoteLspStore {
 8335            upstream_client, ..
 8336        }) = &mut self.mode
 8337        {
 8338            upstream_client.take();
 8339        }
 8340    }
 8341
 8342    pub(crate) fn set_language_server_statuses_from_proto(
 8343        &mut self,
 8344        project: WeakEntity<Project>,
 8345        language_servers: Vec<proto::LanguageServer>,
 8346        server_capabilities: Vec<String>,
 8347        cx: &mut Context<Self>,
 8348    ) {
 8349        let lsp_logs = cx
 8350            .try_global::<GlobalLogStore>()
 8351            .map(|lsp_store| lsp_store.0.clone());
 8352
 8353        self.language_server_statuses = language_servers
 8354            .into_iter()
 8355            .zip(server_capabilities)
 8356            .map(|(server, server_capabilities)| {
 8357                let server_id = LanguageServerId(server.id as usize);
 8358                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8359                    self.lsp_server_capabilities
 8360                        .insert(server_id, server_capabilities);
 8361                }
 8362
 8363                let name = LanguageServerName::from_proto(server.name);
 8364                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8365
 8366                if let Some(lsp_logs) = &lsp_logs {
 8367                    lsp_logs.update(cx, |lsp_logs, cx| {
 8368                        lsp_logs.add_language_server(
 8369                            // Only remote clients get their language servers set from proto
 8370                            LanguageServerKind::Remote {
 8371                                project: project.clone(),
 8372                            },
 8373                            server_id,
 8374                            Some(name.clone()),
 8375                            worktree,
 8376                            None,
 8377                            cx,
 8378                        );
 8379                    });
 8380                }
 8381
 8382                (
 8383                    server_id,
 8384                    LanguageServerStatus {
 8385                        name,
 8386                        server_version: None,
 8387                        pending_work: Default::default(),
 8388                        has_pending_diagnostic_updates: false,
 8389                        progress_tokens: Default::default(),
 8390                        worktree,
 8391                        binary: None,
 8392                        configuration: None,
 8393                        workspace_folders: BTreeSet::new(),
 8394                    },
 8395                )
 8396            })
 8397            .collect();
 8398    }
 8399
 8400    #[cfg(test)]
 8401    pub fn update_diagnostic_entries(
 8402        &mut self,
 8403        server_id: LanguageServerId,
 8404        abs_path: PathBuf,
 8405        result_id: Option<SharedString>,
 8406        version: Option<i32>,
 8407        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8408        cx: &mut Context<Self>,
 8409    ) -> anyhow::Result<()> {
 8410        self.merge_diagnostic_entries(
 8411            vec![DocumentDiagnosticsUpdate {
 8412                diagnostics: DocumentDiagnostics {
 8413                    diagnostics,
 8414                    document_abs_path: abs_path,
 8415                    version,
 8416                },
 8417                result_id,
 8418                server_id,
 8419                disk_based_sources: Cow::Borrowed(&[]),
 8420                registration_id: None,
 8421            }],
 8422            |_, _, _| false,
 8423            cx,
 8424        )?;
 8425        Ok(())
 8426    }
 8427
 8428    pub fn merge_diagnostic_entries<'a>(
 8429        &mut self,
 8430        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8431        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8432        cx: &mut Context<Self>,
 8433    ) -> anyhow::Result<()> {
 8434        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8435        let mut updated_diagnostics_paths = HashMap::default();
 8436        for mut update in diagnostic_updates {
 8437            let abs_path = &update.diagnostics.document_abs_path;
 8438            let server_id = update.server_id;
 8439            let Some((worktree, relative_path)) =
 8440                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8441            else {
 8442                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8443                return Ok(());
 8444            };
 8445
 8446            let worktree_id = worktree.read(cx).id();
 8447            let project_path = ProjectPath {
 8448                worktree_id,
 8449                path: relative_path,
 8450            };
 8451
 8452            let document_uri = lsp::Uri::from_file_path(abs_path)
 8453                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8454            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8455                let snapshot = buffer_handle.read(cx).snapshot();
 8456                let buffer = buffer_handle.read(cx);
 8457                let reused_diagnostics = buffer
 8458                    .buffer_diagnostics(Some(server_id))
 8459                    .iter()
 8460                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8461                    .map(|v| {
 8462                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8463                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8464                        DiagnosticEntry {
 8465                            range: start..end,
 8466                            diagnostic: v.diagnostic.clone(),
 8467                        }
 8468                    })
 8469                    .collect::<Vec<_>>();
 8470
 8471                self.as_local_mut()
 8472                    .context("cannot merge diagnostics on a remote LspStore")?
 8473                    .update_buffer_diagnostics(
 8474                        &buffer_handle,
 8475                        server_id,
 8476                        Some(update.registration_id),
 8477                        update.result_id,
 8478                        update.diagnostics.version,
 8479                        update.diagnostics.diagnostics.clone(),
 8480                        reused_diagnostics.clone(),
 8481                        cx,
 8482                    )?;
 8483
 8484                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8485            } else if let Some(local) = self.as_local() {
 8486                let reused_diagnostics = local
 8487                    .diagnostics
 8488                    .get(&worktree_id)
 8489                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8490                    .and_then(|diagnostics_by_server_id| {
 8491                        diagnostics_by_server_id
 8492                            .binary_search_by_key(&server_id, |e| e.0)
 8493                            .ok()
 8494                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8495                    })
 8496                    .into_iter()
 8497                    .flatten()
 8498                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8499
 8500                update
 8501                    .diagnostics
 8502                    .diagnostics
 8503                    .extend(reused_diagnostics.cloned());
 8504            }
 8505
 8506            let updated = worktree.update(cx, |worktree, cx| {
 8507                self.update_worktree_diagnostics(
 8508                    worktree.id(),
 8509                    server_id,
 8510                    project_path.path.clone(),
 8511                    update.diagnostics.diagnostics,
 8512                    cx,
 8513                )
 8514            })?;
 8515            match updated {
 8516                ControlFlow::Continue(new_summary) => {
 8517                    if let Some((project_id, new_summary)) = new_summary {
 8518                        match &mut diagnostics_summary {
 8519                            Some(diagnostics_summary) => {
 8520                                diagnostics_summary
 8521                                    .more_summaries
 8522                                    .push(proto::DiagnosticSummary {
 8523                                        path: project_path.path.as_ref().to_proto(),
 8524                                        language_server_id: server_id.0 as u64,
 8525                                        error_count: new_summary.error_count,
 8526                                        warning_count: new_summary.warning_count,
 8527                                    })
 8528                            }
 8529                            None => {
 8530                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8531                                    project_id,
 8532                                    worktree_id: worktree_id.to_proto(),
 8533                                    summary: Some(proto::DiagnosticSummary {
 8534                                        path: project_path.path.as_ref().to_proto(),
 8535                                        language_server_id: server_id.0 as u64,
 8536                                        error_count: new_summary.error_count,
 8537                                        warning_count: new_summary.warning_count,
 8538                                    }),
 8539                                    more_summaries: Vec::new(),
 8540                                })
 8541                            }
 8542                        }
 8543                    }
 8544                    updated_diagnostics_paths
 8545                        .entry(server_id)
 8546                        .or_insert_with(Vec::new)
 8547                        .push(project_path);
 8548                }
 8549                ControlFlow::Break(()) => {}
 8550            }
 8551        }
 8552
 8553        if let Some((diagnostics_summary, (downstream_client, _))) =
 8554            diagnostics_summary.zip(self.downstream_client.as_ref())
 8555        {
 8556            downstream_client.send(diagnostics_summary).log_err();
 8557        }
 8558        for (server_id, paths) in updated_diagnostics_paths {
 8559            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8560        }
 8561        Ok(())
 8562    }
 8563
 8564    fn update_worktree_diagnostics(
 8565        &mut self,
 8566        worktree_id: WorktreeId,
 8567        server_id: LanguageServerId,
 8568        path_in_worktree: Arc<RelPath>,
 8569        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8570        _: &mut Context<Worktree>,
 8571    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8572        let local = match &mut self.mode {
 8573            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8574            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8575        };
 8576
 8577        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8578        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8579        let summaries_by_server_id = summaries_for_tree
 8580            .entry(path_in_worktree.clone())
 8581            .or_default();
 8582
 8583        let old_summary = summaries_by_server_id
 8584            .remove(&server_id)
 8585            .unwrap_or_default();
 8586
 8587        let new_summary = DiagnosticSummary::new(&diagnostics);
 8588        if diagnostics.is_empty() {
 8589            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8590            {
 8591                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8592                    diagnostics_by_server_id.remove(ix);
 8593                }
 8594                if diagnostics_by_server_id.is_empty() {
 8595                    diagnostics_for_tree.remove(&path_in_worktree);
 8596                }
 8597            }
 8598        } else {
 8599            summaries_by_server_id.insert(server_id, new_summary);
 8600            let diagnostics_by_server_id = diagnostics_for_tree
 8601                .entry(path_in_worktree.clone())
 8602                .or_default();
 8603            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8604                Ok(ix) => {
 8605                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8606                }
 8607                Err(ix) => {
 8608                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8609                }
 8610            }
 8611        }
 8612
 8613        if !old_summary.is_empty() || !new_summary.is_empty() {
 8614            if let Some((_, project_id)) = &self.downstream_client {
 8615                Ok(ControlFlow::Continue(Some((
 8616                    *project_id,
 8617                    proto::DiagnosticSummary {
 8618                        path: path_in_worktree.to_proto(),
 8619                        language_server_id: server_id.0 as u64,
 8620                        error_count: new_summary.error_count as u32,
 8621                        warning_count: new_summary.warning_count as u32,
 8622                    },
 8623                ))))
 8624            } else {
 8625                Ok(ControlFlow::Continue(None))
 8626            }
 8627        } else {
 8628            Ok(ControlFlow::Break(()))
 8629        }
 8630    }
 8631
 8632    pub fn open_buffer_for_symbol(
 8633        &mut self,
 8634        symbol: &Symbol,
 8635        cx: &mut Context<Self>,
 8636    ) -> Task<Result<Entity<Buffer>>> {
 8637        if let Some((client, project_id)) = self.upstream_client() {
 8638            let request = client.request(proto::OpenBufferForSymbol {
 8639                project_id,
 8640                symbol: Some(Self::serialize_symbol(symbol)),
 8641            });
 8642            cx.spawn(async move |this, cx| {
 8643                let response = request.await?;
 8644                let buffer_id = BufferId::new(response.buffer_id)?;
 8645                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8646                    .await
 8647            })
 8648        } else if let Some(local) = self.as_local() {
 8649            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8650                seed.worktree_id == symbol.source_worktree_id
 8651                    && state.id == symbol.source_language_server_id
 8652                    && symbol.language_server_name == seed.name
 8653            });
 8654            if !is_valid {
 8655                return Task::ready(Err(anyhow!(
 8656                    "language server for worktree and language not found"
 8657                )));
 8658            };
 8659
 8660            let symbol_abs_path = match &symbol.path {
 8661                SymbolLocation::InProject(project_path) => self
 8662                    .worktree_store
 8663                    .read(cx)
 8664                    .absolutize(&project_path, cx)
 8665                    .context("no such worktree"),
 8666                SymbolLocation::OutsideProject {
 8667                    abs_path,
 8668                    signature: _,
 8669                } => Ok(abs_path.to_path_buf()),
 8670            };
 8671            let symbol_abs_path = match symbol_abs_path {
 8672                Ok(abs_path) => abs_path,
 8673                Err(err) => return Task::ready(Err(err)),
 8674            };
 8675            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8676                uri
 8677            } else {
 8678                return Task::ready(Err(anyhow!("invalid symbol path")));
 8679            };
 8680
 8681            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8682        } else {
 8683            Task::ready(Err(anyhow!("no upstream client or local store")))
 8684        }
 8685    }
 8686
 8687    pub(crate) fn open_local_buffer_via_lsp(
 8688        &mut self,
 8689        abs_path: lsp::Uri,
 8690        language_server_id: LanguageServerId,
 8691        cx: &mut Context<Self>,
 8692    ) -> Task<Result<Entity<Buffer>>> {
 8693        cx.spawn(async move |lsp_store, cx| {
 8694            // Escape percent-encoded string.
 8695            let current_scheme = abs_path.scheme().to_owned();
 8696            // Uri is immutable, so we can't modify the scheme
 8697
 8698            let abs_path = abs_path
 8699                .to_file_path()
 8700                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8701            let p = abs_path.clone();
 8702            let yarn_worktree = lsp_store
 8703                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8704                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8705                        cx.spawn(async move |this, cx| {
 8706                            let t = this
 8707                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8708                                .ok()?;
 8709                            t.await
 8710                        })
 8711                    }),
 8712                    None => Task::ready(None),
 8713                })?
 8714                .await;
 8715            let (worktree_root_target, known_relative_path) =
 8716                if let Some((zip_root, relative_path)) = yarn_worktree {
 8717                    (zip_root, Some(relative_path))
 8718                } else {
 8719                    (Arc::<Path>::from(abs_path.as_path()), None)
 8720                };
 8721            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8722                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8723                    worktree_store.find_worktree(&worktree_root_target, cx)
 8724                })
 8725            })?;
 8726            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8727                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8728                (result.0, relative_path, None)
 8729            } else {
 8730                let worktree = lsp_store
 8731                    .update(cx, |lsp_store, cx| {
 8732                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8733                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8734                        })
 8735                    })?
 8736                    .await?;
 8737                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8738                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8739                    lsp_store
 8740                        .update(cx, |lsp_store, cx| {
 8741                            if let Some(local) = lsp_store.as_local_mut() {
 8742                                local.register_language_server_for_invisible_worktree(
 8743                                    &worktree,
 8744                                    language_server_id,
 8745                                    cx,
 8746                                )
 8747                            }
 8748                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8749                                Some(status) => status.worktree,
 8750                                None => None,
 8751                            }
 8752                        })
 8753                        .ok()
 8754                        .flatten()
 8755                        .zip(Some(worktree_root.clone()))
 8756                } else {
 8757                    None
 8758                };
 8759                let relative_path = if let Some(known_path) = known_relative_path {
 8760                    known_path
 8761                } else {
 8762                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8763                        .into_arc()
 8764                };
 8765                (worktree, relative_path, source_ws)
 8766            };
 8767            let project_path = ProjectPath {
 8768                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8769                path: relative_path,
 8770            };
 8771            let buffer = lsp_store
 8772                .update(cx, |lsp_store, cx| {
 8773                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8774                        buffer_store.open_buffer(project_path, cx)
 8775                    })
 8776                })?
 8777                .await?;
 8778            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8779            if let Some((source_ws, worktree_root)) = source_ws {
 8780                buffer.update(cx, |buffer, cx| {
 8781                    let settings = WorktreeSettings::get(
 8782                        Some(
 8783                            (&ProjectPath {
 8784                                worktree_id: source_ws,
 8785                                path: Arc::from(RelPath::empty()),
 8786                            })
 8787                                .into(),
 8788                        ),
 8789                        cx,
 8790                    );
 8791                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8792                    if is_read_only {
 8793                        buffer.set_capability(Capability::ReadOnly, cx);
 8794                    }
 8795                })?;
 8796            }
 8797            Ok(buffer)
 8798        })
 8799    }
 8800
 8801    fn request_multiple_lsp_locally<P, R>(
 8802        &mut self,
 8803        buffer: &Entity<Buffer>,
 8804        position: Option<P>,
 8805        request: R,
 8806        cx: &mut Context<Self>,
 8807    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8808    where
 8809        P: ToOffset,
 8810        R: LspCommand + Clone,
 8811        <R::LspRequest as lsp::request::Request>::Result: Send,
 8812        <R::LspRequest as lsp::request::Request>::Params: Send,
 8813    {
 8814        let Some(local) = self.as_local() else {
 8815            return Task::ready(Vec::new());
 8816        };
 8817
 8818        let snapshot = buffer.read(cx).snapshot();
 8819        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8820
 8821        let server_ids = buffer.update(cx, |buffer, cx| {
 8822            local
 8823                .language_servers_for_buffer(buffer, cx)
 8824                .filter(|(adapter, _)| {
 8825                    scope
 8826                        .as_ref()
 8827                        .map(|scope| scope.language_allowed(&adapter.name))
 8828                        .unwrap_or(true)
 8829                })
 8830                .map(|(_, server)| server.server_id())
 8831                .filter(|server_id| {
 8832                    self.as_local().is_none_or(|local| {
 8833                        local
 8834                            .buffers_opened_in_servers
 8835                            .get(&snapshot.remote_id())
 8836                            .is_some_and(|servers| servers.contains(server_id))
 8837                    })
 8838                })
 8839                .collect::<Vec<_>>()
 8840        });
 8841
 8842        let mut response_results = server_ids
 8843            .into_iter()
 8844            .map(|server_id| {
 8845                let task = self.request_lsp(
 8846                    buffer.clone(),
 8847                    LanguageServerToQuery::Other(server_id),
 8848                    request.clone(),
 8849                    cx,
 8850                );
 8851                async move { (server_id, task.await) }
 8852            })
 8853            .collect::<FuturesUnordered<_>>();
 8854
 8855        cx.background_spawn(async move {
 8856            let mut responses = Vec::with_capacity(response_results.len());
 8857            while let Some((server_id, response_result)) = response_results.next().await {
 8858                match response_result {
 8859                    Ok(response) => responses.push((server_id, response)),
 8860                    // rust-analyzer likes to error with this when its still loading up
 8861                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8862                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8863                }
 8864            }
 8865            responses
 8866        })
 8867    }
 8868
 8869    async fn handle_lsp_get_completions(
 8870        this: Entity<Self>,
 8871        envelope: TypedEnvelope<proto::GetCompletions>,
 8872        mut cx: AsyncApp,
 8873    ) -> Result<proto::GetCompletionsResponse> {
 8874        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8875
 8876        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8877        let buffer_handle = this.update(&mut cx, |this, cx| {
 8878            this.buffer_store.read(cx).get_existing(buffer_id)
 8879        })??;
 8880        let request = GetCompletions::from_proto(
 8881            envelope.payload,
 8882            this.clone(),
 8883            buffer_handle.clone(),
 8884            cx.clone(),
 8885        )
 8886        .await?;
 8887
 8888        let server_to_query = match request.server_id {
 8889            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8890            None => LanguageServerToQuery::FirstCapable,
 8891        };
 8892
 8893        let response = this
 8894            .update(&mut cx, |this, cx| {
 8895                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8896            })?
 8897            .await?;
 8898        this.update(&mut cx, |this, cx| {
 8899            Ok(GetCompletions::response_to_proto(
 8900                response,
 8901                this,
 8902                sender_id,
 8903                &buffer_handle.read(cx).version(),
 8904                cx,
 8905            ))
 8906        })?
 8907    }
 8908
 8909    async fn handle_lsp_command<T: LspCommand>(
 8910        this: Entity<Self>,
 8911        envelope: TypedEnvelope<T::ProtoRequest>,
 8912        mut cx: AsyncApp,
 8913    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8914    where
 8915        <T::LspRequest as lsp::request::Request>::Params: Send,
 8916        <T::LspRequest as lsp::request::Request>::Result: Send,
 8917    {
 8918        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8919        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8920        let buffer_handle = this.update(&mut cx, |this, cx| {
 8921            this.buffer_store.read(cx).get_existing(buffer_id)
 8922        })??;
 8923        let request = T::from_proto(
 8924            envelope.payload,
 8925            this.clone(),
 8926            buffer_handle.clone(),
 8927            cx.clone(),
 8928        )
 8929        .await?;
 8930        let response = this
 8931            .update(&mut cx, |this, cx| {
 8932                this.request_lsp(
 8933                    buffer_handle.clone(),
 8934                    LanguageServerToQuery::FirstCapable,
 8935                    request,
 8936                    cx,
 8937                )
 8938            })?
 8939            .await?;
 8940        this.update(&mut cx, |this, cx| {
 8941            Ok(T::response_to_proto(
 8942                response,
 8943                this,
 8944                sender_id,
 8945                &buffer_handle.read(cx).version(),
 8946                cx,
 8947            ))
 8948        })?
 8949    }
 8950
 8951    async fn handle_lsp_query(
 8952        lsp_store: Entity<Self>,
 8953        envelope: TypedEnvelope<proto::LspQuery>,
 8954        mut cx: AsyncApp,
 8955    ) -> Result<proto::Ack> {
 8956        use proto::lsp_query::Request;
 8957        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8958        let lsp_query = envelope.payload;
 8959        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8960        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8961        match lsp_query.request.context("invalid LSP query request")? {
 8962            Request::GetReferences(get_references) => {
 8963                let position = get_references.position.clone().and_then(deserialize_anchor);
 8964                Self::query_lsp_locally::<GetReferences>(
 8965                    lsp_store,
 8966                    server_id,
 8967                    sender_id,
 8968                    lsp_request_id,
 8969                    get_references,
 8970                    position,
 8971                    &mut cx,
 8972                )
 8973                .await?;
 8974            }
 8975            Request::GetDocumentColor(get_document_color) => {
 8976                Self::query_lsp_locally::<GetDocumentColor>(
 8977                    lsp_store,
 8978                    server_id,
 8979                    sender_id,
 8980                    lsp_request_id,
 8981                    get_document_color,
 8982                    None,
 8983                    &mut cx,
 8984                )
 8985                .await?;
 8986            }
 8987            Request::GetHover(get_hover) => {
 8988                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8989                Self::query_lsp_locally::<GetHover>(
 8990                    lsp_store,
 8991                    server_id,
 8992                    sender_id,
 8993                    lsp_request_id,
 8994                    get_hover,
 8995                    position,
 8996                    &mut cx,
 8997                )
 8998                .await?;
 8999            }
 9000            Request::GetCodeActions(get_code_actions) => {
 9001                Self::query_lsp_locally::<GetCodeActions>(
 9002                    lsp_store,
 9003                    server_id,
 9004                    sender_id,
 9005                    lsp_request_id,
 9006                    get_code_actions,
 9007                    None,
 9008                    &mut cx,
 9009                )
 9010                .await?;
 9011            }
 9012            Request::GetSignatureHelp(get_signature_help) => {
 9013                let position = get_signature_help
 9014                    .position
 9015                    .clone()
 9016                    .and_then(deserialize_anchor);
 9017                Self::query_lsp_locally::<GetSignatureHelp>(
 9018                    lsp_store,
 9019                    server_id,
 9020                    sender_id,
 9021                    lsp_request_id,
 9022                    get_signature_help,
 9023                    position,
 9024                    &mut cx,
 9025                )
 9026                .await?;
 9027            }
 9028            Request::GetCodeLens(get_code_lens) => {
 9029                Self::query_lsp_locally::<GetCodeLens>(
 9030                    lsp_store,
 9031                    server_id,
 9032                    sender_id,
 9033                    lsp_request_id,
 9034                    get_code_lens,
 9035                    None,
 9036                    &mut cx,
 9037                )
 9038                .await?;
 9039            }
 9040            Request::GetDefinition(get_definition) => {
 9041                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9042                Self::query_lsp_locally::<GetDefinitions>(
 9043                    lsp_store,
 9044                    server_id,
 9045                    sender_id,
 9046                    lsp_request_id,
 9047                    get_definition,
 9048                    position,
 9049                    &mut cx,
 9050                )
 9051                .await?;
 9052            }
 9053            Request::GetDeclaration(get_declaration) => {
 9054                let position = get_declaration
 9055                    .position
 9056                    .clone()
 9057                    .and_then(deserialize_anchor);
 9058                Self::query_lsp_locally::<GetDeclarations>(
 9059                    lsp_store,
 9060                    server_id,
 9061                    sender_id,
 9062                    lsp_request_id,
 9063                    get_declaration,
 9064                    position,
 9065                    &mut cx,
 9066                )
 9067                .await?;
 9068            }
 9069            Request::GetTypeDefinition(get_type_definition) => {
 9070                let position = get_type_definition
 9071                    .position
 9072                    .clone()
 9073                    .and_then(deserialize_anchor);
 9074                Self::query_lsp_locally::<GetTypeDefinitions>(
 9075                    lsp_store,
 9076                    server_id,
 9077                    sender_id,
 9078                    lsp_request_id,
 9079                    get_type_definition,
 9080                    position,
 9081                    &mut cx,
 9082                )
 9083                .await?;
 9084            }
 9085            Request::GetImplementation(get_implementation) => {
 9086                let position = get_implementation
 9087                    .position
 9088                    .clone()
 9089                    .and_then(deserialize_anchor);
 9090                Self::query_lsp_locally::<GetImplementations>(
 9091                    lsp_store,
 9092                    server_id,
 9093                    sender_id,
 9094                    lsp_request_id,
 9095                    get_implementation,
 9096                    position,
 9097                    &mut cx,
 9098                )
 9099                .await?;
 9100            }
 9101            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9102                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 9103                let version = deserialize_version(get_document_diagnostics.buffer_version());
 9104                let buffer = lsp_store.update(&mut cx, |this, cx| {
 9105                    this.buffer_store.read(cx).get_existing(buffer_id)
 9106                })??;
 9107                buffer
 9108                    .update(&mut cx, |buffer, _| {
 9109                        buffer.wait_for_version(version.clone())
 9110                    })?
 9111                    .await?;
 9112                lsp_store.update(&mut cx, |lsp_store, cx| {
 9113                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9114                    let key = LspKey {
 9115                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9116                        server_queried: server_id,
 9117                    };
 9118                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9119                    ) {
 9120                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9121                            lsp_requests.clear();
 9122                        };
 9123                    }
 9124
 9125                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 9126                    existing_queries.insert(
 9127                        lsp_request_id,
 9128                        cx.spawn(async move |lsp_store, cx| {
 9129                            let diagnostics_pull = lsp_store
 9130                                .update(cx, |lsp_store, cx| {
 9131                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9132                                })
 9133                                .ok();
 9134                            if let Some(diagnostics_pull) = diagnostics_pull {
 9135                                match diagnostics_pull.await {
 9136                                    Ok(()) => {}
 9137                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9138                                };
 9139                            }
 9140                        }),
 9141                    );
 9142                })?;
 9143            }
 9144            Request::InlayHints(inlay_hints) => {
 9145                let query_start = inlay_hints
 9146                    .start
 9147                    .clone()
 9148                    .and_then(deserialize_anchor)
 9149                    .context("invalid inlay hints range start")?;
 9150                let query_end = inlay_hints
 9151                    .end
 9152                    .clone()
 9153                    .and_then(deserialize_anchor)
 9154                    .context("invalid inlay hints range end")?;
 9155                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9156                    &lsp_store,
 9157                    server_id,
 9158                    lsp_request_id,
 9159                    &inlay_hints,
 9160                    query_start..query_end,
 9161                    &mut cx,
 9162                )
 9163                .await
 9164                .context("preparing inlay hints request")?;
 9165                Self::query_lsp_locally::<InlayHints>(
 9166                    lsp_store,
 9167                    server_id,
 9168                    sender_id,
 9169                    lsp_request_id,
 9170                    inlay_hints,
 9171                    None,
 9172                    &mut cx,
 9173                )
 9174                .await
 9175                .context("querying for inlay hints")?
 9176            }
 9177        }
 9178        Ok(proto::Ack {})
 9179    }
 9180
 9181    async fn handle_lsp_query_response(
 9182        lsp_store: Entity<Self>,
 9183        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9184        cx: AsyncApp,
 9185    ) -> Result<()> {
 9186        lsp_store.read_with(&cx, |lsp_store, _| {
 9187            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9188                upstream_client.handle_lsp_response(envelope.clone());
 9189            }
 9190        })?;
 9191        Ok(())
 9192    }
 9193
 9194    async fn handle_apply_code_action(
 9195        this: Entity<Self>,
 9196        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9197        mut cx: AsyncApp,
 9198    ) -> Result<proto::ApplyCodeActionResponse> {
 9199        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9200        let action =
 9201            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9202        let apply_code_action = this.update(&mut cx, |this, cx| {
 9203            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9204            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9205            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9206        })??;
 9207
 9208        let project_transaction = apply_code_action.await?;
 9209        let project_transaction = this.update(&mut cx, |this, cx| {
 9210            this.buffer_store.update(cx, |buffer_store, cx| {
 9211                buffer_store.serialize_project_transaction_for_peer(
 9212                    project_transaction,
 9213                    sender_id,
 9214                    cx,
 9215                )
 9216            })
 9217        })?;
 9218        Ok(proto::ApplyCodeActionResponse {
 9219            transaction: Some(project_transaction),
 9220        })
 9221    }
 9222
 9223    async fn handle_register_buffer_with_language_servers(
 9224        this: Entity<Self>,
 9225        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9226        mut cx: AsyncApp,
 9227    ) -> Result<proto::Ack> {
 9228        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9229        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9230        this.update(&mut cx, |this, cx| {
 9231            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9232                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9233                    project_id: upstream_project_id,
 9234                    buffer_id: buffer_id.to_proto(),
 9235                    only_servers: envelope.payload.only_servers,
 9236                });
 9237            }
 9238
 9239            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9240                anyhow::bail!("buffer is not open");
 9241            };
 9242
 9243            let handle = this.register_buffer_with_language_servers(
 9244                &buffer,
 9245                envelope
 9246                    .payload
 9247                    .only_servers
 9248                    .into_iter()
 9249                    .filter_map(|selector| {
 9250                        Some(match selector.selector? {
 9251                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9252                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9253                            }
 9254                            proto::language_server_selector::Selector::Name(name) => {
 9255                                LanguageServerSelector::Name(LanguageServerName(
 9256                                    SharedString::from(name),
 9257                                ))
 9258                            }
 9259                        })
 9260                    })
 9261                    .collect(),
 9262                false,
 9263                cx,
 9264            );
 9265            this.buffer_store().update(cx, |buffer_store, _| {
 9266                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9267            });
 9268
 9269            Ok(())
 9270        })??;
 9271        Ok(proto::Ack {})
 9272    }
 9273
 9274    async fn handle_rename_project_entry(
 9275        this: Entity<Self>,
 9276        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9277        mut cx: AsyncApp,
 9278    ) -> Result<proto::ProjectEntryResponse> {
 9279        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9280        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9281        let new_path =
 9282            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9283
 9284        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9285            .update(&mut cx, |this, cx| {
 9286                let (worktree, entry) = this
 9287                    .worktree_store
 9288                    .read(cx)
 9289                    .worktree_and_entry_for_id(entry_id, cx)?;
 9290                let new_worktree = this
 9291                    .worktree_store
 9292                    .read(cx)
 9293                    .worktree_for_id(new_worktree_id, cx)?;
 9294                Some((
 9295                    this.worktree_store.clone(),
 9296                    worktree,
 9297                    new_worktree,
 9298                    entry.clone(),
 9299                ))
 9300            })?
 9301            .context("worktree not found")?;
 9302        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9303            (worktree.absolutize(&old_entry.path), worktree.id())
 9304        })?;
 9305        let new_abs_path =
 9306            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 9307
 9308        let _transaction = Self::will_rename_entry(
 9309            this.downgrade(),
 9310            old_worktree_id,
 9311            &old_abs_path,
 9312            &new_abs_path,
 9313            old_entry.is_dir(),
 9314            cx.clone(),
 9315        )
 9316        .await;
 9317        let response = WorktreeStore::handle_rename_project_entry(
 9318            worktree_store,
 9319            envelope.payload,
 9320            cx.clone(),
 9321        )
 9322        .await;
 9323        this.read_with(&cx, |this, _| {
 9324            this.did_rename_entry(
 9325                old_worktree_id,
 9326                &old_abs_path,
 9327                &new_abs_path,
 9328                old_entry.is_dir(),
 9329            );
 9330        })
 9331        .ok();
 9332        response
 9333    }
 9334
 9335    async fn handle_update_diagnostic_summary(
 9336        this: Entity<Self>,
 9337        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9338        mut cx: AsyncApp,
 9339    ) -> Result<()> {
 9340        this.update(&mut cx, |lsp_store, cx| {
 9341            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9342            let mut updated_diagnostics_paths = HashMap::default();
 9343            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9344            for message_summary in envelope
 9345                .payload
 9346                .summary
 9347                .into_iter()
 9348                .chain(envelope.payload.more_summaries)
 9349            {
 9350                let project_path = ProjectPath {
 9351                    worktree_id,
 9352                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9353                };
 9354                let path = project_path.path.clone();
 9355                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9356                let summary = DiagnosticSummary {
 9357                    error_count: message_summary.error_count as usize,
 9358                    warning_count: message_summary.warning_count as usize,
 9359                };
 9360
 9361                if summary.is_empty() {
 9362                    if let Some(worktree_summaries) =
 9363                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9364                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9365                    {
 9366                        summaries.remove(&server_id);
 9367                        if summaries.is_empty() {
 9368                            worktree_summaries.remove(&path);
 9369                        }
 9370                    }
 9371                } else {
 9372                    lsp_store
 9373                        .diagnostic_summaries
 9374                        .entry(worktree_id)
 9375                        .or_default()
 9376                        .entry(path)
 9377                        .or_default()
 9378                        .insert(server_id, summary);
 9379                }
 9380
 9381                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9382                    match &mut diagnostics_summary {
 9383                        Some(diagnostics_summary) => {
 9384                            diagnostics_summary
 9385                                .more_summaries
 9386                                .push(proto::DiagnosticSummary {
 9387                                    path: project_path.path.as_ref().to_proto(),
 9388                                    language_server_id: server_id.0 as u64,
 9389                                    error_count: summary.error_count as u32,
 9390                                    warning_count: summary.warning_count as u32,
 9391                                })
 9392                        }
 9393                        None => {
 9394                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9395                                project_id: *project_id,
 9396                                worktree_id: worktree_id.to_proto(),
 9397                                summary: Some(proto::DiagnosticSummary {
 9398                                    path: project_path.path.as_ref().to_proto(),
 9399                                    language_server_id: server_id.0 as u64,
 9400                                    error_count: summary.error_count as u32,
 9401                                    warning_count: summary.warning_count as u32,
 9402                                }),
 9403                                more_summaries: Vec::new(),
 9404                            })
 9405                        }
 9406                    }
 9407                }
 9408                updated_diagnostics_paths
 9409                    .entry(server_id)
 9410                    .or_insert_with(Vec::new)
 9411                    .push(project_path);
 9412            }
 9413
 9414            if let Some((diagnostics_summary, (downstream_client, _))) =
 9415                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9416            {
 9417                downstream_client.send(diagnostics_summary).log_err();
 9418            }
 9419            for (server_id, paths) in updated_diagnostics_paths {
 9420                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9421            }
 9422            Ok(())
 9423        })?
 9424    }
 9425
 9426    async fn handle_start_language_server(
 9427        lsp_store: Entity<Self>,
 9428        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9429        mut cx: AsyncApp,
 9430    ) -> Result<()> {
 9431        let server = envelope.payload.server.context("invalid server")?;
 9432        let server_capabilities =
 9433            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9434                .with_context(|| {
 9435                    format!(
 9436                        "incorrect server capabilities {}",
 9437                        envelope.payload.capabilities
 9438                    )
 9439                })?;
 9440        lsp_store.update(&mut cx, |lsp_store, cx| {
 9441            let server_id = LanguageServerId(server.id as usize);
 9442            let server_name = LanguageServerName::from_proto(server.name.clone());
 9443            lsp_store
 9444                .lsp_server_capabilities
 9445                .insert(server_id, server_capabilities);
 9446            lsp_store.language_server_statuses.insert(
 9447                server_id,
 9448                LanguageServerStatus {
 9449                    name: server_name.clone(),
 9450                    server_version: None,
 9451                    pending_work: Default::default(),
 9452                    has_pending_diagnostic_updates: false,
 9453                    progress_tokens: Default::default(),
 9454                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9455                    binary: None,
 9456                    configuration: None,
 9457                    workspace_folders: BTreeSet::new(),
 9458                },
 9459            );
 9460            cx.emit(LspStoreEvent::LanguageServerAdded(
 9461                server_id,
 9462                server_name,
 9463                server.worktree_id.map(WorktreeId::from_proto),
 9464            ));
 9465            cx.notify();
 9466        })?;
 9467        Ok(())
 9468    }
 9469
 9470    async fn handle_update_language_server(
 9471        lsp_store: Entity<Self>,
 9472        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9473        mut cx: AsyncApp,
 9474    ) -> Result<()> {
 9475        lsp_store.update(&mut cx, |lsp_store, cx| {
 9476            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9477
 9478            match envelope.payload.variant.context("invalid variant")? {
 9479                proto::update_language_server::Variant::WorkStart(payload) => {
 9480                    lsp_store.on_lsp_work_start(
 9481                        language_server_id,
 9482                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9483                            .context("invalid progress token value")?,
 9484                        LanguageServerProgress {
 9485                            title: payload.title,
 9486                            is_disk_based_diagnostics_progress: false,
 9487                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9488                            message: payload.message,
 9489                            percentage: payload.percentage.map(|p| p as usize),
 9490                            last_update_at: cx.background_executor().now(),
 9491                        },
 9492                        cx,
 9493                    );
 9494                }
 9495                proto::update_language_server::Variant::WorkProgress(payload) => {
 9496                    lsp_store.on_lsp_work_progress(
 9497                        language_server_id,
 9498                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9499                            .context("invalid progress token value")?,
 9500                        LanguageServerProgress {
 9501                            title: None,
 9502                            is_disk_based_diagnostics_progress: false,
 9503                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9504                            message: payload.message,
 9505                            percentage: payload.percentage.map(|p| p as usize),
 9506                            last_update_at: cx.background_executor().now(),
 9507                        },
 9508                        cx,
 9509                    );
 9510                }
 9511
 9512                proto::update_language_server::Variant::WorkEnd(payload) => {
 9513                    lsp_store.on_lsp_work_end(
 9514                        language_server_id,
 9515                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9516                            .context("invalid progress token value")?,
 9517                        cx,
 9518                    );
 9519                }
 9520
 9521                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9522                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9523                }
 9524
 9525                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9526                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9527                }
 9528
 9529                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9530                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9531                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9532                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9533                        language_server_id,
 9534                        name: envelope
 9535                            .payload
 9536                            .server_name
 9537                            .map(SharedString::new)
 9538                            .map(LanguageServerName),
 9539                        message: non_lsp,
 9540                    });
 9541                }
 9542            }
 9543
 9544            Ok(())
 9545        })?
 9546    }
 9547
 9548    async fn handle_language_server_log(
 9549        this: Entity<Self>,
 9550        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9551        mut cx: AsyncApp,
 9552    ) -> Result<()> {
 9553        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9554        let log_type = envelope
 9555            .payload
 9556            .log_type
 9557            .map(LanguageServerLogType::from_proto)
 9558            .context("invalid language server log type")?;
 9559
 9560        let message = envelope.payload.message;
 9561
 9562        this.update(&mut cx, |_, cx| {
 9563            cx.emit(LspStoreEvent::LanguageServerLog(
 9564                language_server_id,
 9565                log_type,
 9566                message,
 9567            ));
 9568        })
 9569    }
 9570
 9571    async fn handle_lsp_ext_cancel_flycheck(
 9572        lsp_store: Entity<Self>,
 9573        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9574        cx: AsyncApp,
 9575    ) -> Result<proto::Ack> {
 9576        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9577        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9578            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9579                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9580            } else {
 9581                None
 9582            }
 9583        })?;
 9584        if let Some(task) = task {
 9585            task.context("handling lsp ext cancel flycheck")?;
 9586        }
 9587
 9588        Ok(proto::Ack {})
 9589    }
 9590
 9591    async fn handle_lsp_ext_run_flycheck(
 9592        lsp_store: Entity<Self>,
 9593        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9594        mut cx: AsyncApp,
 9595    ) -> Result<proto::Ack> {
 9596        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9597        lsp_store.update(&mut cx, |lsp_store, cx| {
 9598            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9599                let text_document = if envelope.payload.current_file_only {
 9600                    let buffer_id = envelope
 9601                        .payload
 9602                        .buffer_id
 9603                        .map(|id| BufferId::new(id))
 9604                        .transpose()?;
 9605                    buffer_id
 9606                        .and_then(|buffer_id| {
 9607                            lsp_store
 9608                                .buffer_store()
 9609                                .read(cx)
 9610                                .get(buffer_id)
 9611                                .and_then(|buffer| {
 9612                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9613                                })
 9614                                .map(|path| make_text_document_identifier(&path))
 9615                        })
 9616                        .transpose()?
 9617                } else {
 9618                    None
 9619                };
 9620                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9621                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9622                )?;
 9623            }
 9624            anyhow::Ok(())
 9625        })??;
 9626
 9627        Ok(proto::Ack {})
 9628    }
 9629
 9630    async fn handle_lsp_ext_clear_flycheck(
 9631        lsp_store: Entity<Self>,
 9632        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9633        cx: AsyncApp,
 9634    ) -> Result<proto::Ack> {
 9635        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9636        lsp_store
 9637            .read_with(&cx, |lsp_store, _| {
 9638                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9639                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9640                } else {
 9641                    None
 9642                }
 9643            })
 9644            .context("handling lsp ext clear flycheck")?;
 9645
 9646        Ok(proto::Ack {})
 9647    }
 9648
 9649    pub fn disk_based_diagnostics_started(
 9650        &mut self,
 9651        language_server_id: LanguageServerId,
 9652        cx: &mut Context<Self>,
 9653    ) {
 9654        if let Some(language_server_status) =
 9655            self.language_server_statuses.get_mut(&language_server_id)
 9656        {
 9657            language_server_status.has_pending_diagnostic_updates = true;
 9658        }
 9659
 9660        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9661        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9662            language_server_id,
 9663            name: self
 9664                .language_server_adapter_for_id(language_server_id)
 9665                .map(|adapter| adapter.name()),
 9666            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9667                Default::default(),
 9668            ),
 9669        })
 9670    }
 9671
 9672    pub fn disk_based_diagnostics_finished(
 9673        &mut self,
 9674        language_server_id: LanguageServerId,
 9675        cx: &mut Context<Self>,
 9676    ) {
 9677        if let Some(language_server_status) =
 9678            self.language_server_statuses.get_mut(&language_server_id)
 9679        {
 9680            language_server_status.has_pending_diagnostic_updates = false;
 9681        }
 9682
 9683        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9684        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9685            language_server_id,
 9686            name: self
 9687                .language_server_adapter_for_id(language_server_id)
 9688                .map(|adapter| adapter.name()),
 9689            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9690                Default::default(),
 9691            ),
 9692        })
 9693    }
 9694
 9695    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9696    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9697    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9698    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9699    // the language server might take some time to publish diagnostics.
 9700    fn simulate_disk_based_diagnostics_events_if_needed(
 9701        &mut self,
 9702        language_server_id: LanguageServerId,
 9703        cx: &mut Context<Self>,
 9704    ) {
 9705        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9706
 9707        let Some(LanguageServerState::Running {
 9708            simulate_disk_based_diagnostics_completion,
 9709            adapter,
 9710            ..
 9711        }) = self
 9712            .as_local_mut()
 9713            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9714        else {
 9715            return;
 9716        };
 9717
 9718        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9719            return;
 9720        }
 9721
 9722        let prev_task =
 9723            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9724                cx.background_executor()
 9725                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9726                    .await;
 9727
 9728                this.update(cx, |this, cx| {
 9729                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9730
 9731                    if let Some(LanguageServerState::Running {
 9732                        simulate_disk_based_diagnostics_completion,
 9733                        ..
 9734                    }) = this.as_local_mut().and_then(|local_store| {
 9735                        local_store.language_servers.get_mut(&language_server_id)
 9736                    }) {
 9737                        *simulate_disk_based_diagnostics_completion = None;
 9738                    }
 9739                })
 9740                .ok();
 9741            }));
 9742
 9743        if prev_task.is_none() {
 9744            self.disk_based_diagnostics_started(language_server_id, cx);
 9745        }
 9746    }
 9747
 9748    pub fn language_server_statuses(
 9749        &self,
 9750    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9751        self.language_server_statuses
 9752            .iter()
 9753            .map(|(key, value)| (*key, value))
 9754    }
 9755
 9756    pub(super) fn did_rename_entry(
 9757        &self,
 9758        worktree_id: WorktreeId,
 9759        old_path: &Path,
 9760        new_path: &Path,
 9761        is_dir: bool,
 9762    ) {
 9763        maybe!({
 9764            let local_store = self.as_local()?;
 9765
 9766            let old_uri = lsp::Uri::from_file_path(old_path)
 9767                .ok()
 9768                .map(|uri| uri.to_string())?;
 9769            let new_uri = lsp::Uri::from_file_path(new_path)
 9770                .ok()
 9771                .map(|uri| uri.to_string())?;
 9772
 9773            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9774                let Some(filter) = local_store
 9775                    .language_server_paths_watched_for_rename
 9776                    .get(&language_server.server_id())
 9777                else {
 9778                    continue;
 9779                };
 9780
 9781                if filter.should_send_did_rename(&old_uri, is_dir) {
 9782                    language_server
 9783                        .notify::<DidRenameFiles>(RenameFilesParams {
 9784                            files: vec![FileRename {
 9785                                old_uri: old_uri.clone(),
 9786                                new_uri: new_uri.clone(),
 9787                            }],
 9788                        })
 9789                        .ok();
 9790                }
 9791            }
 9792            Some(())
 9793        });
 9794    }
 9795
 9796    pub(super) fn will_rename_entry(
 9797        this: WeakEntity<Self>,
 9798        worktree_id: WorktreeId,
 9799        old_path: &Path,
 9800        new_path: &Path,
 9801        is_dir: bool,
 9802        cx: AsyncApp,
 9803    ) -> Task<ProjectTransaction> {
 9804        let old_uri = lsp::Uri::from_file_path(old_path)
 9805            .ok()
 9806            .map(|uri| uri.to_string());
 9807        let new_uri = lsp::Uri::from_file_path(new_path)
 9808            .ok()
 9809            .map(|uri| uri.to_string());
 9810        cx.spawn(async move |cx| {
 9811            let mut tasks = vec![];
 9812            this.update(cx, |this, cx| {
 9813                let local_store = this.as_local()?;
 9814                let old_uri = old_uri?;
 9815                let new_uri = new_uri?;
 9816                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9817                    let Some(filter) = local_store
 9818                        .language_server_paths_watched_for_rename
 9819                        .get(&language_server.server_id())
 9820                    else {
 9821                        continue;
 9822                    };
 9823
 9824                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9825                        let apply_edit = cx.spawn({
 9826                            let old_uri = old_uri.clone();
 9827                            let new_uri = new_uri.clone();
 9828                            let language_server = language_server.clone();
 9829                            async move |this, cx| {
 9830                                let edit = language_server
 9831                                    .request::<WillRenameFiles>(RenameFilesParams {
 9832                                        files: vec![FileRename { old_uri, new_uri }],
 9833                                    })
 9834                                    .await
 9835                                    .into_response()
 9836                                    .context("will rename files")
 9837                                    .log_err()
 9838                                    .flatten()?;
 9839
 9840                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9841                                    this.upgrade()?,
 9842                                    edit,
 9843                                    false,
 9844                                    language_server.clone(),
 9845                                    cx,
 9846                                )
 9847                                .await
 9848                                .ok()?;
 9849                                Some(transaction)
 9850                            }
 9851                        });
 9852                        tasks.push(apply_edit);
 9853                    }
 9854                }
 9855                Some(())
 9856            })
 9857            .ok()
 9858            .flatten();
 9859            let mut merged_transaction = ProjectTransaction::default();
 9860            for task in tasks {
 9861                // Await on tasks sequentially so that the order of application of edits is deterministic
 9862                // (at least with regards to the order of registration of language servers)
 9863                if let Some(transaction) = task.await {
 9864                    for (buffer, buffer_transaction) in transaction.0 {
 9865                        merged_transaction.0.insert(buffer, buffer_transaction);
 9866                    }
 9867                }
 9868            }
 9869            merged_transaction
 9870        })
 9871    }
 9872
 9873    fn lsp_notify_abs_paths_changed(
 9874        &mut self,
 9875        server_id: LanguageServerId,
 9876        changes: Vec<PathEvent>,
 9877    ) {
 9878        maybe!({
 9879            let server = self.language_server_for_id(server_id)?;
 9880            let changes = changes
 9881                .into_iter()
 9882                .filter_map(|event| {
 9883                    let typ = match event.kind? {
 9884                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9885                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9886                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9887                    };
 9888                    Some(lsp::FileEvent {
 9889                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9890                        typ,
 9891                    })
 9892                })
 9893                .collect::<Vec<_>>();
 9894            if !changes.is_empty() {
 9895                server
 9896                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9897                        lsp::DidChangeWatchedFilesParams { changes },
 9898                    )
 9899                    .ok();
 9900            }
 9901            Some(())
 9902        });
 9903    }
 9904
 9905    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9906        self.as_local()?.language_server_for_id(id)
 9907    }
 9908
 9909    fn on_lsp_progress(
 9910        &mut self,
 9911        progress_params: lsp::ProgressParams,
 9912        language_server_id: LanguageServerId,
 9913        disk_based_diagnostics_progress_token: Option<String>,
 9914        cx: &mut Context<Self>,
 9915    ) {
 9916        match progress_params.value {
 9917            lsp::ProgressParamsValue::WorkDone(progress) => {
 9918                self.handle_work_done_progress(
 9919                    progress,
 9920                    language_server_id,
 9921                    disk_based_diagnostics_progress_token,
 9922                    ProgressToken::from_lsp(progress_params.token),
 9923                    cx,
 9924                );
 9925            }
 9926            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9927                let registration_id = match progress_params.token {
 9928                    lsp::NumberOrString::Number(_) => None,
 9929                    lsp::NumberOrString::String(token) => token
 9930                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9931                        .map(|(_, id)| id.to_owned()),
 9932                };
 9933                if let Some(LanguageServerState::Running {
 9934                    workspace_diagnostics_refresh_tasks,
 9935                    ..
 9936                }) = self
 9937                    .as_local_mut()
 9938                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9939                    && let Some(workspace_diagnostics) =
 9940                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9941                {
 9942                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9943                    self.apply_workspace_diagnostic_report(
 9944                        language_server_id,
 9945                        report,
 9946                        registration_id.map(SharedString::from),
 9947                        cx,
 9948                    )
 9949                }
 9950            }
 9951        }
 9952    }
 9953
 9954    fn handle_work_done_progress(
 9955        &mut self,
 9956        progress: lsp::WorkDoneProgress,
 9957        language_server_id: LanguageServerId,
 9958        disk_based_diagnostics_progress_token: Option<String>,
 9959        token: ProgressToken,
 9960        cx: &mut Context<Self>,
 9961    ) {
 9962        let language_server_status =
 9963            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9964                status
 9965            } else {
 9966                return;
 9967            };
 9968
 9969        if !language_server_status.progress_tokens.contains(&token) {
 9970            return;
 9971        }
 9972
 9973        let is_disk_based_diagnostics_progress =
 9974            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9975                (&disk_based_diagnostics_progress_token, &token)
 9976            {
 9977                token.starts_with(disk_based_token)
 9978            } else {
 9979                false
 9980            };
 9981
 9982        match progress {
 9983            lsp::WorkDoneProgress::Begin(report) => {
 9984                if is_disk_based_diagnostics_progress {
 9985                    self.disk_based_diagnostics_started(language_server_id, cx);
 9986                }
 9987                self.on_lsp_work_start(
 9988                    language_server_id,
 9989                    token.clone(),
 9990                    LanguageServerProgress {
 9991                        title: Some(report.title),
 9992                        is_disk_based_diagnostics_progress,
 9993                        is_cancellable: report.cancellable.unwrap_or(false),
 9994                        message: report.message.clone(),
 9995                        percentage: report.percentage.map(|p| p as usize),
 9996                        last_update_at: cx.background_executor().now(),
 9997                    },
 9998                    cx,
 9999                );
10000            }
10001            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10002                language_server_id,
10003                token,
10004                LanguageServerProgress {
10005                    title: None,
10006                    is_disk_based_diagnostics_progress,
10007                    is_cancellable: report.cancellable.unwrap_or(false),
10008                    message: report.message,
10009                    percentage: report.percentage.map(|p| p as usize),
10010                    last_update_at: cx.background_executor().now(),
10011                },
10012                cx,
10013            ),
10014            lsp::WorkDoneProgress::End(_) => {
10015                language_server_status.progress_tokens.remove(&token);
10016                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10017                if is_disk_based_diagnostics_progress {
10018                    self.disk_based_diagnostics_finished(language_server_id, cx);
10019                }
10020            }
10021        }
10022    }
10023
10024    fn on_lsp_work_start(
10025        &mut self,
10026        language_server_id: LanguageServerId,
10027        token: ProgressToken,
10028        progress: LanguageServerProgress,
10029        cx: &mut Context<Self>,
10030    ) {
10031        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10032            status.pending_work.insert(token.clone(), progress.clone());
10033            cx.notify();
10034        }
10035        cx.emit(LspStoreEvent::LanguageServerUpdate {
10036            language_server_id,
10037            name: self
10038                .language_server_adapter_for_id(language_server_id)
10039                .map(|adapter| adapter.name()),
10040            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10041                token: Some(token.to_proto()),
10042                title: progress.title,
10043                message: progress.message,
10044                percentage: progress.percentage.map(|p| p as u32),
10045                is_cancellable: Some(progress.is_cancellable),
10046            }),
10047        })
10048    }
10049
10050    fn on_lsp_work_progress(
10051        &mut self,
10052        language_server_id: LanguageServerId,
10053        token: ProgressToken,
10054        progress: LanguageServerProgress,
10055        cx: &mut Context<Self>,
10056    ) {
10057        let mut did_update = false;
10058        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10059            match status.pending_work.entry(token.clone()) {
10060                btree_map::Entry::Vacant(entry) => {
10061                    entry.insert(progress.clone());
10062                    did_update = true;
10063                }
10064                btree_map::Entry::Occupied(mut entry) => {
10065                    let entry = entry.get_mut();
10066                    if (progress.last_update_at - entry.last_update_at)
10067                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10068                    {
10069                        entry.last_update_at = progress.last_update_at;
10070                        if progress.message.is_some() {
10071                            entry.message = progress.message.clone();
10072                        }
10073                        if progress.percentage.is_some() {
10074                            entry.percentage = progress.percentage;
10075                        }
10076                        if progress.is_cancellable != entry.is_cancellable {
10077                            entry.is_cancellable = progress.is_cancellable;
10078                        }
10079                        did_update = true;
10080                    }
10081                }
10082            }
10083        }
10084
10085        if did_update {
10086            cx.emit(LspStoreEvent::LanguageServerUpdate {
10087                language_server_id,
10088                name: self
10089                    .language_server_adapter_for_id(language_server_id)
10090                    .map(|adapter| adapter.name()),
10091                message: proto::update_language_server::Variant::WorkProgress(
10092                    proto::LspWorkProgress {
10093                        token: Some(token.to_proto()),
10094                        message: progress.message,
10095                        percentage: progress.percentage.map(|p| p as u32),
10096                        is_cancellable: Some(progress.is_cancellable),
10097                    },
10098                ),
10099            })
10100        }
10101    }
10102
10103    fn on_lsp_work_end(
10104        &mut self,
10105        language_server_id: LanguageServerId,
10106        token: ProgressToken,
10107        cx: &mut Context<Self>,
10108    ) {
10109        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10110            if let Some(work) = status.pending_work.remove(&token)
10111                && !work.is_disk_based_diagnostics_progress
10112            {
10113                cx.emit(LspStoreEvent::RefreshInlayHints {
10114                    server_id: language_server_id,
10115                    request_id: None,
10116                });
10117            }
10118            cx.notify();
10119        }
10120
10121        cx.emit(LspStoreEvent::LanguageServerUpdate {
10122            language_server_id,
10123            name: self
10124                .language_server_adapter_for_id(language_server_id)
10125                .map(|adapter| adapter.name()),
10126            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10127                token: Some(token.to_proto()),
10128            }),
10129        })
10130    }
10131
10132    pub async fn handle_resolve_completion_documentation(
10133        this: Entity<Self>,
10134        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10135        mut cx: AsyncApp,
10136    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10137        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10138
10139        let completion = this
10140            .read_with(&cx, |this, cx| {
10141                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10142                let server = this
10143                    .language_server_for_id(id)
10144                    .with_context(|| format!("No language server {id}"))?;
10145
10146                anyhow::Ok(cx.background_spawn(async move {
10147                    let can_resolve = server
10148                        .capabilities()
10149                        .completion_provider
10150                        .as_ref()
10151                        .and_then(|options| options.resolve_provider)
10152                        .unwrap_or(false);
10153                    if can_resolve {
10154                        server
10155                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
10156                            .await
10157                            .into_response()
10158                            .context("resolve completion item")
10159                    } else {
10160                        anyhow::Ok(lsp_completion)
10161                    }
10162                }))
10163            })??
10164            .await?;
10165
10166        let mut documentation_is_markdown = false;
10167        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10168        let documentation = match completion.documentation {
10169            Some(lsp::Documentation::String(text)) => text,
10170
10171            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10172                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10173                value
10174            }
10175
10176            _ => String::new(),
10177        };
10178
10179        // If we have a new buffer_id, that means we're talking to a new client
10180        // and want to check for new text_edits in the completion too.
10181        let mut old_replace_start = None;
10182        let mut old_replace_end = None;
10183        let mut old_insert_start = None;
10184        let mut old_insert_end = None;
10185        let mut new_text = String::default();
10186        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10187            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10188                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10189                anyhow::Ok(buffer.read(cx).snapshot())
10190            })??;
10191
10192            if let Some(text_edit) = completion.text_edit.as_ref() {
10193                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10194
10195                if let Some(mut edit) = edit {
10196                    LineEnding::normalize(&mut edit.new_text);
10197
10198                    new_text = edit.new_text;
10199                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10200                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10201                    if let Some(insert_range) = edit.insert_range {
10202                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10203                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10204                    }
10205                }
10206            }
10207        }
10208
10209        Ok(proto::ResolveCompletionDocumentationResponse {
10210            documentation,
10211            documentation_is_markdown,
10212            old_replace_start,
10213            old_replace_end,
10214            new_text,
10215            lsp_completion,
10216            old_insert_start,
10217            old_insert_end,
10218        })
10219    }
10220
10221    async fn handle_on_type_formatting(
10222        this: Entity<Self>,
10223        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10224        mut cx: AsyncApp,
10225    ) -> Result<proto::OnTypeFormattingResponse> {
10226        let on_type_formatting = this.update(&mut cx, |this, cx| {
10227            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10228            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10229            let position = envelope
10230                .payload
10231                .position
10232                .and_then(deserialize_anchor)
10233                .context("invalid position")?;
10234            anyhow::Ok(this.apply_on_type_formatting(
10235                buffer,
10236                position,
10237                envelope.payload.trigger.clone(),
10238                cx,
10239            ))
10240        })??;
10241
10242        let transaction = on_type_formatting
10243            .await?
10244            .as_ref()
10245            .map(language::proto::serialize_transaction);
10246        Ok(proto::OnTypeFormattingResponse { transaction })
10247    }
10248
10249    async fn handle_refresh_inlay_hints(
10250        lsp_store: Entity<Self>,
10251        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10252        mut cx: AsyncApp,
10253    ) -> Result<proto::Ack> {
10254        lsp_store.update(&mut cx, |_, cx| {
10255            cx.emit(LspStoreEvent::RefreshInlayHints {
10256                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10257                request_id: envelope.payload.request_id.map(|id| id as usize),
10258            });
10259        })?;
10260        Ok(proto::Ack {})
10261    }
10262
10263    async fn handle_pull_workspace_diagnostics(
10264        lsp_store: Entity<Self>,
10265        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10266        mut cx: AsyncApp,
10267    ) -> Result<proto::Ack> {
10268        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10269        lsp_store.update(&mut cx, |lsp_store, _| {
10270            lsp_store.pull_workspace_diagnostics(server_id);
10271        })?;
10272        Ok(proto::Ack {})
10273    }
10274
10275    async fn handle_get_color_presentation(
10276        lsp_store: Entity<Self>,
10277        envelope: TypedEnvelope<proto::GetColorPresentation>,
10278        mut cx: AsyncApp,
10279    ) -> Result<proto::GetColorPresentationResponse> {
10280        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10281        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10282            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10283        })??;
10284
10285        let color = envelope
10286            .payload
10287            .color
10288            .context("invalid color resolve request")?;
10289        let start = color
10290            .lsp_range_start
10291            .context("invalid color resolve request")?;
10292        let end = color
10293            .lsp_range_end
10294            .context("invalid color resolve request")?;
10295
10296        let color = DocumentColor {
10297            lsp_range: lsp::Range {
10298                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10299                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10300            },
10301            color: lsp::Color {
10302                red: color.red,
10303                green: color.green,
10304                blue: color.blue,
10305                alpha: color.alpha,
10306            },
10307            resolved: false,
10308            color_presentations: Vec::new(),
10309        };
10310        let resolved_color = lsp_store
10311            .update(&mut cx, |lsp_store, cx| {
10312                lsp_store.resolve_color_presentation(
10313                    color,
10314                    buffer.clone(),
10315                    LanguageServerId(envelope.payload.server_id as usize),
10316                    cx,
10317                )
10318            })?
10319            .await
10320            .context("resolving color presentation")?;
10321
10322        Ok(proto::GetColorPresentationResponse {
10323            presentations: resolved_color
10324                .color_presentations
10325                .into_iter()
10326                .map(|presentation| proto::ColorPresentation {
10327                    label: presentation.label.to_string(),
10328                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10329                    additional_text_edits: presentation
10330                        .additional_text_edits
10331                        .into_iter()
10332                        .map(serialize_lsp_edit)
10333                        .collect(),
10334                })
10335                .collect(),
10336        })
10337    }
10338
10339    async fn handle_resolve_inlay_hint(
10340        lsp_store: Entity<Self>,
10341        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10342        mut cx: AsyncApp,
10343    ) -> Result<proto::ResolveInlayHintResponse> {
10344        let proto_hint = envelope
10345            .payload
10346            .hint
10347            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10348        let hint = InlayHints::proto_to_project_hint(proto_hint)
10349            .context("resolved proto inlay hint conversion")?;
10350        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10351            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10352            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10353        })??;
10354        let response_hint = lsp_store
10355            .update(&mut cx, |lsp_store, cx| {
10356                lsp_store.resolve_inlay_hint(
10357                    hint,
10358                    buffer,
10359                    LanguageServerId(envelope.payload.language_server_id as usize),
10360                    cx,
10361                )
10362            })?
10363            .await
10364            .context("inlay hints fetch")?;
10365        Ok(proto::ResolveInlayHintResponse {
10366            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10367        })
10368    }
10369
10370    async fn handle_refresh_code_lens(
10371        this: Entity<Self>,
10372        _: TypedEnvelope<proto::RefreshCodeLens>,
10373        mut cx: AsyncApp,
10374    ) -> Result<proto::Ack> {
10375        this.update(&mut cx, |_, cx| {
10376            cx.emit(LspStoreEvent::RefreshCodeLens);
10377        })?;
10378        Ok(proto::Ack {})
10379    }
10380
10381    async fn handle_open_buffer_for_symbol(
10382        this: Entity<Self>,
10383        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10384        mut cx: AsyncApp,
10385    ) -> Result<proto::OpenBufferForSymbolResponse> {
10386        let peer_id = envelope.original_sender_id().unwrap_or_default();
10387        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10388        let symbol = Self::deserialize_symbol(symbol)?;
10389        this.read_with(&cx, |this, _| {
10390            if let SymbolLocation::OutsideProject {
10391                abs_path,
10392                signature,
10393            } = &symbol.path
10394            {
10395                let new_signature = this.symbol_signature(&abs_path);
10396                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10397            }
10398            Ok(())
10399        })??;
10400        let buffer = this
10401            .update(&mut cx, |this, cx| {
10402                this.open_buffer_for_symbol(
10403                    &Symbol {
10404                        language_server_name: symbol.language_server_name,
10405                        source_worktree_id: symbol.source_worktree_id,
10406                        source_language_server_id: symbol.source_language_server_id,
10407                        path: symbol.path,
10408                        name: symbol.name,
10409                        kind: symbol.kind,
10410                        range: symbol.range,
10411                        label: CodeLabel::default(),
10412                    },
10413                    cx,
10414                )
10415            })?
10416            .await?;
10417
10418        this.update(&mut cx, |this, cx| {
10419            let is_private = buffer
10420                .read(cx)
10421                .file()
10422                .map(|f| f.is_private())
10423                .unwrap_or_default();
10424            if is_private {
10425                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10426            } else {
10427                this.buffer_store
10428                    .update(cx, |buffer_store, cx| {
10429                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10430                    })
10431                    .detach_and_log_err(cx);
10432                let buffer_id = buffer.read(cx).remote_id().to_proto();
10433                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10434            }
10435        })?
10436    }
10437
10438    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10439        let mut hasher = Sha256::new();
10440        hasher.update(abs_path.to_string_lossy().as_bytes());
10441        hasher.update(self.nonce.to_be_bytes());
10442        hasher.finalize().as_slice().try_into().unwrap()
10443    }
10444
10445    pub async fn handle_get_project_symbols(
10446        this: Entity<Self>,
10447        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10448        mut cx: AsyncApp,
10449    ) -> Result<proto::GetProjectSymbolsResponse> {
10450        let symbols = this
10451            .update(&mut cx, |this, cx| {
10452                this.symbols(&envelope.payload.query, cx)
10453            })?
10454            .await?;
10455
10456        Ok(proto::GetProjectSymbolsResponse {
10457            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10458        })
10459    }
10460
10461    pub async fn handle_restart_language_servers(
10462        this: Entity<Self>,
10463        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10464        mut cx: AsyncApp,
10465    ) -> Result<proto::Ack> {
10466        this.update(&mut cx, |lsp_store, cx| {
10467            let buffers =
10468                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10469            lsp_store.restart_language_servers_for_buffers(
10470                buffers,
10471                envelope
10472                    .payload
10473                    .only_servers
10474                    .into_iter()
10475                    .filter_map(|selector| {
10476                        Some(match selector.selector? {
10477                            proto::language_server_selector::Selector::ServerId(server_id) => {
10478                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10479                            }
10480                            proto::language_server_selector::Selector::Name(name) => {
10481                                LanguageServerSelector::Name(LanguageServerName(
10482                                    SharedString::from(name),
10483                                ))
10484                            }
10485                        })
10486                    })
10487                    .collect(),
10488                cx,
10489            );
10490        })?;
10491
10492        Ok(proto::Ack {})
10493    }
10494
10495    pub async fn handle_stop_language_servers(
10496        lsp_store: Entity<Self>,
10497        envelope: TypedEnvelope<proto::StopLanguageServers>,
10498        mut cx: AsyncApp,
10499    ) -> Result<proto::Ack> {
10500        lsp_store.update(&mut cx, |lsp_store, cx| {
10501            if envelope.payload.all
10502                && envelope.payload.also_servers.is_empty()
10503                && envelope.payload.buffer_ids.is_empty()
10504            {
10505                lsp_store.stop_all_language_servers(cx);
10506            } else {
10507                let buffers =
10508                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10509                lsp_store
10510                    .stop_language_servers_for_buffers(
10511                        buffers,
10512                        envelope
10513                            .payload
10514                            .also_servers
10515                            .into_iter()
10516                            .filter_map(|selector| {
10517                                Some(match selector.selector? {
10518                                    proto::language_server_selector::Selector::ServerId(
10519                                        server_id,
10520                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10521                                        server_id,
10522                                    )),
10523                                    proto::language_server_selector::Selector::Name(name) => {
10524                                        LanguageServerSelector::Name(LanguageServerName(
10525                                            SharedString::from(name),
10526                                        ))
10527                                    }
10528                                })
10529                            })
10530                            .collect(),
10531                        cx,
10532                    )
10533                    .detach_and_log_err(cx);
10534            }
10535        })?;
10536
10537        Ok(proto::Ack {})
10538    }
10539
10540    pub async fn handle_cancel_language_server_work(
10541        lsp_store: Entity<Self>,
10542        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10543        mut cx: AsyncApp,
10544    ) -> Result<proto::Ack> {
10545        lsp_store.update(&mut cx, |lsp_store, cx| {
10546            if let Some(work) = envelope.payload.work {
10547                match work {
10548                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10549                        let buffers =
10550                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10551                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10552                    }
10553                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10554                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10555                        let token = work
10556                            .token
10557                            .map(|token| {
10558                                ProgressToken::from_proto(token)
10559                                    .context("invalid work progress token")
10560                            })
10561                            .transpose()?;
10562                        lsp_store.cancel_language_server_work(server_id, token, cx);
10563                    }
10564                }
10565            }
10566            anyhow::Ok(())
10567        })??;
10568
10569        Ok(proto::Ack {})
10570    }
10571
10572    fn buffer_ids_to_buffers(
10573        &mut self,
10574        buffer_ids: impl Iterator<Item = u64>,
10575        cx: &mut Context<Self>,
10576    ) -> Vec<Entity<Buffer>> {
10577        buffer_ids
10578            .into_iter()
10579            .flat_map(|buffer_id| {
10580                self.buffer_store
10581                    .read(cx)
10582                    .get(BufferId::new(buffer_id).log_err()?)
10583            })
10584            .collect::<Vec<_>>()
10585    }
10586
10587    async fn handle_apply_additional_edits_for_completion(
10588        this: Entity<Self>,
10589        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10590        mut cx: AsyncApp,
10591    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10592        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10593            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10594            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10595            let completion = Self::deserialize_completion(
10596                envelope.payload.completion.context("invalid completion")?,
10597            )?;
10598            anyhow::Ok((buffer, completion))
10599        })??;
10600
10601        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10602            this.apply_additional_edits_for_completion(
10603                buffer,
10604                Rc::new(RefCell::new(Box::new([Completion {
10605                    replace_range: completion.replace_range,
10606                    new_text: completion.new_text,
10607                    source: completion.source,
10608                    documentation: None,
10609                    label: CodeLabel::default(),
10610                    match_start: None,
10611                    snippet_deduplication_key: None,
10612                    insert_text_mode: None,
10613                    icon_path: None,
10614                    confirm: None,
10615                }]))),
10616                0,
10617                false,
10618                cx,
10619            )
10620        })?;
10621
10622        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10623            transaction: apply_additional_edits
10624                .await?
10625                .as_ref()
10626                .map(language::proto::serialize_transaction),
10627        })
10628    }
10629
10630    pub fn last_formatting_failure(&self) -> Option<&str> {
10631        self.last_formatting_failure.as_deref()
10632    }
10633
10634    pub fn reset_last_formatting_failure(&mut self) {
10635        self.last_formatting_failure = None;
10636    }
10637
10638    pub fn environment_for_buffer(
10639        &self,
10640        buffer: &Entity<Buffer>,
10641        cx: &mut Context<Self>,
10642    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10643        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10644            environment.update(cx, |env, cx| {
10645                env.buffer_environment(buffer, &self.worktree_store, cx)
10646            })
10647        } else {
10648            Task::ready(None).shared()
10649        }
10650    }
10651
10652    pub fn format(
10653        &mut self,
10654        buffers: HashSet<Entity<Buffer>>,
10655        target: LspFormatTarget,
10656        push_to_history: bool,
10657        trigger: FormatTrigger,
10658        cx: &mut Context<Self>,
10659    ) -> Task<anyhow::Result<ProjectTransaction>> {
10660        let logger = zlog::scoped!("format");
10661        if self.as_local().is_some() {
10662            zlog::trace!(logger => "Formatting locally");
10663            let logger = zlog::scoped!(logger => "local");
10664            let buffers = buffers
10665                .into_iter()
10666                .map(|buffer_handle| {
10667                    let buffer = buffer_handle.read(cx);
10668                    let buffer_abs_path = File::from_dyn(buffer.file())
10669                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10670
10671                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10672                })
10673                .collect::<Vec<_>>();
10674
10675            cx.spawn(async move |lsp_store, cx| {
10676                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10677
10678                for (handle, abs_path, id) in buffers {
10679                    let env = lsp_store
10680                        .update(cx, |lsp_store, cx| {
10681                            lsp_store.environment_for_buffer(&handle, cx)
10682                        })?
10683                        .await;
10684
10685                    let ranges = match &target {
10686                        LspFormatTarget::Buffers => None,
10687                        LspFormatTarget::Ranges(ranges) => {
10688                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10689                        }
10690                    };
10691
10692                    formattable_buffers.push(FormattableBuffer {
10693                        handle,
10694                        abs_path,
10695                        env,
10696                        ranges,
10697                    });
10698                }
10699                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10700
10701                let format_timer = zlog::time!(logger => "Formatting buffers");
10702                let result = LocalLspStore::format_locally(
10703                    lsp_store.clone(),
10704                    formattable_buffers,
10705                    push_to_history,
10706                    trigger,
10707                    logger,
10708                    cx,
10709                )
10710                .await;
10711                format_timer.end();
10712
10713                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10714
10715                lsp_store.update(cx, |lsp_store, _| {
10716                    lsp_store.update_last_formatting_failure(&result);
10717                })?;
10718
10719                result
10720            })
10721        } else if let Some((client, project_id)) = self.upstream_client() {
10722            zlog::trace!(logger => "Formatting remotely");
10723            let logger = zlog::scoped!(logger => "remote");
10724            // Don't support formatting ranges via remote
10725            match target {
10726                LspFormatTarget::Buffers => {}
10727                LspFormatTarget::Ranges(_) => {
10728                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10729                    return Task::ready(Ok(ProjectTransaction::default()));
10730                }
10731            }
10732
10733            let buffer_store = self.buffer_store();
10734            cx.spawn(async move |lsp_store, cx| {
10735                zlog::trace!(logger => "Sending remote format request");
10736                let request_timer = zlog::time!(logger => "remote format request");
10737                let result = client
10738                    .request(proto::FormatBuffers {
10739                        project_id,
10740                        trigger: trigger as i32,
10741                        buffer_ids: buffers
10742                            .iter()
10743                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10744                            .collect::<Result<_>>()?,
10745                    })
10746                    .await
10747                    .and_then(|result| result.transaction.context("missing transaction"));
10748                request_timer.end();
10749
10750                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10751
10752                lsp_store.update(cx, |lsp_store, _| {
10753                    lsp_store.update_last_formatting_failure(&result);
10754                })?;
10755
10756                let transaction_response = result?;
10757                let _timer = zlog::time!(logger => "deserializing project transaction");
10758                buffer_store
10759                    .update(cx, |buffer_store, cx| {
10760                        buffer_store.deserialize_project_transaction(
10761                            transaction_response,
10762                            push_to_history,
10763                            cx,
10764                        )
10765                    })?
10766                    .await
10767            })
10768        } else {
10769            zlog::trace!(logger => "Not formatting");
10770            Task::ready(Ok(ProjectTransaction::default()))
10771        }
10772    }
10773
10774    async fn handle_format_buffers(
10775        this: Entity<Self>,
10776        envelope: TypedEnvelope<proto::FormatBuffers>,
10777        mut cx: AsyncApp,
10778    ) -> Result<proto::FormatBuffersResponse> {
10779        let sender_id = envelope.original_sender_id().unwrap_or_default();
10780        let format = this.update(&mut cx, |this, cx| {
10781            let mut buffers = HashSet::default();
10782            for buffer_id in &envelope.payload.buffer_ids {
10783                let buffer_id = BufferId::new(*buffer_id)?;
10784                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10785            }
10786            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10787            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10788        })??;
10789
10790        let project_transaction = format.await?;
10791        let project_transaction = this.update(&mut cx, |this, cx| {
10792            this.buffer_store.update(cx, |buffer_store, cx| {
10793                buffer_store.serialize_project_transaction_for_peer(
10794                    project_transaction,
10795                    sender_id,
10796                    cx,
10797                )
10798            })
10799        })?;
10800        Ok(proto::FormatBuffersResponse {
10801            transaction: Some(project_transaction),
10802        })
10803    }
10804
10805    async fn handle_apply_code_action_kind(
10806        this: Entity<Self>,
10807        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10808        mut cx: AsyncApp,
10809    ) -> Result<proto::ApplyCodeActionKindResponse> {
10810        let sender_id = envelope.original_sender_id().unwrap_or_default();
10811        let format = this.update(&mut cx, |this, cx| {
10812            let mut buffers = HashSet::default();
10813            for buffer_id in &envelope.payload.buffer_ids {
10814                let buffer_id = BufferId::new(*buffer_id)?;
10815                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10816            }
10817            let kind = match envelope.payload.kind.as_str() {
10818                "" => CodeActionKind::EMPTY,
10819                "quickfix" => CodeActionKind::QUICKFIX,
10820                "refactor" => CodeActionKind::REFACTOR,
10821                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10822                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10823                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10824                "source" => CodeActionKind::SOURCE,
10825                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10826                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10827                _ => anyhow::bail!(
10828                    "Invalid code action kind {}",
10829                    envelope.payload.kind.as_str()
10830                ),
10831            };
10832            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10833        })??;
10834
10835        let project_transaction = format.await?;
10836        let project_transaction = this.update(&mut cx, |this, cx| {
10837            this.buffer_store.update(cx, |buffer_store, cx| {
10838                buffer_store.serialize_project_transaction_for_peer(
10839                    project_transaction,
10840                    sender_id,
10841                    cx,
10842                )
10843            })
10844        })?;
10845        Ok(proto::ApplyCodeActionKindResponse {
10846            transaction: Some(project_transaction),
10847        })
10848    }
10849
10850    async fn shutdown_language_server(
10851        server_state: Option<LanguageServerState>,
10852        name: LanguageServerName,
10853        cx: &mut AsyncApp,
10854    ) {
10855        let server = match server_state {
10856            Some(LanguageServerState::Starting { startup, .. }) => {
10857                let mut timer = cx
10858                    .background_executor()
10859                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10860                    .fuse();
10861
10862                select! {
10863                    server = startup.fuse() => server,
10864                    () = timer => {
10865                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10866                        None
10867                    },
10868                }
10869            }
10870
10871            Some(LanguageServerState::Running { server, .. }) => Some(server),
10872
10873            None => None,
10874        };
10875
10876        if let Some(server) = server
10877            && let Some(shutdown) = server.shutdown()
10878        {
10879            shutdown.await;
10880        }
10881    }
10882
10883    // Returns a list of all of the worktrees which no longer have a language server and the root path
10884    // for the stopped server
10885    fn stop_local_language_server(
10886        &mut self,
10887        server_id: LanguageServerId,
10888        cx: &mut Context<Self>,
10889    ) -> Task<()> {
10890        let local = match &mut self.mode {
10891            LspStoreMode::Local(local) => local,
10892            _ => {
10893                return Task::ready(());
10894            }
10895        };
10896
10897        // Remove this server ID from all entries in the given worktree.
10898        local
10899            .language_server_ids
10900            .retain(|_, state| state.id != server_id);
10901        self.buffer_store.update(cx, |buffer_store, cx| {
10902            for buffer in buffer_store.buffers() {
10903                buffer.update(cx, |buffer, cx| {
10904                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10905                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10906                });
10907            }
10908        });
10909
10910        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10911            summaries.retain(|path, summaries_by_server_id| {
10912                if summaries_by_server_id.remove(&server_id).is_some() {
10913                    if let Some((client, project_id)) = self.downstream_client.clone() {
10914                        client
10915                            .send(proto::UpdateDiagnosticSummary {
10916                                project_id,
10917                                worktree_id: worktree_id.to_proto(),
10918                                summary: Some(proto::DiagnosticSummary {
10919                                    path: path.as_ref().to_proto(),
10920                                    language_server_id: server_id.0 as u64,
10921                                    error_count: 0,
10922                                    warning_count: 0,
10923                                }),
10924                                more_summaries: Vec::new(),
10925                            })
10926                            .log_err();
10927                    }
10928                    !summaries_by_server_id.is_empty()
10929                } else {
10930                    true
10931                }
10932            });
10933        }
10934
10935        let local = self.as_local_mut().unwrap();
10936        for diagnostics in local.diagnostics.values_mut() {
10937            diagnostics.retain(|_, diagnostics_by_server_id| {
10938                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10939                    diagnostics_by_server_id.remove(ix);
10940                    !diagnostics_by_server_id.is_empty()
10941                } else {
10942                    true
10943                }
10944            });
10945        }
10946        local.language_server_watched_paths.remove(&server_id);
10947
10948        let server_state = local.language_servers.remove(&server_id);
10949        self.cleanup_lsp_data(server_id);
10950        let name = self
10951            .language_server_statuses
10952            .remove(&server_id)
10953            .map(|status| status.name)
10954            .or_else(|| {
10955                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10956                    Some(adapter.name())
10957                } else {
10958                    None
10959                }
10960            });
10961
10962        if let Some(name) = name {
10963            log::info!("stopping language server {name}");
10964            self.languages
10965                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10966            cx.notify();
10967
10968            return cx.spawn(async move |lsp_store, cx| {
10969                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10970                lsp_store
10971                    .update(cx, |lsp_store, cx| {
10972                        lsp_store
10973                            .languages
10974                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10975                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10976                        cx.notify();
10977                    })
10978                    .ok();
10979            });
10980        }
10981
10982        if server_state.is_some() {
10983            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10984        }
10985        Task::ready(())
10986    }
10987
10988    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10989        if let Some((client, project_id)) = self.upstream_client() {
10990            let request = client.request(proto::StopLanguageServers {
10991                project_id,
10992                buffer_ids: Vec::new(),
10993                also_servers: Vec::new(),
10994                all: true,
10995            });
10996            cx.background_spawn(request).detach_and_log_err(cx);
10997        } else {
10998            let Some(local) = self.as_local_mut() else {
10999                return;
11000            };
11001            let language_servers_to_stop = local
11002                .language_server_ids
11003                .values()
11004                .map(|state| state.id)
11005                .collect();
11006            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11007            let tasks = language_servers_to_stop
11008                .into_iter()
11009                .map(|server| self.stop_local_language_server(server, cx))
11010                .collect::<Vec<_>>();
11011            cx.background_spawn(async move {
11012                futures::future::join_all(tasks).await;
11013            })
11014            .detach();
11015        }
11016    }
11017
11018    pub fn restart_language_servers_for_buffers(
11019        &mut self,
11020        buffers: Vec<Entity<Buffer>>,
11021        only_restart_servers: HashSet<LanguageServerSelector>,
11022        cx: &mut Context<Self>,
11023    ) {
11024        if let Some((client, project_id)) = self.upstream_client() {
11025            let request = client.request(proto::RestartLanguageServers {
11026                project_id,
11027                buffer_ids: buffers
11028                    .into_iter()
11029                    .map(|b| b.read(cx).remote_id().to_proto())
11030                    .collect(),
11031                only_servers: only_restart_servers
11032                    .into_iter()
11033                    .map(|selector| {
11034                        let selector = match selector {
11035                            LanguageServerSelector::Id(language_server_id) => {
11036                                proto::language_server_selector::Selector::ServerId(
11037                                    language_server_id.to_proto(),
11038                                )
11039                            }
11040                            LanguageServerSelector::Name(language_server_name) => {
11041                                proto::language_server_selector::Selector::Name(
11042                                    language_server_name.to_string(),
11043                                )
11044                            }
11045                        };
11046                        proto::LanguageServerSelector {
11047                            selector: Some(selector),
11048                        }
11049                    })
11050                    .collect(),
11051                all: false,
11052            });
11053            cx.background_spawn(request).detach_and_log_err(cx);
11054        } else {
11055            let stop_task = if only_restart_servers.is_empty() {
11056                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11057            } else {
11058                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11059            };
11060            cx.spawn(async move |lsp_store, cx| {
11061                stop_task.await;
11062                lsp_store
11063                    .update(cx, |lsp_store, cx| {
11064                        for buffer in buffers {
11065                            lsp_store.register_buffer_with_language_servers(
11066                                &buffer,
11067                                only_restart_servers.clone(),
11068                                true,
11069                                cx,
11070                            );
11071                        }
11072                    })
11073                    .ok()
11074            })
11075            .detach();
11076        }
11077    }
11078
11079    pub fn stop_language_servers_for_buffers(
11080        &mut self,
11081        buffers: Vec<Entity<Buffer>>,
11082        also_stop_servers: HashSet<LanguageServerSelector>,
11083        cx: &mut Context<Self>,
11084    ) -> Task<Result<()>> {
11085        if let Some((client, project_id)) = self.upstream_client() {
11086            let request = client.request(proto::StopLanguageServers {
11087                project_id,
11088                buffer_ids: buffers
11089                    .into_iter()
11090                    .map(|b| b.read(cx).remote_id().to_proto())
11091                    .collect(),
11092                also_servers: also_stop_servers
11093                    .into_iter()
11094                    .map(|selector| {
11095                        let selector = match selector {
11096                            LanguageServerSelector::Id(language_server_id) => {
11097                                proto::language_server_selector::Selector::ServerId(
11098                                    language_server_id.to_proto(),
11099                                )
11100                            }
11101                            LanguageServerSelector::Name(language_server_name) => {
11102                                proto::language_server_selector::Selector::Name(
11103                                    language_server_name.to_string(),
11104                                )
11105                            }
11106                        };
11107                        proto::LanguageServerSelector {
11108                            selector: Some(selector),
11109                        }
11110                    })
11111                    .collect(),
11112                all: false,
11113            });
11114            cx.background_spawn(async move {
11115                let _ = request.await?;
11116                Ok(())
11117            })
11118        } else {
11119            let task =
11120                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11121            cx.background_spawn(async move {
11122                task.await;
11123                Ok(())
11124            })
11125        }
11126    }
11127
11128    fn stop_local_language_servers_for_buffers(
11129        &mut self,
11130        buffers: &[Entity<Buffer>],
11131        also_stop_servers: HashSet<LanguageServerSelector>,
11132        cx: &mut Context<Self>,
11133    ) -> Task<()> {
11134        let Some(local) = self.as_local_mut() else {
11135            return Task::ready(());
11136        };
11137        let mut language_server_names_to_stop = BTreeSet::default();
11138        let mut language_servers_to_stop = also_stop_servers
11139            .into_iter()
11140            .flat_map(|selector| match selector {
11141                LanguageServerSelector::Id(id) => Some(id),
11142                LanguageServerSelector::Name(name) => {
11143                    language_server_names_to_stop.insert(name);
11144                    None
11145                }
11146            })
11147            .collect::<BTreeSet<_>>();
11148
11149        let mut covered_worktrees = HashSet::default();
11150        for buffer in buffers {
11151            buffer.update(cx, |buffer, cx| {
11152                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11153                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11154                    && covered_worktrees.insert(worktree_id)
11155                {
11156                    language_server_names_to_stop.retain(|name| {
11157                        let old_ids_count = language_servers_to_stop.len();
11158                        let all_language_servers_with_this_name = local
11159                            .language_server_ids
11160                            .iter()
11161                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11162                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11163                        old_ids_count == language_servers_to_stop.len()
11164                    });
11165                }
11166            });
11167        }
11168        for name in language_server_names_to_stop {
11169            language_servers_to_stop.extend(
11170                local
11171                    .language_server_ids
11172                    .iter()
11173                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11174            );
11175        }
11176
11177        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11178        let tasks = language_servers_to_stop
11179            .into_iter()
11180            .map(|server| self.stop_local_language_server(server, cx))
11181            .collect::<Vec<_>>();
11182
11183        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11184    }
11185
11186    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11187        let (worktree, relative_path) =
11188            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11189
11190        let project_path = ProjectPath {
11191            worktree_id: worktree.read(cx).id(),
11192            path: relative_path,
11193        };
11194
11195        Some(
11196            self.buffer_store()
11197                .read(cx)
11198                .get_by_path(&project_path)?
11199                .read(cx),
11200        )
11201    }
11202
11203    #[cfg(any(test, feature = "test-support"))]
11204    pub fn update_diagnostics(
11205        &mut self,
11206        server_id: LanguageServerId,
11207        diagnostics: lsp::PublishDiagnosticsParams,
11208        result_id: Option<SharedString>,
11209        source_kind: DiagnosticSourceKind,
11210        disk_based_sources: &[String],
11211        cx: &mut Context<Self>,
11212    ) -> Result<()> {
11213        self.merge_lsp_diagnostics(
11214            source_kind,
11215            vec![DocumentDiagnosticsUpdate {
11216                diagnostics,
11217                result_id,
11218                server_id,
11219                disk_based_sources: Cow::Borrowed(disk_based_sources),
11220                registration_id: None,
11221            }],
11222            |_, _, _| false,
11223            cx,
11224        )
11225    }
11226
11227    pub fn merge_lsp_diagnostics(
11228        &mut self,
11229        source_kind: DiagnosticSourceKind,
11230        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11231        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11232        cx: &mut Context<Self>,
11233    ) -> Result<()> {
11234        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11235        let updates = lsp_diagnostics
11236            .into_iter()
11237            .filter_map(|update| {
11238                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11239                Some(DocumentDiagnosticsUpdate {
11240                    diagnostics: self.lsp_to_document_diagnostics(
11241                        abs_path,
11242                        source_kind,
11243                        update.server_id,
11244                        update.diagnostics,
11245                        &update.disk_based_sources,
11246                        update.registration_id.clone(),
11247                    ),
11248                    result_id: update.result_id,
11249                    server_id: update.server_id,
11250                    disk_based_sources: update.disk_based_sources,
11251                    registration_id: update.registration_id,
11252                })
11253            })
11254            .collect();
11255        self.merge_diagnostic_entries(updates, merge, cx)?;
11256        Ok(())
11257    }
11258
11259    fn lsp_to_document_diagnostics(
11260        &mut self,
11261        document_abs_path: PathBuf,
11262        source_kind: DiagnosticSourceKind,
11263        server_id: LanguageServerId,
11264        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11265        disk_based_sources: &[String],
11266        registration_id: Option<SharedString>,
11267    ) -> DocumentDiagnostics {
11268        let mut diagnostics = Vec::default();
11269        let mut primary_diagnostic_group_ids = HashMap::default();
11270        let mut sources_by_group_id = HashMap::default();
11271        let mut supporting_diagnostics = HashMap::default();
11272
11273        let adapter = self.language_server_adapter_for_id(server_id);
11274
11275        // Ensure that primary diagnostics are always the most severe
11276        lsp_diagnostics
11277            .diagnostics
11278            .sort_by_key(|item| item.severity);
11279
11280        for diagnostic in &lsp_diagnostics.diagnostics {
11281            let source = diagnostic.source.as_ref();
11282            let range = range_from_lsp(diagnostic.range);
11283            let is_supporting = diagnostic
11284                .related_information
11285                .as_ref()
11286                .is_some_and(|infos| {
11287                    infos.iter().any(|info| {
11288                        primary_diagnostic_group_ids.contains_key(&(
11289                            source,
11290                            diagnostic.code.clone(),
11291                            range_from_lsp(info.location.range),
11292                        ))
11293                    })
11294                });
11295
11296            let is_unnecessary = diagnostic
11297                .tags
11298                .as_ref()
11299                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11300
11301            let underline = self
11302                .language_server_adapter_for_id(server_id)
11303                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11304
11305            if is_supporting {
11306                supporting_diagnostics.insert(
11307                    (source, diagnostic.code.clone(), range),
11308                    (diagnostic.severity, is_unnecessary),
11309                );
11310            } else {
11311                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11312                let is_disk_based =
11313                    source.is_some_and(|source| disk_based_sources.contains(source));
11314
11315                sources_by_group_id.insert(group_id, source);
11316                primary_diagnostic_group_ids
11317                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11318
11319                diagnostics.push(DiagnosticEntry {
11320                    range,
11321                    diagnostic: Diagnostic {
11322                        source: diagnostic.source.clone(),
11323                        source_kind,
11324                        code: diagnostic.code.clone(),
11325                        code_description: diagnostic
11326                            .code_description
11327                            .as_ref()
11328                            .and_then(|d| d.href.clone()),
11329                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11330                        markdown: adapter.as_ref().and_then(|adapter| {
11331                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11332                        }),
11333                        message: diagnostic.message.trim().to_string(),
11334                        group_id,
11335                        is_primary: true,
11336                        is_disk_based,
11337                        is_unnecessary,
11338                        underline,
11339                        data: diagnostic.data.clone(),
11340                        registration_id: registration_id.clone(),
11341                    },
11342                });
11343                if let Some(infos) = &diagnostic.related_information {
11344                    for info in infos {
11345                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11346                            let range = range_from_lsp(info.location.range);
11347                            diagnostics.push(DiagnosticEntry {
11348                                range,
11349                                diagnostic: Diagnostic {
11350                                    source: diagnostic.source.clone(),
11351                                    source_kind,
11352                                    code: diagnostic.code.clone(),
11353                                    code_description: diagnostic
11354                                        .code_description
11355                                        .as_ref()
11356                                        .and_then(|d| d.href.clone()),
11357                                    severity: DiagnosticSeverity::INFORMATION,
11358                                    markdown: adapter.as_ref().and_then(|adapter| {
11359                                        adapter.diagnostic_message_to_markdown(&info.message)
11360                                    }),
11361                                    message: info.message.trim().to_string(),
11362                                    group_id,
11363                                    is_primary: false,
11364                                    is_disk_based,
11365                                    is_unnecessary: false,
11366                                    underline,
11367                                    data: diagnostic.data.clone(),
11368                                    registration_id: registration_id.clone(),
11369                                },
11370                            });
11371                        }
11372                    }
11373                }
11374            }
11375        }
11376
11377        for entry in &mut diagnostics {
11378            let diagnostic = &mut entry.diagnostic;
11379            if !diagnostic.is_primary {
11380                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11381                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11382                    source,
11383                    diagnostic.code.clone(),
11384                    entry.range.clone(),
11385                )) {
11386                    if let Some(severity) = severity {
11387                        diagnostic.severity = severity;
11388                    }
11389                    diagnostic.is_unnecessary = is_unnecessary;
11390                }
11391            }
11392        }
11393
11394        DocumentDiagnostics {
11395            diagnostics,
11396            document_abs_path,
11397            version: lsp_diagnostics.version,
11398        }
11399    }
11400
11401    fn insert_newly_running_language_server(
11402        &mut self,
11403        adapter: Arc<CachedLspAdapter>,
11404        language_server: Arc<LanguageServer>,
11405        server_id: LanguageServerId,
11406        key: LanguageServerSeed,
11407        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11408        cx: &mut Context<Self>,
11409    ) {
11410        let Some(local) = self.as_local_mut() else {
11411            return;
11412        };
11413        // If the language server for this key doesn't match the server id, don't store the
11414        // server. Which will cause it to be dropped, killing the process
11415        if local
11416            .language_server_ids
11417            .get(&key)
11418            .map(|state| state.id != server_id)
11419            .unwrap_or(false)
11420        {
11421            return;
11422        }
11423
11424        // Update language_servers collection with Running variant of LanguageServerState
11425        // indicating that the server is up and running and ready
11426        let workspace_folders = workspace_folders.lock().clone();
11427        language_server.set_workspace_folders(workspace_folders);
11428
11429        let workspace_diagnostics_refresh_tasks = language_server
11430            .capabilities()
11431            .diagnostic_provider
11432            .and_then(|provider| {
11433                local
11434                    .language_server_dynamic_registrations
11435                    .entry(server_id)
11436                    .or_default()
11437                    .diagnostics
11438                    .entry(None)
11439                    .or_insert(provider.clone());
11440                let workspace_refresher =
11441                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11442
11443                Some((None, workspace_refresher))
11444            })
11445            .into_iter()
11446            .collect();
11447        local.language_servers.insert(
11448            server_id,
11449            LanguageServerState::Running {
11450                workspace_diagnostics_refresh_tasks,
11451                adapter: adapter.clone(),
11452                server: language_server.clone(),
11453                simulate_disk_based_diagnostics_completion: None,
11454            },
11455        );
11456        local
11457            .languages
11458            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11459        if let Some(file_ops_caps) = language_server
11460            .capabilities()
11461            .workspace
11462            .as_ref()
11463            .and_then(|ws| ws.file_operations.as_ref())
11464        {
11465            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11466            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11467            if did_rename_caps.or(will_rename_caps).is_some() {
11468                let watcher = RenamePathsWatchedForServer::default()
11469                    .with_did_rename_patterns(did_rename_caps)
11470                    .with_will_rename_patterns(will_rename_caps);
11471                local
11472                    .language_server_paths_watched_for_rename
11473                    .insert(server_id, watcher);
11474            }
11475        }
11476
11477        self.language_server_statuses.insert(
11478            server_id,
11479            LanguageServerStatus {
11480                name: language_server.name(),
11481                server_version: language_server.version(),
11482                pending_work: Default::default(),
11483                has_pending_diagnostic_updates: false,
11484                progress_tokens: Default::default(),
11485                worktree: Some(key.worktree_id),
11486                binary: Some(language_server.binary().clone()),
11487                configuration: Some(language_server.configuration().clone()),
11488                workspace_folders: language_server.workspace_folders(),
11489            },
11490        );
11491
11492        cx.emit(LspStoreEvent::LanguageServerAdded(
11493            server_id,
11494            language_server.name(),
11495            Some(key.worktree_id),
11496        ));
11497
11498        let server_capabilities = language_server.capabilities();
11499        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11500            downstream_client
11501                .send(proto::StartLanguageServer {
11502                    project_id: *project_id,
11503                    server: Some(proto::LanguageServer {
11504                        id: server_id.to_proto(),
11505                        name: language_server.name().to_string(),
11506                        worktree_id: Some(key.worktree_id.to_proto()),
11507                    }),
11508                    capabilities: serde_json::to_string(&server_capabilities)
11509                        .expect("serializing server LSP capabilities"),
11510                })
11511                .log_err();
11512        }
11513        self.lsp_server_capabilities
11514            .insert(server_id, server_capabilities);
11515
11516        // Tell the language server about every open buffer in the worktree that matches the language.
11517        // Also check for buffers in worktrees that reused this server
11518        let mut worktrees_using_server = vec![key.worktree_id];
11519        if let Some(local) = self.as_local() {
11520            // Find all worktrees that have this server in their language server tree
11521            for (worktree_id, servers) in &local.lsp_tree.instances {
11522                if *worktree_id != key.worktree_id {
11523                    for server_map in servers.roots.values() {
11524                        if server_map
11525                            .values()
11526                            .any(|(node, _)| node.id() == Some(server_id))
11527                        {
11528                            worktrees_using_server.push(*worktree_id);
11529                        }
11530                    }
11531                }
11532            }
11533        }
11534
11535        let mut buffer_paths_registered = Vec::new();
11536        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11537            let mut lsp_adapters = HashMap::default();
11538            for buffer_handle in buffer_store.buffers() {
11539                let buffer = buffer_handle.read(cx);
11540                let file = match File::from_dyn(buffer.file()) {
11541                    Some(file) => file,
11542                    None => continue,
11543                };
11544                let language = match buffer.language() {
11545                    Some(language) => language,
11546                    None => continue,
11547                };
11548
11549                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11550                    || !lsp_adapters
11551                        .entry(language.name())
11552                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11553                        .iter()
11554                        .any(|a| a.name == key.name)
11555                {
11556                    continue;
11557                }
11558                // didOpen
11559                let file = match file.as_local() {
11560                    Some(file) => file,
11561                    None => continue,
11562                };
11563
11564                let local = self.as_local_mut().unwrap();
11565
11566                let buffer_id = buffer.remote_id();
11567                if local.registered_buffers.contains_key(&buffer_id) {
11568                    let versions = local
11569                        .buffer_snapshots
11570                        .entry(buffer_id)
11571                        .or_default()
11572                        .entry(server_id)
11573                        .and_modify(|_| {
11574                            assert!(
11575                            false,
11576                            "There should not be an existing snapshot for a newly inserted buffer"
11577                        )
11578                        })
11579                        .or_insert_with(|| {
11580                            vec![LspBufferSnapshot {
11581                                version: 0,
11582                                snapshot: buffer.text_snapshot(),
11583                            }]
11584                        });
11585
11586                    let snapshot = versions.last().unwrap();
11587                    let version = snapshot.version;
11588                    let initial_snapshot = &snapshot.snapshot;
11589                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11590                    language_server.register_buffer(
11591                        uri,
11592                        adapter.language_id(&language.name()),
11593                        version,
11594                        initial_snapshot.text(),
11595                    );
11596                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11597                    local
11598                        .buffers_opened_in_servers
11599                        .entry(buffer_id)
11600                        .or_default()
11601                        .insert(server_id);
11602                }
11603                buffer_handle.update(cx, |buffer, cx| {
11604                    buffer.set_completion_triggers(
11605                        server_id,
11606                        language_server
11607                            .capabilities()
11608                            .completion_provider
11609                            .as_ref()
11610                            .and_then(|provider| {
11611                                provider
11612                                    .trigger_characters
11613                                    .as_ref()
11614                                    .map(|characters| characters.iter().cloned().collect())
11615                            })
11616                            .unwrap_or_default(),
11617                        cx,
11618                    )
11619                });
11620            }
11621        });
11622
11623        for (buffer_id, abs_path) in buffer_paths_registered {
11624            cx.emit(LspStoreEvent::LanguageServerUpdate {
11625                language_server_id: server_id,
11626                name: Some(adapter.name()),
11627                message: proto::update_language_server::Variant::RegisteredForBuffer(
11628                    proto::RegisteredForBuffer {
11629                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11630                        buffer_id: buffer_id.to_proto(),
11631                    },
11632                ),
11633            });
11634        }
11635
11636        cx.notify();
11637    }
11638
11639    pub fn language_servers_running_disk_based_diagnostics(
11640        &self,
11641    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11642        self.language_server_statuses
11643            .iter()
11644            .filter_map(|(id, status)| {
11645                if status.has_pending_diagnostic_updates {
11646                    Some(*id)
11647                } else {
11648                    None
11649                }
11650            })
11651    }
11652
11653    pub(crate) fn cancel_language_server_work_for_buffers(
11654        &mut self,
11655        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11656        cx: &mut Context<Self>,
11657    ) {
11658        if let Some((client, project_id)) = self.upstream_client() {
11659            let request = client.request(proto::CancelLanguageServerWork {
11660                project_id,
11661                work: Some(proto::cancel_language_server_work::Work::Buffers(
11662                    proto::cancel_language_server_work::Buffers {
11663                        buffer_ids: buffers
11664                            .into_iter()
11665                            .map(|b| b.read(cx).remote_id().to_proto())
11666                            .collect(),
11667                    },
11668                )),
11669            });
11670            cx.background_spawn(request).detach_and_log_err(cx);
11671        } else if let Some(local) = self.as_local() {
11672            let servers = buffers
11673                .into_iter()
11674                .flat_map(|buffer| {
11675                    buffer.update(cx, |buffer, cx| {
11676                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11677                    })
11678                })
11679                .collect::<HashSet<_>>();
11680            for server_id in servers {
11681                self.cancel_language_server_work(server_id, None, cx);
11682            }
11683        }
11684    }
11685
11686    pub(crate) fn cancel_language_server_work(
11687        &mut self,
11688        server_id: LanguageServerId,
11689        token_to_cancel: Option<ProgressToken>,
11690        cx: &mut Context<Self>,
11691    ) {
11692        if let Some(local) = self.as_local() {
11693            let status = self.language_server_statuses.get(&server_id);
11694            let server = local.language_servers.get(&server_id);
11695            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11696            {
11697                for (token, progress) in &status.pending_work {
11698                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11699                        && token != token_to_cancel
11700                    {
11701                        continue;
11702                    }
11703                    if progress.is_cancellable {
11704                        server
11705                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11706                                WorkDoneProgressCancelParams {
11707                                    token: token.to_lsp(),
11708                                },
11709                            )
11710                            .ok();
11711                    }
11712                }
11713            }
11714        } else if let Some((client, project_id)) = self.upstream_client() {
11715            let request = client.request(proto::CancelLanguageServerWork {
11716                project_id,
11717                work: Some(
11718                    proto::cancel_language_server_work::Work::LanguageServerWork(
11719                        proto::cancel_language_server_work::LanguageServerWork {
11720                            language_server_id: server_id.to_proto(),
11721                            token: token_to_cancel.map(|token| token.to_proto()),
11722                        },
11723                    ),
11724                ),
11725            });
11726            cx.background_spawn(request).detach_and_log_err(cx);
11727        }
11728    }
11729
11730    fn register_supplementary_language_server(
11731        &mut self,
11732        id: LanguageServerId,
11733        name: LanguageServerName,
11734        server: Arc<LanguageServer>,
11735        cx: &mut Context<Self>,
11736    ) {
11737        if let Some(local) = self.as_local_mut() {
11738            local
11739                .supplementary_language_servers
11740                .insert(id, (name.clone(), server));
11741            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11742        }
11743    }
11744
11745    fn unregister_supplementary_language_server(
11746        &mut self,
11747        id: LanguageServerId,
11748        cx: &mut Context<Self>,
11749    ) {
11750        if let Some(local) = self.as_local_mut() {
11751            local.supplementary_language_servers.remove(&id);
11752            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11753        }
11754    }
11755
11756    pub(crate) fn supplementary_language_servers(
11757        &self,
11758    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11759        self.as_local().into_iter().flat_map(|local| {
11760            local
11761                .supplementary_language_servers
11762                .iter()
11763                .map(|(id, (name, _))| (*id, name.clone()))
11764        })
11765    }
11766
11767    pub fn language_server_adapter_for_id(
11768        &self,
11769        id: LanguageServerId,
11770    ) -> Option<Arc<CachedLspAdapter>> {
11771        self.as_local()
11772            .and_then(|local| local.language_servers.get(&id))
11773            .and_then(|language_server_state| match language_server_state {
11774                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11775                _ => None,
11776            })
11777    }
11778
11779    pub(super) fn update_local_worktree_language_servers(
11780        &mut self,
11781        worktree_handle: &Entity<Worktree>,
11782        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11783        cx: &mut Context<Self>,
11784    ) {
11785        if changes.is_empty() {
11786            return;
11787        }
11788
11789        let Some(local) = self.as_local() else { return };
11790
11791        local.prettier_store.update(cx, |prettier_store, cx| {
11792            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11793        });
11794
11795        let worktree_id = worktree_handle.read(cx).id();
11796        let mut language_server_ids = local
11797            .language_server_ids
11798            .iter()
11799            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11800            .collect::<Vec<_>>();
11801        language_server_ids.sort();
11802        language_server_ids.dedup();
11803
11804        // let abs_path = worktree_handle.read(cx).abs_path();
11805        for server_id in &language_server_ids {
11806            if let Some(LanguageServerState::Running { server, .. }) =
11807                local.language_servers.get(server_id)
11808                && let Some(watched_paths) = local
11809                    .language_server_watched_paths
11810                    .get(server_id)
11811                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11812            {
11813                let params = lsp::DidChangeWatchedFilesParams {
11814                    changes: changes
11815                        .iter()
11816                        .filter_map(|(path, _, change)| {
11817                            if !watched_paths.is_match(path.as_std_path()) {
11818                                return None;
11819                            }
11820                            let typ = match change {
11821                                PathChange::Loaded => return None,
11822                                PathChange::Added => lsp::FileChangeType::CREATED,
11823                                PathChange::Removed => lsp::FileChangeType::DELETED,
11824                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11825                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11826                            };
11827                            let uri = lsp::Uri::from_file_path(
11828                                worktree_handle.read(cx).absolutize(&path),
11829                            )
11830                            .ok()?;
11831                            Some(lsp::FileEvent { uri, typ })
11832                        })
11833                        .collect(),
11834                };
11835                if !params.changes.is_empty() {
11836                    server
11837                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11838                        .ok();
11839                }
11840            }
11841        }
11842        for (path, _, _) in changes {
11843            if let Some(file_name) = path.file_name()
11844                && local.watched_manifest_filenames.contains(file_name)
11845            {
11846                self.request_workspace_config_refresh();
11847                break;
11848            }
11849        }
11850    }
11851
11852    pub fn wait_for_remote_buffer(
11853        &mut self,
11854        id: BufferId,
11855        cx: &mut Context<Self>,
11856    ) -> Task<Result<Entity<Buffer>>> {
11857        self.buffer_store.update(cx, |buffer_store, cx| {
11858            buffer_store.wait_for_remote_buffer(id, cx)
11859        })
11860    }
11861
11862    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11863        let mut result = proto::Symbol {
11864            language_server_name: symbol.language_server_name.0.to_string(),
11865            source_worktree_id: symbol.source_worktree_id.to_proto(),
11866            language_server_id: symbol.source_language_server_id.to_proto(),
11867            name: symbol.name.clone(),
11868            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11869            start: Some(proto::PointUtf16 {
11870                row: symbol.range.start.0.row,
11871                column: symbol.range.start.0.column,
11872            }),
11873            end: Some(proto::PointUtf16 {
11874                row: symbol.range.end.0.row,
11875                column: symbol.range.end.0.column,
11876            }),
11877            worktree_id: Default::default(),
11878            path: Default::default(),
11879            signature: Default::default(),
11880        };
11881        match &symbol.path {
11882            SymbolLocation::InProject(path) => {
11883                result.worktree_id = path.worktree_id.to_proto();
11884                result.path = path.path.to_proto();
11885            }
11886            SymbolLocation::OutsideProject {
11887                abs_path,
11888                signature,
11889            } => {
11890                result.path = abs_path.to_string_lossy().into_owned();
11891                result.signature = signature.to_vec();
11892            }
11893        }
11894        result
11895    }
11896
11897    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11898        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11899        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11900        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11901
11902        let path = if serialized_symbol.signature.is_empty() {
11903            SymbolLocation::InProject(ProjectPath {
11904                worktree_id,
11905                path: RelPath::from_proto(&serialized_symbol.path)
11906                    .context("invalid symbol path")?,
11907            })
11908        } else {
11909            SymbolLocation::OutsideProject {
11910                abs_path: Path::new(&serialized_symbol.path).into(),
11911                signature: serialized_symbol
11912                    .signature
11913                    .try_into()
11914                    .map_err(|_| anyhow!("invalid signature"))?,
11915            }
11916        };
11917
11918        let start = serialized_symbol.start.context("invalid start")?;
11919        let end = serialized_symbol.end.context("invalid end")?;
11920        Ok(CoreSymbol {
11921            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11922            source_worktree_id,
11923            source_language_server_id: LanguageServerId::from_proto(
11924                serialized_symbol.language_server_id,
11925            ),
11926            path,
11927            name: serialized_symbol.name,
11928            range: Unclipped(PointUtf16::new(start.row, start.column))
11929                ..Unclipped(PointUtf16::new(end.row, end.column)),
11930            kind,
11931        })
11932    }
11933
11934    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11935        let mut serialized_completion = proto::Completion {
11936            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11937            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11938            new_text: completion.new_text.clone(),
11939            ..proto::Completion::default()
11940        };
11941        match &completion.source {
11942            CompletionSource::Lsp {
11943                insert_range,
11944                server_id,
11945                lsp_completion,
11946                lsp_defaults,
11947                resolved,
11948            } => {
11949                let (old_insert_start, old_insert_end) = insert_range
11950                    .as_ref()
11951                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11952                    .unzip();
11953
11954                serialized_completion.old_insert_start = old_insert_start;
11955                serialized_completion.old_insert_end = old_insert_end;
11956                serialized_completion.source = proto::completion::Source::Lsp as i32;
11957                serialized_completion.server_id = server_id.0 as u64;
11958                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11959                serialized_completion.lsp_defaults = lsp_defaults
11960                    .as_deref()
11961                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11962                serialized_completion.resolved = *resolved;
11963            }
11964            CompletionSource::BufferWord {
11965                word_range,
11966                resolved,
11967            } => {
11968                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11969                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11970                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11971                serialized_completion.resolved = *resolved;
11972            }
11973            CompletionSource::Custom => {
11974                serialized_completion.source = proto::completion::Source::Custom as i32;
11975                serialized_completion.resolved = true;
11976            }
11977            CompletionSource::Dap { sort_text } => {
11978                serialized_completion.source = proto::completion::Source::Dap as i32;
11979                serialized_completion.sort_text = Some(sort_text.clone());
11980            }
11981        }
11982
11983        serialized_completion
11984    }
11985
11986    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11987        let old_replace_start = completion
11988            .old_replace_start
11989            .and_then(deserialize_anchor)
11990            .context("invalid old start")?;
11991        let old_replace_end = completion
11992            .old_replace_end
11993            .and_then(deserialize_anchor)
11994            .context("invalid old end")?;
11995        let insert_range = {
11996            match completion.old_insert_start.zip(completion.old_insert_end) {
11997                Some((start, end)) => {
11998                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11999                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12000                    Some(start..end)
12001                }
12002                None => None,
12003            }
12004        };
12005        Ok(CoreCompletion {
12006            replace_range: old_replace_start..old_replace_end,
12007            new_text: completion.new_text,
12008            source: match proto::completion::Source::from_i32(completion.source) {
12009                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12010                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12011                    insert_range,
12012                    server_id: LanguageServerId::from_proto(completion.server_id),
12013                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12014                    lsp_defaults: completion
12015                        .lsp_defaults
12016                        .as_deref()
12017                        .map(serde_json::from_slice)
12018                        .transpose()?,
12019                    resolved: completion.resolved,
12020                },
12021                Some(proto::completion::Source::BufferWord) => {
12022                    let word_range = completion
12023                        .buffer_word_start
12024                        .and_then(deserialize_anchor)
12025                        .context("invalid buffer word start")?
12026                        ..completion
12027                            .buffer_word_end
12028                            .and_then(deserialize_anchor)
12029                            .context("invalid buffer word end")?;
12030                    CompletionSource::BufferWord {
12031                        word_range,
12032                        resolved: completion.resolved,
12033                    }
12034                }
12035                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12036                    sort_text: completion
12037                        .sort_text
12038                        .context("expected sort text to exist")?,
12039                },
12040                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12041            },
12042        })
12043    }
12044
12045    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12046        let (kind, lsp_action) = match &action.lsp_action {
12047            LspAction::Action(code_action) => (
12048                proto::code_action::Kind::Action as i32,
12049                serde_json::to_vec(code_action).unwrap(),
12050            ),
12051            LspAction::Command(command) => (
12052                proto::code_action::Kind::Command as i32,
12053                serde_json::to_vec(command).unwrap(),
12054            ),
12055            LspAction::CodeLens(code_lens) => (
12056                proto::code_action::Kind::CodeLens as i32,
12057                serde_json::to_vec(code_lens).unwrap(),
12058            ),
12059        };
12060
12061        proto::CodeAction {
12062            server_id: action.server_id.0 as u64,
12063            start: Some(serialize_anchor(&action.range.start)),
12064            end: Some(serialize_anchor(&action.range.end)),
12065            lsp_action,
12066            kind,
12067            resolved: action.resolved,
12068        }
12069    }
12070
12071    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12072        let start = action
12073            .start
12074            .and_then(deserialize_anchor)
12075            .context("invalid start")?;
12076        let end = action
12077            .end
12078            .and_then(deserialize_anchor)
12079            .context("invalid end")?;
12080        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12081            Some(proto::code_action::Kind::Action) => {
12082                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12083            }
12084            Some(proto::code_action::Kind::Command) => {
12085                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12086            }
12087            Some(proto::code_action::Kind::CodeLens) => {
12088                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12089            }
12090            None => anyhow::bail!("Unknown action kind {}", action.kind),
12091        };
12092        Ok(CodeAction {
12093            server_id: LanguageServerId(action.server_id as usize),
12094            range: start..end,
12095            resolved: action.resolved,
12096            lsp_action,
12097        })
12098    }
12099
12100    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12101        match &formatting_result {
12102            Ok(_) => self.last_formatting_failure = None,
12103            Err(error) => {
12104                let error_string = format!("{error:#}");
12105                log::error!("Formatting failed: {error_string}");
12106                self.last_formatting_failure
12107                    .replace(error_string.lines().join(" "));
12108            }
12109        }
12110    }
12111
12112    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12113        self.lsp_server_capabilities.remove(&for_server);
12114        for lsp_data in self.lsp_data.values_mut() {
12115            lsp_data.remove_server_data(for_server);
12116        }
12117        if let Some(local) = self.as_local_mut() {
12118            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12119            local
12120                .workspace_pull_diagnostics_result_ids
12121                .remove(&for_server);
12122            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12123                buffer_servers.remove(&for_server);
12124            }
12125        }
12126    }
12127
12128    pub fn result_id_for_buffer_pull(
12129        &self,
12130        server_id: LanguageServerId,
12131        buffer_id: BufferId,
12132        registration_id: &Option<SharedString>,
12133        cx: &App,
12134    ) -> Option<SharedString> {
12135        let abs_path = self
12136            .buffer_store
12137            .read(cx)
12138            .get(buffer_id)
12139            .and_then(|b| File::from_dyn(b.read(cx).file()))
12140            .map(|f| f.abs_path(cx))?;
12141        self.as_local()?
12142            .buffer_pull_diagnostics_result_ids
12143            .get(&server_id)?
12144            .get(registration_id)?
12145            .get(&abs_path)?
12146            .clone()
12147    }
12148
12149    /// Gets all result_ids for a workspace diagnostics pull request.
12150    /// 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.
12151    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12152    pub fn result_ids_for_workspace_refresh(
12153        &self,
12154        server_id: LanguageServerId,
12155        registration_id: &Option<SharedString>,
12156    ) -> HashMap<PathBuf, SharedString> {
12157        let Some(local) = self.as_local() else {
12158            return HashMap::default();
12159        };
12160        local
12161            .workspace_pull_diagnostics_result_ids
12162            .get(&server_id)
12163            .into_iter()
12164            .filter_map(|diagnostics| diagnostics.get(registration_id))
12165            .flatten()
12166            .filter_map(|(abs_path, result_id)| {
12167                let result_id = local
12168                    .buffer_pull_diagnostics_result_ids
12169                    .get(&server_id)
12170                    .and_then(|buffer_ids_result_ids| {
12171                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12172                    })
12173                    .cloned()
12174                    .flatten()
12175                    .or_else(|| result_id.clone())?;
12176                Some((abs_path.clone(), result_id))
12177            })
12178            .collect()
12179    }
12180
12181    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12182        if let Some(LanguageServerState::Running {
12183            workspace_diagnostics_refresh_tasks,
12184            ..
12185        }) = self
12186            .as_local_mut()
12187            .and_then(|local| local.language_servers.get_mut(&server_id))
12188        {
12189            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12190                diagnostics.refresh_tx.try_send(()).ok();
12191            }
12192        }
12193    }
12194
12195    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
12196        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
12197            return;
12198        };
12199        let Some(local) = self.as_local_mut() else {
12200            return;
12201        };
12202
12203        for server_id in buffer.update(cx, |buffer, cx| {
12204            local.language_server_ids_for_buffer(buffer, cx)
12205        }) {
12206            if let Some(LanguageServerState::Running {
12207                workspace_diagnostics_refresh_tasks,
12208                ..
12209            }) = local.language_servers.get_mut(&server_id)
12210            {
12211                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12212                    diagnostics.refresh_tx.try_send(()).ok();
12213                }
12214            }
12215        }
12216    }
12217
12218    fn apply_workspace_diagnostic_report(
12219        &mut self,
12220        server_id: LanguageServerId,
12221        report: lsp::WorkspaceDiagnosticReportResult,
12222        registration_id: Option<SharedString>,
12223        cx: &mut Context<Self>,
12224    ) {
12225        let mut workspace_diagnostics =
12226            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12227                report,
12228                server_id,
12229                registration_id,
12230            );
12231        workspace_diagnostics.retain(|d| match &d.diagnostics {
12232            LspPullDiagnostics::Response {
12233                server_id,
12234                registration_id,
12235                ..
12236            } => self.diagnostic_registration_exists(*server_id, registration_id),
12237            LspPullDiagnostics::Default => false,
12238        });
12239        let mut unchanged_buffers = HashMap::default();
12240        let workspace_diagnostics_updates = workspace_diagnostics
12241            .into_iter()
12242            .filter_map(
12243                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12244                    LspPullDiagnostics::Response {
12245                        server_id,
12246                        uri,
12247                        diagnostics,
12248                        registration_id,
12249                    } => Some((
12250                        server_id,
12251                        uri,
12252                        diagnostics,
12253                        workspace_diagnostics.version,
12254                        registration_id,
12255                    )),
12256                    LspPullDiagnostics::Default => None,
12257                },
12258            )
12259            .fold(
12260                HashMap::default(),
12261                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12262                    let (result_id, diagnostics) = match diagnostics {
12263                        PulledDiagnostics::Unchanged { result_id } => {
12264                            unchanged_buffers
12265                                .entry(new_registration_id.clone())
12266                                .or_insert_with(HashSet::default)
12267                                .insert(uri.clone());
12268                            (Some(result_id), Vec::new())
12269                        }
12270                        PulledDiagnostics::Changed {
12271                            result_id,
12272                            diagnostics,
12273                        } => (result_id, diagnostics),
12274                    };
12275                    let disk_based_sources = Cow::Owned(
12276                        self.language_server_adapter_for_id(server_id)
12277                            .as_ref()
12278                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12279                            .unwrap_or(&[])
12280                            .to_vec(),
12281                    );
12282
12283                    let Some(abs_path) = uri.to_file_path().ok() else {
12284                        return acc;
12285                    };
12286                    let Some((worktree, relative_path)) =
12287                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12288                    else {
12289                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12290                        return acc;
12291                    };
12292                    let worktree_id = worktree.read(cx).id();
12293                    let project_path = ProjectPath {
12294                        worktree_id,
12295                        path: relative_path,
12296                    };
12297                    if let Some(local_lsp_store) = self.as_local_mut() {
12298                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12299                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12300                    }
12301                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12302                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12303                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12304                        acc.entry(server_id)
12305                            .or_insert_with(HashMap::default)
12306                            .entry(new_registration_id.clone())
12307                            .or_insert_with(Vec::new)
12308                            .push(DocumentDiagnosticsUpdate {
12309                                server_id,
12310                                diagnostics: lsp::PublishDiagnosticsParams {
12311                                    uri,
12312                                    diagnostics,
12313                                    version,
12314                                },
12315                                result_id,
12316                                disk_based_sources,
12317                                registration_id: new_registration_id,
12318                            });
12319                    }
12320                    acc
12321                },
12322            );
12323
12324        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12325            for (registration_id, diagnostic_updates) in diagnostic_updates {
12326                self.merge_lsp_diagnostics(
12327                    DiagnosticSourceKind::Pulled,
12328                    diagnostic_updates,
12329                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12330                        DiagnosticSourceKind::Pulled => {
12331                            old_diagnostic.registration_id != registration_id
12332                                || unchanged_buffers
12333                                    .get(&old_diagnostic.registration_id)
12334                                    .is_some_and(|unchanged_buffers| {
12335                                        unchanged_buffers.contains(&document_uri)
12336                                    })
12337                        }
12338                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12339                    },
12340                    cx,
12341                )
12342                .log_err();
12343            }
12344        }
12345    }
12346
12347    fn register_server_capabilities(
12348        &mut self,
12349        server_id: LanguageServerId,
12350        params: lsp::RegistrationParams,
12351        cx: &mut Context<Self>,
12352    ) -> anyhow::Result<()> {
12353        let server = self
12354            .language_server_for_id(server_id)
12355            .with_context(|| format!("no server {server_id} found"))?;
12356        for reg in params.registrations {
12357            match reg.method.as_str() {
12358                "workspace/didChangeWatchedFiles" => {
12359                    if let Some(options) = reg.register_options {
12360                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12361                            let caps = serde_json::from_value(options)?;
12362                            local_lsp_store
12363                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12364                            true
12365                        } else {
12366                            false
12367                        };
12368                        if notify {
12369                            notify_server_capabilities_updated(&server, cx);
12370                        }
12371                    }
12372                }
12373                "workspace/didChangeConfiguration" => {
12374                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12375                }
12376                "workspace/didChangeWorkspaceFolders" => {
12377                    // In this case register options is an empty object, we can ignore it
12378                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12379                        supported: Some(true),
12380                        change_notifications: Some(OneOf::Right(reg.id)),
12381                    };
12382                    server.update_capabilities(|capabilities| {
12383                        capabilities
12384                            .workspace
12385                            .get_or_insert_default()
12386                            .workspace_folders = Some(caps);
12387                    });
12388                    notify_server_capabilities_updated(&server, cx);
12389                }
12390                "workspace/symbol" => {
12391                    let options = parse_register_capabilities(reg)?;
12392                    server.update_capabilities(|capabilities| {
12393                        capabilities.workspace_symbol_provider = Some(options);
12394                    });
12395                    notify_server_capabilities_updated(&server, cx);
12396                }
12397                "workspace/fileOperations" => {
12398                    if let Some(options) = reg.register_options {
12399                        let caps = serde_json::from_value(options)?;
12400                        server.update_capabilities(|capabilities| {
12401                            capabilities
12402                                .workspace
12403                                .get_or_insert_default()
12404                                .file_operations = Some(caps);
12405                        });
12406                        notify_server_capabilities_updated(&server, cx);
12407                    }
12408                }
12409                "workspace/executeCommand" => {
12410                    if let Some(options) = reg.register_options {
12411                        let options = serde_json::from_value(options)?;
12412                        server.update_capabilities(|capabilities| {
12413                            capabilities.execute_command_provider = Some(options);
12414                        });
12415                        notify_server_capabilities_updated(&server, cx);
12416                    }
12417                }
12418                "textDocument/rangeFormatting" => {
12419                    let options = parse_register_capabilities(reg)?;
12420                    server.update_capabilities(|capabilities| {
12421                        capabilities.document_range_formatting_provider = Some(options);
12422                    });
12423                    notify_server_capabilities_updated(&server, cx);
12424                }
12425                "textDocument/onTypeFormatting" => {
12426                    if let Some(options) = reg
12427                        .register_options
12428                        .map(serde_json::from_value)
12429                        .transpose()?
12430                    {
12431                        server.update_capabilities(|capabilities| {
12432                            capabilities.document_on_type_formatting_provider = Some(options);
12433                        });
12434                        notify_server_capabilities_updated(&server, cx);
12435                    }
12436                }
12437                "textDocument/formatting" => {
12438                    let options = parse_register_capabilities(reg)?;
12439                    server.update_capabilities(|capabilities| {
12440                        capabilities.document_formatting_provider = Some(options);
12441                    });
12442                    notify_server_capabilities_updated(&server, cx);
12443                }
12444                "textDocument/rename" => {
12445                    let options = parse_register_capabilities(reg)?;
12446                    server.update_capabilities(|capabilities| {
12447                        capabilities.rename_provider = Some(options);
12448                    });
12449                    notify_server_capabilities_updated(&server, cx);
12450                }
12451                "textDocument/inlayHint" => {
12452                    let options = parse_register_capabilities(reg)?;
12453                    server.update_capabilities(|capabilities| {
12454                        capabilities.inlay_hint_provider = Some(options);
12455                    });
12456                    notify_server_capabilities_updated(&server, cx);
12457                }
12458                "textDocument/documentSymbol" => {
12459                    let options = parse_register_capabilities(reg)?;
12460                    server.update_capabilities(|capabilities| {
12461                        capabilities.document_symbol_provider = Some(options);
12462                    });
12463                    notify_server_capabilities_updated(&server, cx);
12464                }
12465                "textDocument/codeAction" => {
12466                    let options = parse_register_capabilities(reg)?;
12467                    let provider = match options {
12468                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12469                        OneOf::Right(caps) => caps,
12470                    };
12471                    server.update_capabilities(|capabilities| {
12472                        capabilities.code_action_provider = Some(provider);
12473                    });
12474                    notify_server_capabilities_updated(&server, cx);
12475                }
12476                "textDocument/definition" => {
12477                    let options = parse_register_capabilities(reg)?;
12478                    server.update_capabilities(|capabilities| {
12479                        capabilities.definition_provider = Some(options);
12480                    });
12481                    notify_server_capabilities_updated(&server, cx);
12482                }
12483                "textDocument/completion" => {
12484                    if let Some(caps) = reg
12485                        .register_options
12486                        .map(serde_json::from_value::<CompletionOptions>)
12487                        .transpose()?
12488                    {
12489                        server.update_capabilities(|capabilities| {
12490                            capabilities.completion_provider = Some(caps.clone());
12491                        });
12492
12493                        if let Some(local) = self.as_local() {
12494                            let mut buffers_with_language_server = Vec::new();
12495                            for handle in self.buffer_store.read(cx).buffers() {
12496                                let buffer_id = handle.read(cx).remote_id();
12497                                if local
12498                                    .buffers_opened_in_servers
12499                                    .get(&buffer_id)
12500                                    .filter(|s| s.contains(&server_id))
12501                                    .is_some()
12502                                {
12503                                    buffers_with_language_server.push(handle);
12504                                }
12505                            }
12506                            let triggers = caps
12507                                .trigger_characters
12508                                .unwrap_or_default()
12509                                .into_iter()
12510                                .collect::<BTreeSet<_>>();
12511                            for handle in buffers_with_language_server {
12512                                let triggers = triggers.clone();
12513                                let _ = handle.update(cx, move |buffer, cx| {
12514                                    buffer.set_completion_triggers(server_id, triggers, cx);
12515                                });
12516                            }
12517                        }
12518                        notify_server_capabilities_updated(&server, cx);
12519                    }
12520                }
12521                "textDocument/hover" => {
12522                    let options = parse_register_capabilities(reg)?;
12523                    let provider = match options {
12524                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12525                        OneOf::Right(caps) => caps,
12526                    };
12527                    server.update_capabilities(|capabilities| {
12528                        capabilities.hover_provider = Some(provider);
12529                    });
12530                    notify_server_capabilities_updated(&server, cx);
12531                }
12532                "textDocument/signatureHelp" => {
12533                    if let Some(caps) = reg
12534                        .register_options
12535                        .map(serde_json::from_value)
12536                        .transpose()?
12537                    {
12538                        server.update_capabilities(|capabilities| {
12539                            capabilities.signature_help_provider = Some(caps);
12540                        });
12541                        notify_server_capabilities_updated(&server, cx);
12542                    }
12543                }
12544                "textDocument/didChange" => {
12545                    if let Some(sync_kind) = reg
12546                        .register_options
12547                        .and_then(|opts| opts.get("syncKind").cloned())
12548                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12549                        .transpose()?
12550                    {
12551                        server.update_capabilities(|capabilities| {
12552                            let mut sync_options =
12553                                Self::take_text_document_sync_options(capabilities);
12554                            sync_options.change = Some(sync_kind);
12555                            capabilities.text_document_sync =
12556                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12557                        });
12558                        notify_server_capabilities_updated(&server, cx);
12559                    }
12560                }
12561                "textDocument/didSave" => {
12562                    if let Some(include_text) = reg
12563                        .register_options
12564                        .map(|opts| {
12565                            let transpose = opts
12566                                .get("includeText")
12567                                .cloned()
12568                                .map(serde_json::from_value::<Option<bool>>)
12569                                .transpose();
12570                            match transpose {
12571                                Ok(value) => Ok(value.flatten()),
12572                                Err(e) => Err(e),
12573                            }
12574                        })
12575                        .transpose()?
12576                    {
12577                        server.update_capabilities(|capabilities| {
12578                            let mut sync_options =
12579                                Self::take_text_document_sync_options(capabilities);
12580                            sync_options.save =
12581                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12582                                    include_text,
12583                                }));
12584                            capabilities.text_document_sync =
12585                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12586                        });
12587                        notify_server_capabilities_updated(&server, cx);
12588                    }
12589                }
12590                "textDocument/codeLens" => {
12591                    if let Some(caps) = reg
12592                        .register_options
12593                        .map(serde_json::from_value)
12594                        .transpose()?
12595                    {
12596                        server.update_capabilities(|capabilities| {
12597                            capabilities.code_lens_provider = Some(caps);
12598                        });
12599                        notify_server_capabilities_updated(&server, cx);
12600                    }
12601                }
12602                "textDocument/diagnostic" => {
12603                    if let Some(caps) = reg
12604                        .register_options
12605                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12606                        .transpose()?
12607                    {
12608                        let local = self
12609                            .as_local_mut()
12610                            .context("Expected LSP Store to be local")?;
12611                        let state = local
12612                            .language_servers
12613                            .get_mut(&server_id)
12614                            .context("Could not obtain Language Servers state")?;
12615                        local
12616                            .language_server_dynamic_registrations
12617                            .entry(server_id)
12618                            .or_default()
12619                            .diagnostics
12620                            .insert(Some(reg.id.clone()), caps.clone());
12621
12622                        let supports_workspace_diagnostics =
12623                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12624                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12625                                    diagnostic_options.workspace_diagnostics
12626                                }
12627                                DiagnosticServerCapabilities::RegistrationOptions(
12628                                    diagnostic_registration_options,
12629                                ) => {
12630                                    diagnostic_registration_options
12631                                        .diagnostic_options
12632                                        .workspace_diagnostics
12633                                }
12634                            };
12635
12636                        if supports_workspace_diagnostics(&caps) {
12637                            if let LanguageServerState::Running {
12638                                workspace_diagnostics_refresh_tasks,
12639                                ..
12640                            } = state
12641                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12642                                    Some(reg.id.clone()),
12643                                    caps.clone(),
12644                                    server.clone(),
12645                                    cx,
12646                                )
12647                            {
12648                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12649                            }
12650                        }
12651
12652                        server.update_capabilities(|capabilities| {
12653                            capabilities.diagnostic_provider = Some(caps);
12654                        });
12655
12656                        notify_server_capabilities_updated(&server, cx);
12657
12658                        let buffers_to_pull: Vec<_> = self
12659                            .as_local()
12660                            .into_iter()
12661                            .flat_map(|local| {
12662                                self.buffer_store.read(cx).buffers().filter(|buffer| {
12663                                    let buffer_id = buffer.read(cx).remote_id();
12664                                    local
12665                                        .buffers_opened_in_servers
12666                                        .get(&buffer_id)
12667                                        .is_some_and(|servers| servers.contains(&server_id))
12668                                })
12669                            })
12670                            .collect();
12671                        for buffer in buffers_to_pull {
12672                            self.pull_diagnostics_for_buffer(buffer, cx).detach();
12673                        }
12674                    }
12675                }
12676                "textDocument/documentColor" => {
12677                    let options = parse_register_capabilities(reg)?;
12678                    let provider = match options {
12679                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12680                        OneOf::Right(caps) => caps,
12681                    };
12682                    server.update_capabilities(|capabilities| {
12683                        capabilities.color_provider = Some(provider);
12684                    });
12685                    notify_server_capabilities_updated(&server, cx);
12686                }
12687                _ => log::warn!("unhandled capability registration: {reg:?}"),
12688            }
12689        }
12690
12691        Ok(())
12692    }
12693
12694    fn unregister_server_capabilities(
12695        &mut self,
12696        server_id: LanguageServerId,
12697        params: lsp::UnregistrationParams,
12698        cx: &mut Context<Self>,
12699    ) -> anyhow::Result<()> {
12700        let server = self
12701            .language_server_for_id(server_id)
12702            .with_context(|| format!("no server {server_id} found"))?;
12703        for unreg in params.unregisterations.iter() {
12704            match unreg.method.as_str() {
12705                "workspace/didChangeWatchedFiles" => {
12706                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12707                        local_lsp_store
12708                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12709                        true
12710                    } else {
12711                        false
12712                    };
12713                    if notify {
12714                        notify_server_capabilities_updated(&server, cx);
12715                    }
12716                }
12717                "workspace/didChangeConfiguration" => {
12718                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12719                }
12720                "workspace/didChangeWorkspaceFolders" => {
12721                    server.update_capabilities(|capabilities| {
12722                        capabilities
12723                            .workspace
12724                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12725                                workspace_folders: None,
12726                                file_operations: None,
12727                            })
12728                            .workspace_folders = None;
12729                    });
12730                    notify_server_capabilities_updated(&server, cx);
12731                }
12732                "workspace/symbol" => {
12733                    server.update_capabilities(|capabilities| {
12734                        capabilities.workspace_symbol_provider = None
12735                    });
12736                    notify_server_capabilities_updated(&server, cx);
12737                }
12738                "workspace/fileOperations" => {
12739                    server.update_capabilities(|capabilities| {
12740                        capabilities
12741                            .workspace
12742                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12743                                workspace_folders: None,
12744                                file_operations: None,
12745                            })
12746                            .file_operations = None;
12747                    });
12748                    notify_server_capabilities_updated(&server, cx);
12749                }
12750                "workspace/executeCommand" => {
12751                    server.update_capabilities(|capabilities| {
12752                        capabilities.execute_command_provider = None;
12753                    });
12754                    notify_server_capabilities_updated(&server, cx);
12755                }
12756                "textDocument/rangeFormatting" => {
12757                    server.update_capabilities(|capabilities| {
12758                        capabilities.document_range_formatting_provider = None
12759                    });
12760                    notify_server_capabilities_updated(&server, cx);
12761                }
12762                "textDocument/onTypeFormatting" => {
12763                    server.update_capabilities(|capabilities| {
12764                        capabilities.document_on_type_formatting_provider = None;
12765                    });
12766                    notify_server_capabilities_updated(&server, cx);
12767                }
12768                "textDocument/formatting" => {
12769                    server.update_capabilities(|capabilities| {
12770                        capabilities.document_formatting_provider = None;
12771                    });
12772                    notify_server_capabilities_updated(&server, cx);
12773                }
12774                "textDocument/rename" => {
12775                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12776                    notify_server_capabilities_updated(&server, cx);
12777                }
12778                "textDocument/codeAction" => {
12779                    server.update_capabilities(|capabilities| {
12780                        capabilities.code_action_provider = None;
12781                    });
12782                    notify_server_capabilities_updated(&server, cx);
12783                }
12784                "textDocument/definition" => {
12785                    server.update_capabilities(|capabilities| {
12786                        capabilities.definition_provider = None;
12787                    });
12788                    notify_server_capabilities_updated(&server, cx);
12789                }
12790                "textDocument/completion" => {
12791                    server.update_capabilities(|capabilities| {
12792                        capabilities.completion_provider = None;
12793                    });
12794                    notify_server_capabilities_updated(&server, cx);
12795                }
12796                "textDocument/hover" => {
12797                    server.update_capabilities(|capabilities| {
12798                        capabilities.hover_provider = None;
12799                    });
12800                    notify_server_capabilities_updated(&server, cx);
12801                }
12802                "textDocument/signatureHelp" => {
12803                    server.update_capabilities(|capabilities| {
12804                        capabilities.signature_help_provider = None;
12805                    });
12806                    notify_server_capabilities_updated(&server, cx);
12807                }
12808                "textDocument/didChange" => {
12809                    server.update_capabilities(|capabilities| {
12810                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12811                        sync_options.change = None;
12812                        capabilities.text_document_sync =
12813                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12814                    });
12815                    notify_server_capabilities_updated(&server, cx);
12816                }
12817                "textDocument/didSave" => {
12818                    server.update_capabilities(|capabilities| {
12819                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12820                        sync_options.save = None;
12821                        capabilities.text_document_sync =
12822                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12823                    });
12824                    notify_server_capabilities_updated(&server, cx);
12825                }
12826                "textDocument/codeLens" => {
12827                    server.update_capabilities(|capabilities| {
12828                        capabilities.code_lens_provider = None;
12829                    });
12830                    notify_server_capabilities_updated(&server, cx);
12831                }
12832                "textDocument/diagnostic" => {
12833                    let local = self
12834                        .as_local_mut()
12835                        .context("Expected LSP Store to be local")?;
12836
12837                    let state = local
12838                        .language_servers
12839                        .get_mut(&server_id)
12840                        .context("Could not obtain Language Servers state")?;
12841                    let registrations = local
12842                        .language_server_dynamic_registrations
12843                        .get_mut(&server_id)
12844                        .with_context(|| {
12845                            format!("Expected dynamic registration to exist for server {server_id}")
12846                        })?;
12847                    registrations.diagnostics
12848                        .remove(&Some(unreg.id.clone()))
12849                        .with_context(|| format!(
12850                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12851                            unreg.id)
12852                        )?;
12853                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12854
12855                    if let LanguageServerState::Running {
12856                        workspace_diagnostics_refresh_tasks,
12857                        ..
12858                    } = state
12859                    {
12860                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12861                    }
12862
12863                    self.clear_unregistered_diagnostics(
12864                        server_id,
12865                        SharedString::from(unreg.id.clone()),
12866                        cx,
12867                    )?;
12868
12869                    if removed_last_diagnostic_provider {
12870                        server.update_capabilities(|capabilities| {
12871                            debug_assert!(capabilities.diagnostic_provider.is_some());
12872                            capabilities.diagnostic_provider = None;
12873                        });
12874                    }
12875
12876                    notify_server_capabilities_updated(&server, cx);
12877                }
12878                "textDocument/documentColor" => {
12879                    server.update_capabilities(|capabilities| {
12880                        capabilities.color_provider = None;
12881                    });
12882                    notify_server_capabilities_updated(&server, cx);
12883                }
12884                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12885            }
12886        }
12887
12888        Ok(())
12889    }
12890
12891    fn clear_unregistered_diagnostics(
12892        &mut self,
12893        server_id: LanguageServerId,
12894        cleared_registration_id: SharedString,
12895        cx: &mut Context<Self>,
12896    ) -> anyhow::Result<()> {
12897        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12898
12899        self.buffer_store.update(cx, |buffer_store, cx| {
12900            for buffer_handle in buffer_store.buffers() {
12901                let buffer = buffer_handle.read(cx);
12902                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12903                let Some(abs_path) = abs_path else {
12904                    continue;
12905                };
12906                affected_abs_paths.insert(abs_path);
12907            }
12908        });
12909
12910        let local = self.as_local().context("Expected LSP Store to be local")?;
12911        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12912            let Some(worktree) = self
12913                .worktree_store
12914                .read(cx)
12915                .worktree_for_id(*worktree_id, cx)
12916            else {
12917                continue;
12918            };
12919
12920            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
12921                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
12922                    let has_matching_registration =
12923                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
12924                            entry.diagnostic.registration_id.as_ref()
12925                                == Some(&cleared_registration_id)
12926                        });
12927                    if has_matching_registration {
12928                        let abs_path = worktree.read(cx).absolutize(rel_path);
12929                        affected_abs_paths.insert(abs_path);
12930                    }
12931                }
12932            }
12933        }
12934
12935        if affected_abs_paths.is_empty() {
12936            return Ok(());
12937        }
12938
12939        // Send a fake diagnostic update which clears the state for the registration ID
12940        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
12941            affected_abs_paths
12942                .into_iter()
12943                .map(|abs_path| DocumentDiagnosticsUpdate {
12944                    diagnostics: DocumentDiagnostics {
12945                        diagnostics: Vec::new(),
12946                        document_abs_path: abs_path,
12947                        version: None,
12948                    },
12949                    result_id: None,
12950                    registration_id: Some(cleared_registration_id.clone()),
12951                    server_id,
12952                    disk_based_sources: Cow::Borrowed(&[]),
12953                })
12954                .collect();
12955
12956        let merge_registration_id = cleared_registration_id.clone();
12957        self.merge_diagnostic_entries(
12958            clears,
12959            move |_, diagnostic, _| {
12960                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
12961                    diagnostic.registration_id != Some(merge_registration_id.clone())
12962                } else {
12963                    true
12964                }
12965            },
12966            cx,
12967        )?;
12968
12969        Ok(())
12970    }
12971
12972    async fn deduplicate_range_based_lsp_requests<T>(
12973        lsp_store: &Entity<Self>,
12974        server_id: Option<LanguageServerId>,
12975        lsp_request_id: LspRequestId,
12976        proto_request: &T::ProtoRequest,
12977        range: Range<Anchor>,
12978        cx: &mut AsyncApp,
12979    ) -> Result<()>
12980    where
12981        T: LspCommand,
12982        T::ProtoRequest: proto::LspRequestMessage,
12983    {
12984        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12985        let version = deserialize_version(proto_request.buffer_version());
12986        let buffer = lsp_store.update(cx, |this, cx| {
12987            this.buffer_store.read(cx).get_existing(buffer_id)
12988        })??;
12989        buffer
12990            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12991            .await?;
12992        lsp_store.update(cx, |lsp_store, cx| {
12993            let buffer_snapshot = buffer.read(cx).snapshot();
12994            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12995            let chunks_queried_for = lsp_data
12996                .inlay_hints
12997                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12998                .collect::<Vec<_>>();
12999            match chunks_queried_for.as_slice() {
13000                &[chunk] => {
13001                    let key = LspKey {
13002                        request_type: TypeId::of::<T>(),
13003                        server_queried: server_id,
13004                    };
13005                    let previous_request = lsp_data
13006                        .chunk_lsp_requests
13007                        .entry(key)
13008                        .or_default()
13009                        .insert(chunk, lsp_request_id);
13010                    if let Some((previous_request, running_requests)) =
13011                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13012                    {
13013                        running_requests.remove(&previous_request);
13014                    }
13015                }
13016                _ambiguous_chunks => {
13017                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13018                    // there, a buffer version-based check will be performed and outdated requests discarded.
13019                }
13020            }
13021            anyhow::Ok(())
13022        })??;
13023
13024        Ok(())
13025    }
13026
13027    async fn query_lsp_locally<T>(
13028        lsp_store: Entity<Self>,
13029        for_server_id: Option<LanguageServerId>,
13030        sender_id: proto::PeerId,
13031        lsp_request_id: LspRequestId,
13032        proto_request: T::ProtoRequest,
13033        position: Option<Anchor>,
13034        cx: &mut AsyncApp,
13035    ) -> Result<()>
13036    where
13037        T: LspCommand + Clone,
13038        T::ProtoRequest: proto::LspRequestMessage,
13039        <T::ProtoRequest as proto::RequestMessage>::Response:
13040            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13041    {
13042        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13043        let version = deserialize_version(proto_request.buffer_version());
13044        let buffer = lsp_store.update(cx, |this, cx| {
13045            this.buffer_store.read(cx).get_existing(buffer_id)
13046        })??;
13047        buffer
13048            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
13049            .await?;
13050        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
13051        let request =
13052            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13053        let key = LspKey {
13054            request_type: TypeId::of::<T>(),
13055            server_queried: for_server_id,
13056        };
13057        lsp_store.update(cx, |lsp_store, cx| {
13058            let request_task = match for_server_id {
13059                Some(server_id) => {
13060                    let server_task = lsp_store.request_lsp(
13061                        buffer.clone(),
13062                        LanguageServerToQuery::Other(server_id),
13063                        request.clone(),
13064                        cx,
13065                    );
13066                    cx.background_spawn(async move {
13067                        let mut responses = Vec::new();
13068                        match server_task.await {
13069                            Ok(response) => responses.push((server_id, response)),
13070                            // rust-analyzer likes to error with this when its still loading up
13071                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13072                            Err(e) => log::error!(
13073                                "Error handling response for request {request:?}: {e:#}"
13074                            ),
13075                        }
13076                        responses
13077                    })
13078                }
13079                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13080            };
13081            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13082            if T::ProtoRequest::stop_previous_requests() {
13083                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13084                    lsp_requests.clear();
13085                }
13086            }
13087            lsp_data.lsp_requests.entry(key).or_default().insert(
13088                lsp_request_id,
13089                cx.spawn(async move |lsp_store, cx| {
13090                    let response = request_task.await;
13091                    lsp_store
13092                        .update(cx, |lsp_store, cx| {
13093                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13094                            {
13095                                let response = response
13096                                    .into_iter()
13097                                    .map(|(server_id, response)| {
13098                                        (
13099                                            server_id.to_proto(),
13100                                            T::response_to_proto(
13101                                                response,
13102                                                lsp_store,
13103                                                sender_id,
13104                                                &buffer_version,
13105                                                cx,
13106                                            )
13107                                            .into(),
13108                                        )
13109                                    })
13110                                    .collect::<HashMap<_, _>>();
13111                                match client.send_lsp_response::<T::ProtoRequest>(
13112                                    project_id,
13113                                    lsp_request_id,
13114                                    response,
13115                                ) {
13116                                    Ok(()) => {}
13117                                    Err(e) => {
13118                                        log::error!("Failed to send LSP response: {e:#}",)
13119                                    }
13120                                }
13121                            }
13122                        })
13123                        .ok();
13124                }),
13125            );
13126        })?;
13127        Ok(())
13128    }
13129
13130    fn take_text_document_sync_options(
13131        capabilities: &mut lsp::ServerCapabilities,
13132    ) -> lsp::TextDocumentSyncOptions {
13133        match capabilities.text_document_sync.take() {
13134            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13135            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13136                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13137                sync_options.change = Some(sync_kind);
13138                sync_options
13139            }
13140            None => lsp::TextDocumentSyncOptions::default(),
13141        }
13142    }
13143
13144    #[cfg(any(test, feature = "test-support"))]
13145    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
13146        Some(
13147            self.lsp_data
13148                .get_mut(&buffer_id)?
13149                .code_lens
13150                .take()?
13151                .update
13152                .take()?
13153                .1,
13154        )
13155    }
13156
13157    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13158        self.downstream_client.clone()
13159    }
13160
13161    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13162        self.worktree_store.clone()
13163    }
13164
13165    /// Gets what's stored in the LSP data for the given buffer.
13166    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13167        self.lsp_data.get_mut(&buffer_id)
13168    }
13169
13170    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13171    /// new [`BufferLspData`] will be created to replace the previous state.
13172    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13173        let (buffer_id, buffer_version) =
13174            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13175        let lsp_data = self
13176            .lsp_data
13177            .entry(buffer_id)
13178            .or_insert_with(|| BufferLspData::new(buffer, cx));
13179        if buffer_version.changed_since(&lsp_data.buffer_version) {
13180            *lsp_data = BufferLspData::new(buffer, cx);
13181        }
13182        lsp_data
13183    }
13184}
13185
13186// Registration with registerOptions as null, should fallback to true.
13187// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13188fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13189    reg: lsp::Registration,
13190) -> Result<OneOf<bool, T>> {
13191    Ok(match reg.register_options {
13192        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13193        None => OneOf::Left(true),
13194    })
13195}
13196
13197fn subscribe_to_binary_statuses(
13198    languages: &Arc<LanguageRegistry>,
13199    cx: &mut Context<'_, LspStore>,
13200) -> Task<()> {
13201    let mut server_statuses = languages.language_server_binary_statuses();
13202    cx.spawn(async move |lsp_store, cx| {
13203        while let Some((server_name, binary_status)) = server_statuses.next().await {
13204            if lsp_store
13205                .update(cx, |_, cx| {
13206                    let mut message = None;
13207                    let binary_status = match binary_status {
13208                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13209                        BinaryStatus::CheckingForUpdate => {
13210                            proto::ServerBinaryStatus::CheckingForUpdate
13211                        }
13212                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13213                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13214                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13215                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13216                        BinaryStatus::Failed { error } => {
13217                            message = Some(error);
13218                            proto::ServerBinaryStatus::Failed
13219                        }
13220                    };
13221                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13222                        // Binary updates are about the binary that might not have any language server id at that point.
13223                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13224                        language_server_id: LanguageServerId(0),
13225                        name: Some(server_name),
13226                        message: proto::update_language_server::Variant::StatusUpdate(
13227                            proto::StatusUpdate {
13228                                message,
13229                                status: Some(proto::status_update::Status::Binary(
13230                                    binary_status as i32,
13231                                )),
13232                            },
13233                        ),
13234                    });
13235                })
13236                .is_err()
13237            {
13238                break;
13239            }
13240        }
13241    })
13242}
13243
13244fn lsp_workspace_diagnostics_refresh(
13245    registration_id: Option<String>,
13246    options: DiagnosticServerCapabilities,
13247    server: Arc<LanguageServer>,
13248    cx: &mut Context<'_, LspStore>,
13249) -> Option<WorkspaceRefreshTask> {
13250    let identifier = workspace_diagnostic_identifier(&options)?;
13251    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13252
13253    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13254    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13255    refresh_tx.try_send(()).ok();
13256
13257    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13258        let mut attempts = 0;
13259        let max_attempts = 50;
13260        let mut requests = 0;
13261
13262        loop {
13263            let Some(()) = refresh_rx.recv().await else {
13264                return;
13265            };
13266
13267            'request: loop {
13268                requests += 1;
13269                if attempts > max_attempts {
13270                    log::error!(
13271                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13272                    );
13273                    return;
13274                }
13275                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13276                cx.background_executor()
13277                    .timer(Duration::from_millis(backoff_millis))
13278                    .await;
13279                attempts += 1;
13280
13281                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13282                    lsp_store
13283                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13284                        .into_iter()
13285                        .filter_map(|(abs_path, result_id)| {
13286                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13287                            Some(lsp::PreviousResultId {
13288                                uri,
13289                                value: result_id.to_string(),
13290                            })
13291                        })
13292                        .collect()
13293                }) else {
13294                    return;
13295                };
13296
13297                let token = if let Some(registration_id) = &registration_id {
13298                    format!(
13299                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13300                        server.server_id(),
13301                    )
13302                } else {
13303                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13304                };
13305
13306                progress_rx.try_recv().ok();
13307                let timer =
13308                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13309                let progress = pin!(progress_rx.recv().fuse());
13310                let response_result = server
13311                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13312                        lsp::WorkspaceDiagnosticParams {
13313                            previous_result_ids,
13314                            identifier: identifier.clone(),
13315                            work_done_progress_params: Default::default(),
13316                            partial_result_params: lsp::PartialResultParams {
13317                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13318                            },
13319                        },
13320                        select(timer, progress).then(|either| match either {
13321                            Either::Left((message, ..)) => ready(message).left_future(),
13322                            Either::Right(..) => pending::<String>().right_future(),
13323                        }),
13324                    )
13325                    .await;
13326
13327                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13328                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13329                match response_result {
13330                    ConnectionResult::Timeout => {
13331                        log::error!("Timeout during workspace diagnostics pull");
13332                        continue 'request;
13333                    }
13334                    ConnectionResult::ConnectionReset => {
13335                        log::error!("Server closed a workspace diagnostics pull request");
13336                        continue 'request;
13337                    }
13338                    ConnectionResult::Result(Err(e)) => {
13339                        log::error!("Error during workspace diagnostics pull: {e:#}");
13340                        break 'request;
13341                    }
13342                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13343                        attempts = 0;
13344                        if lsp_store
13345                            .update(cx, |lsp_store, cx| {
13346                                lsp_store.apply_workspace_diagnostic_report(
13347                                    server.server_id(),
13348                                    pulled_diagnostics,
13349                                    registration_id_shared.clone(),
13350                                    cx,
13351                                )
13352                            })
13353                            .is_err()
13354                        {
13355                            return;
13356                        }
13357                        break 'request;
13358                    }
13359                }
13360            }
13361        }
13362    });
13363
13364    Some(WorkspaceRefreshTask {
13365        refresh_tx,
13366        progress_tx,
13367        task: workspace_query_language_server,
13368    })
13369}
13370
13371fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13372    match &options {
13373        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13374            diagnostic_options.identifier.clone()
13375        }
13376        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13377            let diagnostic_options = &registration_options.diagnostic_options;
13378            diagnostic_options.identifier.clone()
13379        }
13380    }
13381}
13382
13383fn workspace_diagnostic_identifier(
13384    options: &DiagnosticServerCapabilities,
13385) -> Option<Option<String>> {
13386    match &options {
13387        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13388            if !diagnostic_options.workspace_diagnostics {
13389                return None;
13390            }
13391            Some(diagnostic_options.identifier.clone())
13392        }
13393        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13394            let diagnostic_options = &registration_options.diagnostic_options;
13395            if !diagnostic_options.workspace_diagnostics {
13396                return None;
13397            }
13398            Some(diagnostic_options.identifier.clone())
13399        }
13400    }
13401}
13402
13403fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13404    let CompletionSource::BufferWord {
13405        word_range,
13406        resolved,
13407    } = &mut completion.source
13408    else {
13409        return;
13410    };
13411    if *resolved {
13412        return;
13413    }
13414
13415    if completion.new_text
13416        != snapshot
13417            .text_for_range(word_range.clone())
13418            .collect::<String>()
13419    {
13420        return;
13421    }
13422
13423    let mut offset = 0;
13424    for chunk in snapshot.chunks(word_range.clone(), true) {
13425        let end_offset = offset + chunk.text.len();
13426        if let Some(highlight_id) = chunk.syntax_highlight_id {
13427            completion
13428                .label
13429                .runs
13430                .push((offset..end_offset, highlight_id));
13431        }
13432        offset = end_offset;
13433    }
13434    *resolved = true;
13435}
13436
13437impl EventEmitter<LspStoreEvent> for LspStore {}
13438
13439fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13440    hover
13441        .contents
13442        .retain(|hover_block| !hover_block.text.trim().is_empty());
13443    if hover.contents.is_empty() {
13444        None
13445    } else {
13446        Some(hover)
13447    }
13448}
13449
13450async fn populate_labels_for_completions(
13451    new_completions: Vec<CoreCompletion>,
13452    language: Option<Arc<Language>>,
13453    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13454) -> Vec<Completion> {
13455    let lsp_completions = new_completions
13456        .iter()
13457        .filter_map(|new_completion| {
13458            new_completion
13459                .source
13460                .lsp_completion(true)
13461                .map(|lsp_completion| lsp_completion.into_owned())
13462        })
13463        .collect::<Vec<_>>();
13464
13465    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13466        lsp_adapter
13467            .labels_for_completions(&lsp_completions, language)
13468            .await
13469            .log_err()
13470            .unwrap_or_default()
13471    } else {
13472        Vec::new()
13473    }
13474    .into_iter()
13475    .fuse();
13476
13477    let mut completions = Vec::new();
13478    for completion in new_completions {
13479        match completion.source.lsp_completion(true) {
13480            Some(lsp_completion) => {
13481                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13482
13483                let mut label = labels.next().flatten().unwrap_or_else(|| {
13484                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13485                });
13486                ensure_uniform_list_compatible_label(&mut label);
13487                completions.push(Completion {
13488                    label,
13489                    documentation,
13490                    replace_range: completion.replace_range,
13491                    new_text: completion.new_text,
13492                    insert_text_mode: lsp_completion.insert_text_mode,
13493                    source: completion.source,
13494                    icon_path: None,
13495                    confirm: None,
13496                    match_start: None,
13497                    snippet_deduplication_key: None,
13498                });
13499            }
13500            None => {
13501                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13502                ensure_uniform_list_compatible_label(&mut label);
13503                completions.push(Completion {
13504                    label,
13505                    documentation: None,
13506                    replace_range: completion.replace_range,
13507                    new_text: completion.new_text,
13508                    source: completion.source,
13509                    insert_text_mode: None,
13510                    icon_path: None,
13511                    confirm: None,
13512                    match_start: None,
13513                    snippet_deduplication_key: None,
13514                });
13515            }
13516        }
13517    }
13518    completions
13519}
13520
13521#[derive(Debug)]
13522pub enum LanguageServerToQuery {
13523    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13524    FirstCapable,
13525    /// Query a specific language server.
13526    Other(LanguageServerId),
13527}
13528
13529#[derive(Default)]
13530struct RenamePathsWatchedForServer {
13531    did_rename: Vec<RenameActionPredicate>,
13532    will_rename: Vec<RenameActionPredicate>,
13533}
13534
13535impl RenamePathsWatchedForServer {
13536    fn with_did_rename_patterns(
13537        mut self,
13538        did_rename: Option<&FileOperationRegistrationOptions>,
13539    ) -> Self {
13540        if let Some(did_rename) = did_rename {
13541            self.did_rename = did_rename
13542                .filters
13543                .iter()
13544                .filter_map(|filter| filter.try_into().log_err())
13545                .collect();
13546        }
13547        self
13548    }
13549    fn with_will_rename_patterns(
13550        mut self,
13551        will_rename: Option<&FileOperationRegistrationOptions>,
13552    ) -> Self {
13553        if let Some(will_rename) = will_rename {
13554            self.will_rename = will_rename
13555                .filters
13556                .iter()
13557                .filter_map(|filter| filter.try_into().log_err())
13558                .collect();
13559        }
13560        self
13561    }
13562
13563    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13564        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13565    }
13566    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13567        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13568    }
13569}
13570
13571impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13572    type Error = globset::Error;
13573    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13574        Ok(Self {
13575            kind: ops.pattern.matches.clone(),
13576            glob: GlobBuilder::new(&ops.pattern.glob)
13577                .case_insensitive(
13578                    ops.pattern
13579                        .options
13580                        .as_ref()
13581                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13582                )
13583                .build()?
13584                .compile_matcher(),
13585        })
13586    }
13587}
13588struct RenameActionPredicate {
13589    glob: GlobMatcher,
13590    kind: Option<FileOperationPatternKind>,
13591}
13592
13593impl RenameActionPredicate {
13594    // Returns true if language server should be notified
13595    fn eval(&self, path: &str, is_dir: bool) -> bool {
13596        self.kind.as_ref().is_none_or(|kind| {
13597            let expected_kind = if is_dir {
13598                FileOperationPatternKind::Folder
13599            } else {
13600                FileOperationPatternKind::File
13601            };
13602            kind == &expected_kind
13603        }) && self.glob.is_match(path)
13604    }
13605}
13606
13607#[derive(Default)]
13608struct LanguageServerWatchedPaths {
13609    worktree_paths: HashMap<WorktreeId, GlobSet>,
13610    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13611}
13612
13613#[derive(Default)]
13614struct LanguageServerWatchedPathsBuilder {
13615    worktree_paths: HashMap<WorktreeId, GlobSet>,
13616    abs_paths: HashMap<Arc<Path>, GlobSet>,
13617}
13618
13619impl LanguageServerWatchedPathsBuilder {
13620    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13621        self.worktree_paths.insert(worktree_id, glob_set);
13622    }
13623    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13624        self.abs_paths.insert(path, glob_set);
13625    }
13626    fn build(
13627        self,
13628        fs: Arc<dyn Fs>,
13629        language_server_id: LanguageServerId,
13630        cx: &mut Context<LspStore>,
13631    ) -> LanguageServerWatchedPaths {
13632        let lsp_store = cx.weak_entity();
13633
13634        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13635        let abs_paths = self
13636            .abs_paths
13637            .into_iter()
13638            .map(|(abs_path, globset)| {
13639                let task = cx.spawn({
13640                    let abs_path = abs_path.clone();
13641                    let fs = fs.clone();
13642
13643                    let lsp_store = lsp_store.clone();
13644                    async move |_, cx| {
13645                        maybe!(async move {
13646                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13647                            while let Some(update) = push_updates.0.next().await {
13648                                let action = lsp_store
13649                                    .update(cx, |this, _| {
13650                                        let Some(local) = this.as_local() else {
13651                                            return ControlFlow::Break(());
13652                                        };
13653                                        let Some(watcher) = local
13654                                            .language_server_watched_paths
13655                                            .get(&language_server_id)
13656                                        else {
13657                                            return ControlFlow::Break(());
13658                                        };
13659                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13660                                            "Watched abs path is not registered with a watcher",
13661                                        );
13662                                        let matching_entries = update
13663                                            .into_iter()
13664                                            .filter(|event| globs.is_match(&event.path))
13665                                            .collect::<Vec<_>>();
13666                                        this.lsp_notify_abs_paths_changed(
13667                                            language_server_id,
13668                                            matching_entries,
13669                                        );
13670                                        ControlFlow::Continue(())
13671                                    })
13672                                    .ok()?;
13673
13674                                if action.is_break() {
13675                                    break;
13676                                }
13677                            }
13678                            Some(())
13679                        })
13680                        .await;
13681                    }
13682                });
13683                (abs_path, (globset, task))
13684            })
13685            .collect();
13686        LanguageServerWatchedPaths {
13687            worktree_paths: self.worktree_paths,
13688            abs_paths,
13689        }
13690    }
13691}
13692
13693struct LspBufferSnapshot {
13694    version: i32,
13695    snapshot: TextBufferSnapshot,
13696}
13697
13698/// A prompt requested by LSP server.
13699#[derive(Clone, Debug)]
13700pub struct LanguageServerPromptRequest {
13701    pub level: PromptLevel,
13702    pub message: String,
13703    pub actions: Vec<MessageActionItem>,
13704    pub lsp_name: String,
13705    pub(crate) response_channel: Sender<MessageActionItem>,
13706}
13707
13708impl LanguageServerPromptRequest {
13709    pub async fn respond(self, index: usize) -> Option<()> {
13710        if let Some(response) = self.actions.into_iter().nth(index) {
13711            self.response_channel.send(response).await.ok()
13712        } else {
13713            None
13714        }
13715    }
13716}
13717impl PartialEq for LanguageServerPromptRequest {
13718    fn eq(&self, other: &Self) -> bool {
13719        self.message == other.message && self.actions == other.actions
13720    }
13721}
13722
13723#[derive(Clone, Debug, PartialEq)]
13724pub enum LanguageServerLogType {
13725    Log(MessageType),
13726    Trace { verbose_info: Option<String> },
13727    Rpc { received: bool },
13728}
13729
13730impl LanguageServerLogType {
13731    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13732        match self {
13733            Self::Log(log_type) => {
13734                use proto::log_message::LogLevel;
13735                let level = match *log_type {
13736                    MessageType::ERROR => LogLevel::Error,
13737                    MessageType::WARNING => LogLevel::Warning,
13738                    MessageType::INFO => LogLevel::Info,
13739                    MessageType::LOG => LogLevel::Log,
13740                    other => {
13741                        log::warn!("Unknown lsp log message type: {other:?}");
13742                        LogLevel::Log
13743                    }
13744                };
13745                proto::language_server_log::LogType::Log(proto::LogMessage {
13746                    level: level as i32,
13747                })
13748            }
13749            Self::Trace { verbose_info } => {
13750                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13751                    verbose_info: verbose_info.to_owned(),
13752                })
13753            }
13754            Self::Rpc { received } => {
13755                let kind = if *received {
13756                    proto::rpc_message::Kind::Received
13757                } else {
13758                    proto::rpc_message::Kind::Sent
13759                };
13760                let kind = kind as i32;
13761                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13762            }
13763        }
13764    }
13765
13766    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13767        use proto::log_message::LogLevel;
13768        use proto::rpc_message;
13769        match log_type {
13770            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13771                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13772                    LogLevel::Error => MessageType::ERROR,
13773                    LogLevel::Warning => MessageType::WARNING,
13774                    LogLevel::Info => MessageType::INFO,
13775                    LogLevel::Log => MessageType::LOG,
13776                },
13777            ),
13778            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13779                verbose_info: trace_message.verbose_info,
13780            },
13781            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13782                received: match rpc_message::Kind::from_i32(message.kind)
13783                    .unwrap_or(rpc_message::Kind::Received)
13784                {
13785                    rpc_message::Kind::Received => true,
13786                    rpc_message::Kind::Sent => false,
13787                },
13788            },
13789        }
13790    }
13791}
13792
13793pub struct WorkspaceRefreshTask {
13794    refresh_tx: mpsc::Sender<()>,
13795    progress_tx: mpsc::Sender<()>,
13796    #[allow(dead_code)]
13797    task: Task<()>,
13798}
13799
13800pub enum LanguageServerState {
13801    Starting {
13802        startup: Task<Option<Arc<LanguageServer>>>,
13803        /// List of language servers that will be added to the workspace once it's initialization completes.
13804        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13805    },
13806
13807    Running {
13808        adapter: Arc<CachedLspAdapter>,
13809        server: Arc<LanguageServer>,
13810        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13811        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13812    },
13813}
13814
13815impl LanguageServerState {
13816    fn add_workspace_folder(&self, uri: Uri) {
13817        match self {
13818            LanguageServerState::Starting {
13819                pending_workspace_folders,
13820                ..
13821            } => {
13822                pending_workspace_folders.lock().insert(uri);
13823            }
13824            LanguageServerState::Running { server, .. } => {
13825                server.add_workspace_folder(uri);
13826            }
13827        }
13828    }
13829    fn _remove_workspace_folder(&self, uri: Uri) {
13830        match self {
13831            LanguageServerState::Starting {
13832                pending_workspace_folders,
13833                ..
13834            } => {
13835                pending_workspace_folders.lock().remove(&uri);
13836            }
13837            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13838        }
13839    }
13840}
13841
13842impl std::fmt::Debug for LanguageServerState {
13843    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13844        match self {
13845            LanguageServerState::Starting { .. } => {
13846                f.debug_struct("LanguageServerState::Starting").finish()
13847            }
13848            LanguageServerState::Running { .. } => {
13849                f.debug_struct("LanguageServerState::Running").finish()
13850            }
13851        }
13852    }
13853}
13854
13855#[derive(Clone, Debug, Serialize)]
13856pub struct LanguageServerProgress {
13857    pub is_disk_based_diagnostics_progress: bool,
13858    pub is_cancellable: bool,
13859    pub title: Option<String>,
13860    pub message: Option<String>,
13861    pub percentage: Option<usize>,
13862    #[serde(skip_serializing)]
13863    pub last_update_at: Instant,
13864}
13865
13866#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13867pub struct DiagnosticSummary {
13868    pub error_count: usize,
13869    pub warning_count: usize,
13870}
13871
13872impl DiagnosticSummary {
13873    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13874        let mut this = Self {
13875            error_count: 0,
13876            warning_count: 0,
13877        };
13878
13879        for entry in diagnostics {
13880            if entry.diagnostic.is_primary {
13881                match entry.diagnostic.severity {
13882                    DiagnosticSeverity::ERROR => this.error_count += 1,
13883                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13884                    _ => {}
13885                }
13886            }
13887        }
13888
13889        this
13890    }
13891
13892    pub fn is_empty(&self) -> bool {
13893        self.error_count == 0 && self.warning_count == 0
13894    }
13895
13896    pub fn to_proto(
13897        self,
13898        language_server_id: LanguageServerId,
13899        path: &RelPath,
13900    ) -> proto::DiagnosticSummary {
13901        proto::DiagnosticSummary {
13902            path: path.to_proto(),
13903            language_server_id: language_server_id.0 as u64,
13904            error_count: self.error_count as u32,
13905            warning_count: self.warning_count as u32,
13906        }
13907    }
13908}
13909
13910#[derive(Clone, Debug)]
13911pub enum CompletionDocumentation {
13912    /// There is no documentation for this completion.
13913    Undocumented,
13914    /// A single line of documentation.
13915    SingleLine(SharedString),
13916    /// Multiple lines of plain text documentation.
13917    MultiLinePlainText(SharedString),
13918    /// Markdown documentation.
13919    MultiLineMarkdown(SharedString),
13920    /// Both single line and multiple lines of plain text documentation.
13921    SingleLineAndMultiLinePlainText {
13922        single_line: SharedString,
13923        plain_text: Option<SharedString>,
13924    },
13925}
13926
13927impl CompletionDocumentation {
13928    #[cfg(any(test, feature = "test-support"))]
13929    pub fn text(&self) -> SharedString {
13930        match self {
13931            CompletionDocumentation::Undocumented => "".into(),
13932            CompletionDocumentation::SingleLine(s) => s.clone(),
13933            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13934            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13935            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13936                single_line.clone()
13937            }
13938        }
13939    }
13940}
13941
13942impl From<lsp::Documentation> for CompletionDocumentation {
13943    fn from(docs: lsp::Documentation) -> Self {
13944        match docs {
13945            lsp::Documentation::String(text) => {
13946                if text.lines().count() <= 1 {
13947                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
13948                } else {
13949                    CompletionDocumentation::MultiLinePlainText(text.into())
13950                }
13951            }
13952
13953            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13954                lsp::MarkupKind::PlainText => {
13955                    if value.lines().count() <= 1 {
13956                        CompletionDocumentation::SingleLine(value.into())
13957                    } else {
13958                        CompletionDocumentation::MultiLinePlainText(value.into())
13959                    }
13960                }
13961
13962                lsp::MarkupKind::Markdown => {
13963                    CompletionDocumentation::MultiLineMarkdown(value.into())
13964                }
13965            },
13966        }
13967    }
13968}
13969
13970pub enum ResolvedHint {
13971    Resolved(InlayHint),
13972    Resolving(Shared<Task<()>>),
13973}
13974
13975fn glob_literal_prefix(glob: &Path) -> PathBuf {
13976    glob.components()
13977        .take_while(|component| match component {
13978            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13979            _ => true,
13980        })
13981        .collect()
13982}
13983
13984pub struct SshLspAdapter {
13985    name: LanguageServerName,
13986    binary: LanguageServerBinary,
13987    initialization_options: Option<String>,
13988    code_action_kinds: Option<Vec<CodeActionKind>>,
13989}
13990
13991impl SshLspAdapter {
13992    pub fn new(
13993        name: LanguageServerName,
13994        binary: LanguageServerBinary,
13995        initialization_options: Option<String>,
13996        code_action_kinds: Option<String>,
13997    ) -> Self {
13998        Self {
13999            name,
14000            binary,
14001            initialization_options,
14002            code_action_kinds: code_action_kinds
14003                .as_ref()
14004                .and_then(|c| serde_json::from_str(c).ok()),
14005        }
14006    }
14007}
14008
14009impl LspInstaller for SshLspAdapter {
14010    type BinaryVersion = ();
14011    async fn check_if_user_installed(
14012        &self,
14013        _: &dyn LspAdapterDelegate,
14014        _: Option<Toolchain>,
14015        _: &AsyncApp,
14016    ) -> Option<LanguageServerBinary> {
14017        Some(self.binary.clone())
14018    }
14019
14020    async fn cached_server_binary(
14021        &self,
14022        _: PathBuf,
14023        _: &dyn LspAdapterDelegate,
14024    ) -> Option<LanguageServerBinary> {
14025        None
14026    }
14027
14028    async fn fetch_latest_server_version(
14029        &self,
14030        _: &dyn LspAdapterDelegate,
14031        _: bool,
14032        _: &mut AsyncApp,
14033    ) -> Result<()> {
14034        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14035    }
14036
14037    async fn fetch_server_binary(
14038        &self,
14039        _: (),
14040        _: PathBuf,
14041        _: &dyn LspAdapterDelegate,
14042    ) -> Result<LanguageServerBinary> {
14043        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14044    }
14045}
14046
14047#[async_trait(?Send)]
14048impl LspAdapter for SshLspAdapter {
14049    fn name(&self) -> LanguageServerName {
14050        self.name.clone()
14051    }
14052
14053    async fn initialization_options(
14054        self: Arc<Self>,
14055        _: &Arc<dyn LspAdapterDelegate>,
14056    ) -> Result<Option<serde_json::Value>> {
14057        let Some(options) = &self.initialization_options else {
14058            return Ok(None);
14059        };
14060        let result = serde_json::from_str(options)?;
14061        Ok(result)
14062    }
14063
14064    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14065        self.code_action_kinds.clone()
14066    }
14067}
14068
14069pub fn language_server_settings<'a>(
14070    delegate: &'a dyn LspAdapterDelegate,
14071    language: &LanguageServerName,
14072    cx: &'a App,
14073) -> Option<&'a LspSettings> {
14074    language_server_settings_for(
14075        SettingsLocation {
14076            worktree_id: delegate.worktree_id(),
14077            path: RelPath::empty(),
14078        },
14079        language,
14080        cx,
14081    )
14082}
14083
14084pub fn language_server_settings_for<'a>(
14085    location: SettingsLocation<'a>,
14086    language: &LanguageServerName,
14087    cx: &'a App,
14088) -> Option<&'a LspSettings> {
14089    ProjectSettings::get(Some(location), cx).lsp.get(language)
14090}
14091
14092pub struct LocalLspAdapterDelegate {
14093    lsp_store: WeakEntity<LspStore>,
14094    worktree: worktree::Snapshot,
14095    fs: Arc<dyn Fs>,
14096    http_client: Arc<dyn HttpClient>,
14097    language_registry: Arc<LanguageRegistry>,
14098    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14099}
14100
14101impl LocalLspAdapterDelegate {
14102    pub fn new(
14103        language_registry: Arc<LanguageRegistry>,
14104        environment: &Entity<ProjectEnvironment>,
14105        lsp_store: WeakEntity<LspStore>,
14106        worktree: &Entity<Worktree>,
14107        http_client: Arc<dyn HttpClient>,
14108        fs: Arc<dyn Fs>,
14109        cx: &mut App,
14110    ) -> Arc<Self> {
14111        let load_shell_env_task =
14112            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14113
14114        Arc::new(Self {
14115            lsp_store,
14116            worktree: worktree.read(cx).snapshot(),
14117            fs,
14118            http_client,
14119            language_registry,
14120            load_shell_env_task,
14121        })
14122    }
14123
14124    pub fn from_local_lsp(
14125        local: &LocalLspStore,
14126        worktree: &Entity<Worktree>,
14127        cx: &mut App,
14128    ) -> Arc<Self> {
14129        Self::new(
14130            local.languages.clone(),
14131            &local.environment,
14132            local.weak.clone(),
14133            worktree,
14134            local.http_client.clone(),
14135            local.fs.clone(),
14136            cx,
14137        )
14138    }
14139}
14140
14141#[async_trait]
14142impl LspAdapterDelegate for LocalLspAdapterDelegate {
14143    fn show_notification(&self, message: &str, cx: &mut App) {
14144        self.lsp_store
14145            .update(cx, |_, cx| {
14146                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14147            })
14148            .ok();
14149    }
14150
14151    fn http_client(&self) -> Arc<dyn HttpClient> {
14152        self.http_client.clone()
14153    }
14154
14155    fn worktree_id(&self) -> WorktreeId {
14156        self.worktree.id()
14157    }
14158
14159    fn worktree_root_path(&self) -> &Path {
14160        self.worktree.abs_path().as_ref()
14161    }
14162
14163    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
14164        self.worktree.resolve_executable_path(path)
14165    }
14166
14167    async fn shell_env(&self) -> HashMap<String, String> {
14168        let task = self.load_shell_env_task.clone();
14169        task.await.unwrap_or_default()
14170    }
14171
14172    async fn npm_package_installed_version(
14173        &self,
14174        package_name: &str,
14175    ) -> Result<Option<(PathBuf, Version)>> {
14176        let local_package_directory = self.worktree_root_path();
14177        let node_modules_directory = local_package_directory.join("node_modules");
14178
14179        if let Some(version) =
14180            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14181        {
14182            return Ok(Some((node_modules_directory, version)));
14183        }
14184        let Some(npm) = self.which("npm".as_ref()).await else {
14185            log::warn!(
14186                "Failed to find npm executable for {:?}",
14187                local_package_directory
14188            );
14189            return Ok(None);
14190        };
14191
14192        let env = self.shell_env().await;
14193        let output = util::command::new_smol_command(&npm)
14194            .args(["root", "-g"])
14195            .envs(env)
14196            .current_dir(local_package_directory)
14197            .output()
14198            .await?;
14199        let global_node_modules =
14200            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14201
14202        if let Some(version) =
14203            read_package_installed_version(global_node_modules.clone(), package_name).await?
14204        {
14205            return Ok(Some((global_node_modules, version)));
14206        }
14207        return Ok(None);
14208    }
14209
14210    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14211        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14212        if self.fs.is_file(&worktree_abs_path).await {
14213            worktree_abs_path.pop();
14214        }
14215
14216        let env = self.shell_env().await;
14217
14218        let shell_path = env.get("PATH").cloned();
14219
14220        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14221    }
14222
14223    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14224        let mut working_dir = self.worktree_root_path().to_path_buf();
14225        if self.fs.is_file(&working_dir).await {
14226            working_dir.pop();
14227        }
14228        let output = util::command::new_smol_command(&command.path)
14229            .args(command.arguments)
14230            .envs(command.env.clone().unwrap_or_default())
14231            .current_dir(working_dir)
14232            .output()
14233            .await?;
14234
14235        anyhow::ensure!(
14236            output.status.success(),
14237            "{}, stdout: {:?}, stderr: {:?}",
14238            output.status,
14239            String::from_utf8_lossy(&output.stdout),
14240            String::from_utf8_lossy(&output.stderr)
14241        );
14242        Ok(())
14243    }
14244
14245    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14246        self.language_registry
14247            .update_lsp_binary_status(server_name, status);
14248    }
14249
14250    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14251        self.language_registry
14252            .all_lsp_adapters()
14253            .into_iter()
14254            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14255            .collect()
14256    }
14257
14258    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14259        let dir = self.language_registry.language_server_download_dir(name)?;
14260
14261        if !dir.exists() {
14262            smol::fs::create_dir_all(&dir)
14263                .await
14264                .context("failed to create container directory")
14265                .log_err()?;
14266        }
14267
14268        Some(dir)
14269    }
14270
14271    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14272        let entry = self
14273            .worktree
14274            .entry_for_path(path)
14275            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14276        let abs_path = self.worktree.absolutize(&entry.path);
14277        self.fs.load(&abs_path).await
14278    }
14279}
14280
14281async fn populate_labels_for_symbols(
14282    symbols: Vec<CoreSymbol>,
14283    language_registry: &Arc<LanguageRegistry>,
14284    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14285    output: &mut Vec<Symbol>,
14286) {
14287    #[allow(clippy::mutable_key_type)]
14288    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14289
14290    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14291    for symbol in symbols {
14292        let Some(file_name) = symbol.path.file_name() else {
14293            continue;
14294        };
14295        let language = language_registry
14296            .load_language_for_file_path(Path::new(file_name))
14297            .await
14298            .ok()
14299            .or_else(|| {
14300                unknown_paths.insert(file_name.into());
14301                None
14302            });
14303        symbols_by_language
14304            .entry(language)
14305            .or_default()
14306            .push(symbol);
14307    }
14308
14309    for unknown_path in unknown_paths {
14310        log::info!("no language found for symbol in file {unknown_path:?}");
14311    }
14312
14313    let mut label_params = Vec::new();
14314    for (language, mut symbols) in symbols_by_language {
14315        label_params.clear();
14316        label_params.extend(
14317            symbols
14318                .iter_mut()
14319                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14320        );
14321
14322        let mut labels = Vec::new();
14323        if let Some(language) = language {
14324            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14325                language_registry
14326                    .lsp_adapters(&language.name())
14327                    .first()
14328                    .cloned()
14329            });
14330            if let Some(lsp_adapter) = lsp_adapter {
14331                labels = lsp_adapter
14332                    .labels_for_symbols(&label_params, &language)
14333                    .await
14334                    .log_err()
14335                    .unwrap_or_default();
14336            }
14337        }
14338
14339        for ((symbol, (name, _)), label) in symbols
14340            .into_iter()
14341            .zip(label_params.drain(..))
14342            .zip(labels.into_iter().chain(iter::repeat(None)))
14343        {
14344            output.push(Symbol {
14345                language_server_name: symbol.language_server_name,
14346                source_worktree_id: symbol.source_worktree_id,
14347                source_language_server_id: symbol.source_language_server_id,
14348                path: symbol.path,
14349                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14350                name,
14351                kind: symbol.kind,
14352                range: symbol.range,
14353            });
14354        }
14355    }
14356}
14357
14358fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14359    match server.capabilities().text_document_sync.as_ref()? {
14360        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14361            // Server wants didSave but didn't specify includeText.
14362            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14363            // Server doesn't want didSave at all.
14364            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14365            // Server provided SaveOptions.
14366            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14367                Some(save_options.include_text.unwrap_or(false))
14368            }
14369        },
14370        // We do not have any save info. Kind affects didChange only.
14371        lsp::TextDocumentSyncCapability::Kind(_) => None,
14372    }
14373}
14374
14375/// Completion items are displayed in a `UniformList`.
14376/// Usually, those items are single-line strings, but in LSP responses,
14377/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14378/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14379/// 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,
14380/// breaking the completions menu presentation.
14381///
14382/// 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.
14383fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14384    let mut new_text = String::with_capacity(label.text.len());
14385    let mut offset_map = vec![0; label.text.len() + 1];
14386    let mut last_char_was_space = false;
14387    let mut new_idx = 0;
14388    let chars = label.text.char_indices().fuse();
14389    let mut newlines_removed = false;
14390
14391    for (idx, c) in chars {
14392        offset_map[idx] = new_idx;
14393
14394        match c {
14395            '\n' if last_char_was_space => {
14396                newlines_removed = true;
14397            }
14398            '\t' | ' ' if last_char_was_space => {}
14399            '\n' if !last_char_was_space => {
14400                new_text.push(' ');
14401                new_idx += 1;
14402                last_char_was_space = true;
14403                newlines_removed = true;
14404            }
14405            ' ' | '\t' => {
14406                new_text.push(' ');
14407                new_idx += 1;
14408                last_char_was_space = true;
14409            }
14410            _ => {
14411                new_text.push(c);
14412                new_idx += c.len_utf8();
14413                last_char_was_space = false;
14414            }
14415        }
14416    }
14417    offset_map[label.text.len()] = new_idx;
14418
14419    // Only modify the label if newlines were removed.
14420    if !newlines_removed {
14421        return;
14422    }
14423
14424    let last_index = new_idx;
14425    let mut run_ranges_errors = Vec::new();
14426    label.runs.retain_mut(|(range, _)| {
14427        match offset_map.get(range.start) {
14428            Some(&start) => range.start = start,
14429            None => {
14430                run_ranges_errors.push(range.clone());
14431                return false;
14432            }
14433        }
14434
14435        match offset_map.get(range.end) {
14436            Some(&end) => range.end = end,
14437            None => {
14438                run_ranges_errors.push(range.clone());
14439                range.end = last_index;
14440            }
14441        }
14442        true
14443    });
14444    if !run_ranges_errors.is_empty() {
14445        log::error!(
14446            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14447            label.text
14448        );
14449    }
14450
14451    let mut wrong_filter_range = None;
14452    if label.filter_range == (0..label.text.len()) {
14453        label.filter_range = 0..new_text.len();
14454    } else {
14455        let mut original_filter_range = Some(label.filter_range.clone());
14456        match offset_map.get(label.filter_range.start) {
14457            Some(&start) => label.filter_range.start = start,
14458            None => {
14459                wrong_filter_range = original_filter_range.take();
14460                label.filter_range.start = last_index;
14461            }
14462        }
14463
14464        match offset_map.get(label.filter_range.end) {
14465            Some(&end) => label.filter_range.end = end,
14466            None => {
14467                wrong_filter_range = original_filter_range.take();
14468                label.filter_range.end = last_index;
14469            }
14470        }
14471    }
14472    if let Some(wrong_filter_range) = wrong_filter_range {
14473        log::error!(
14474            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14475            label.text
14476        );
14477    }
14478
14479    label.text = new_text;
14480}
14481
14482#[cfg(test)]
14483mod tests {
14484    use language::HighlightId;
14485
14486    use super::*;
14487
14488    #[test]
14489    fn test_glob_literal_prefix() {
14490        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14491        assert_eq!(
14492            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14493            Path::new("node_modules")
14494        );
14495        assert_eq!(
14496            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14497            Path::new("foo")
14498        );
14499        assert_eq!(
14500            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14501            Path::new("foo/bar/baz.js")
14502        );
14503
14504        #[cfg(target_os = "windows")]
14505        {
14506            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14507            assert_eq!(
14508                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14509                Path::new("node_modules")
14510            );
14511            assert_eq!(
14512                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14513                Path::new("foo")
14514            );
14515            assert_eq!(
14516                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14517                Path::new("foo/bar/baz.js")
14518            );
14519        }
14520    }
14521
14522    #[test]
14523    fn test_multi_len_chars_normalization() {
14524        let mut label = CodeLabel::new(
14525            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14526            0..6,
14527            vec![(0..6, HighlightId(1))],
14528        );
14529        ensure_uniform_list_compatible_label(&mut label);
14530        assert_eq!(
14531            label,
14532            CodeLabel::new(
14533                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14534                0..6,
14535                vec![(0..6, HighlightId(1))],
14536            )
14537        );
14538    }
14539
14540    #[test]
14541    fn test_trailing_newline_in_completion_documentation() {
14542        let doc = lsp::Documentation::String(
14543            "Inappropriate argument value (of correct type).\n".to_string(),
14544        );
14545        let completion_doc: CompletionDocumentation = doc.into();
14546        assert!(
14547            matches!(completion_doc, CompletionDocumentation::SingleLine(s) if s == "Inappropriate argument value (of correct type).")
14548        );
14549
14550        let doc = lsp::Documentation::String("  some value  \n".to_string());
14551        let completion_doc: CompletionDocumentation = doc.into();
14552        assert!(matches!(
14553            completion_doc,
14554            CompletionDocumentation::SingleLine(s) if s == "some value"
14555        ));
14556    }
14557}