lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13pub mod json_language_server_ext;
   14pub mod log_store;
   15pub mod lsp_ext_command;
   16pub mod rust_analyzer_ext;
   17pub mod vue_language_server_ext;
   18
   19mod inlay_hint_cache;
   20
   21use self::inlay_hint_cache::BufferInlayHints;
   22use crate::{
   23    CodeAction, ColorPresentation, Completion, CompletionDisplayOptions, CompletionResponse,
   24    CompletionSource, CoreCompletion, DocumentColor, Hover, InlayHint, InlayId, LocationLink,
   25    LspAction, LspPullDiagnostics, ManifestProvidersStore, Project, ProjectItem, ProjectPath,
   26    ProjectTransaction, PulledDiagnostics, ResolveState, Symbol,
   27    buffer_store::{BufferStore, BufferStoreEvent},
   28    environment::ProjectEnvironment,
   29    lsp_command::{self, *},
   30    lsp_store::{
   31        self,
   32        log_store::{GlobalLogStore, LanguageServerKind},
   33    },
   34    manifest_tree::{
   35        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   36        ManifestTree,
   37    },
   38    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   39    project_settings::{LspSettings, ProjectSettings},
   40    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   41    trusted_worktrees::{PathTrust, TrustedWorktrees, TrustedWorktreesEvent},
   42    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   43    yarn::YarnPathStore,
   44};
   45use anyhow::{Context as _, Result, anyhow};
   46use async_trait::async_trait;
   47use client::{TypedEnvelope, proto};
   48use clock::Global;
   49use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   50use futures::{
   51    AsyncWriteExt, Future, FutureExt, StreamExt,
   52    future::{Either, Shared, join_all, pending, select},
   53    select, select_biased,
   54    stream::FuturesUnordered,
   55};
   56use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   57use gpui::{
   58    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString,
   59    Subscription, Task, WeakEntity,
   60};
   61use http_client::HttpClient;
   62use itertools::Itertools as _;
   63use language::{
   64    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   65    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   66    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate,
   67    ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Toolchain,
   68    Transaction, Unclipped,
   69    language_settings::{FormatOnSave, Formatter, LanguageSettings, language_settings},
   70    point_to_lsp,
   71    proto::{
   72        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   73        serialize_lsp_edit, serialize_version,
   74    },
   75    range_from_lsp, range_to_lsp,
   76    row_chunk::RowChunk,
   77};
   78use lsp::{
   79    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   80    DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   81    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   82    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LSP_REQUEST_TIMEOUT,
   83    LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId,
   84    LanguageServerName, LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType,
   85    OneOf, RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri,
   86    WillRenameFiles, WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   87};
   88use node_runtime::read_package_installed_version;
   89use parking_lot::Mutex;
   90use postage::{mpsc, sink::Sink, stream::Stream, watch};
   91use rand::prelude::*;
   92use rpc::{
   93    AnyProtoClient, ErrorCode, ErrorExt as _,
   94    proto::{LspRequestId, LspRequestMessage as _},
   95};
   96use 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    rel_path::RelPath,
  132};
  133
  134pub use fs::*;
  135pub use language::Location;
  136pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  137#[cfg(any(test, feature = "test-support"))]
  138pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  139pub use worktree::{
  140    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  141    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  142};
  143
  144const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  145pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  146const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  147const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  148
  149#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  150pub enum ProgressToken {
  151    Number(i32),
  152    String(SharedString),
  153}
  154
  155impl std::fmt::Display for ProgressToken {
  156    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  157        match self {
  158            Self::Number(number) => write!(f, "{number}"),
  159            Self::String(string) => write!(f, "{string}"),
  160        }
  161    }
  162}
  163
  164impl ProgressToken {
  165    fn from_lsp(value: lsp::NumberOrString) -> Self {
  166        match value {
  167            lsp::NumberOrString::Number(number) => Self::Number(number),
  168            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  169        }
  170    }
  171
  172    fn to_lsp(&self) -> lsp::NumberOrString {
  173        match self {
  174            Self::Number(number) => lsp::NumberOrString::Number(*number),
  175            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  176        }
  177    }
  178
  179    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  180        Some(match value.value? {
  181            proto::progress_token::Value::Number(number) => Self::Number(number),
  182            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  183        })
  184    }
  185
  186    fn to_proto(&self) -> proto::ProgressToken {
  187        proto::ProgressToken {
  188            value: Some(match self {
  189                Self::Number(number) => proto::progress_token::Value::Number(*number),
  190                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  191            }),
  192        }
  193    }
  194}
  195
  196#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  197pub enum FormatTrigger {
  198    Save,
  199    Manual,
  200}
  201
  202pub enum LspFormatTarget {
  203    Buffers,
  204    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  205}
  206
  207#[derive(Clone, PartialEq, Eq, Hash)]
  208pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  209
  210struct OpenLspBuffer(Entity<Buffer>);
  211
  212impl FormatTrigger {
  213    fn from_proto(value: i32) -> FormatTrigger {
  214        match value {
  215            0 => FormatTrigger::Save,
  216            1 => FormatTrigger::Manual,
  217            _ => FormatTrigger::Save,
  218        }
  219    }
  220}
  221
  222#[derive(Clone)]
  223struct UnifiedLanguageServer {
  224    id: LanguageServerId,
  225    project_roots: HashSet<Arc<RelPath>>,
  226}
  227
  228#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  229struct LanguageServerSeed {
  230    worktree_id: WorktreeId,
  231    name: LanguageServerName,
  232    toolchain: Option<Toolchain>,
  233    settings: Arc<LspSettings>,
  234}
  235
  236#[derive(Debug)]
  237pub struct DocumentDiagnosticsUpdate<'a, D> {
  238    pub diagnostics: D,
  239    pub result_id: Option<SharedString>,
  240    pub registration_id: Option<SharedString>,
  241    pub server_id: LanguageServerId,
  242    pub disk_based_sources: Cow<'a, [String]>,
  243}
  244
  245pub struct DocumentDiagnostics {
  246    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  247    document_abs_path: PathBuf,
  248    version: Option<i32>,
  249}
  250
  251#[derive(Default, Debug)]
  252struct DynamicRegistrations {
  253    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  254    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  255}
  256
  257pub struct LocalLspStore {
  258    weak: WeakEntity<LspStore>,
  259    worktree_store: Entity<WorktreeStore>,
  260    toolchain_store: Entity<LocalToolchainStore>,
  261    http_client: Arc<dyn HttpClient>,
  262    environment: Entity<ProjectEnvironment>,
  263    fs: Arc<dyn Fs>,
  264    languages: Arc<LanguageRegistry>,
  265    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  266    yarn: Entity<YarnPathStore>,
  267    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  268    buffers_being_formatted: HashSet<BufferId>,
  269    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  270    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  271    watched_manifest_filenames: HashSet<ManifestName>,
  272    language_server_paths_watched_for_rename:
  273        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  274    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  275    supplementary_language_servers:
  276        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  277    prettier_store: Entity<PrettierStore>,
  278    next_diagnostic_group_id: usize,
  279    diagnostics: HashMap<
  280        WorktreeId,
  281        HashMap<
  282            Arc<RelPath>,
  283            Vec<(
  284                LanguageServerId,
  285                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  286            )>,
  287        >,
  288    >,
  289    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  290    _subscription: gpui::Subscription,
  291    lsp_tree: LanguageServerTree,
  292    registered_buffers: HashMap<BufferId, usize>,
  293    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  294    buffer_pull_diagnostics_result_ids: HashMap<
  295        LanguageServerId,
  296        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  297    >,
  298    workspace_pull_diagnostics_result_ids: HashMap<
  299        LanguageServerId,
  300        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  301    >,
  302    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, Receiver<()>)>,
  303}
  304
  305impl LocalLspStore {
  306    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  307    pub fn running_language_server_for_id(
  308        &self,
  309        id: LanguageServerId,
  310    ) -> Option<&Arc<LanguageServer>> {
  311        let language_server_state = self.language_servers.get(&id)?;
  312
  313        match language_server_state {
  314            LanguageServerState::Running { server, .. } => Some(server),
  315            LanguageServerState::Starting { .. } => None,
  316        }
  317    }
  318
  319    fn get_or_insert_language_server(
  320        &mut self,
  321        worktree_handle: &Entity<Worktree>,
  322        delegate: Arc<LocalLspAdapterDelegate>,
  323        disposition: &Arc<LaunchDisposition>,
  324        language_name: &LanguageName,
  325        cx: &mut App,
  326    ) -> LanguageServerId {
  327        let key = LanguageServerSeed {
  328            worktree_id: worktree_handle.read(cx).id(),
  329            name: disposition.server_name.clone(),
  330            settings: disposition.settings.clone(),
  331            toolchain: disposition.toolchain.clone(),
  332        };
  333        if let Some(state) = self.language_server_ids.get_mut(&key) {
  334            state.project_roots.insert(disposition.path.path.clone());
  335            state.id
  336        } else {
  337            let adapter = self
  338                .languages
  339                .lsp_adapters(language_name)
  340                .into_iter()
  341                .find(|adapter| adapter.name() == disposition.server_name)
  342                .expect("To find LSP adapter");
  343            let new_language_server_id = self.start_language_server(
  344                worktree_handle,
  345                delegate,
  346                adapter,
  347                disposition.settings.clone(),
  348                key.clone(),
  349                cx,
  350            );
  351            if let Some(state) = self.language_server_ids.get_mut(&key) {
  352                state.project_roots.insert(disposition.path.path.clone());
  353            } else {
  354                debug_assert!(
  355                    false,
  356                    "Expected `start_language_server` to ensure that `key` exists in a map"
  357                );
  358            }
  359            new_language_server_id
  360        }
  361    }
  362
  363    fn start_language_server(
  364        &mut self,
  365        worktree_handle: &Entity<Worktree>,
  366        delegate: Arc<LocalLspAdapterDelegate>,
  367        adapter: Arc<CachedLspAdapter>,
  368        settings: Arc<LspSettings>,
  369        key: LanguageServerSeed,
  370        cx: &mut App,
  371    ) -> LanguageServerId {
  372        let worktree = worktree_handle.read(cx);
  373
  374        let worktree_id = worktree.id();
  375        let worktree_abs_path = worktree.abs_path();
  376        let toolchain = key.toolchain.clone();
  377        let override_options = settings.initialization_options.clone();
  378
  379        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  380
  381        let server_id = self.languages.next_language_server_id();
  382        log::trace!(
  383            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  384            adapter.name.0
  385        );
  386
  387        let untrusted_worktree_task =
  388            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  389                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  390                    trusted_worktrees.can_trust(worktree_id, cx)
  391                });
  392                if can_trust {
  393                    self.restricted_worktrees_tasks.remove(&worktree_id);
  394                    None
  395                } else {
  396                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  397                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  398                        hash_map::Entry::Vacant(v) => {
  399                            let (tx, rx) = smol::channel::bounded::<()>(1);
  400                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, _| {
  401                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  402                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  403                                        tx.send_blocking(()).ok();
  404                                    }
  405                                }
  406                            });
  407                            v.insert((subscription, rx.clone()));
  408                            Some(rx)
  409                        }
  410                    }
  411                }
  412            });
  413        let update_binary_status = untrusted_worktree_task.is_none();
  414
  415        let binary = self.get_language_server_binary(
  416            worktree_abs_path.clone(),
  417            adapter.clone(),
  418            settings,
  419            toolchain.clone(),
  420            delegate.clone(),
  421            true,
  422            untrusted_worktree_task,
  423            cx,
  424        );
  425        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  426
  427        let pending_server = cx.spawn({
  428            let adapter = adapter.clone();
  429            let server_name = adapter.name.clone();
  430            let stderr_capture = stderr_capture.clone();
  431            #[cfg(any(test, feature = "test-support"))]
  432            let lsp_store = self.weak.clone();
  433            let pending_workspace_folders = pending_workspace_folders.clone();
  434            async move |cx| {
  435                let binary = binary.await?;
  436                #[cfg(any(test, feature = "test-support"))]
  437                if let Some(server) = lsp_store
  438                    .update(&mut cx.clone(), |this, cx| {
  439                        this.languages.create_fake_language_server(
  440                            server_id,
  441                            &server_name,
  442                            binary.clone(),
  443                            &mut cx.to_async(),
  444                        )
  445                    })
  446                    .ok()
  447                    .flatten()
  448                {
  449                    return Ok(server);
  450                }
  451
  452                let code_action_kinds = adapter.code_action_kinds();
  453                lsp::LanguageServer::new(
  454                    stderr_capture,
  455                    server_id,
  456                    server_name,
  457                    binary,
  458                    &worktree_abs_path,
  459                    code_action_kinds,
  460                    Some(pending_workspace_folders),
  461                    cx,
  462                )
  463            }
  464        });
  465
  466        let startup = {
  467            let server_name = adapter.name.0.clone();
  468            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  469            let key = key.clone();
  470            let adapter = adapter.clone();
  471            let lsp_store = self.weak.clone();
  472            let pending_workspace_folders = pending_workspace_folders.clone();
  473
  474            let pull_diagnostics = ProjectSettings::get_global(cx)
  475                .diagnostics
  476                .lsp_pull_diagnostics
  477                .enabled;
  478            cx.spawn(async move |cx| {
  479                let result = async {
  480                    let language_server = pending_server.await?;
  481
  482                    let workspace_config = Self::workspace_configuration_for_adapter(
  483                        adapter.adapter.clone(),
  484                        &delegate,
  485                        toolchain,
  486                        None,
  487                        cx,
  488                    )
  489                    .await?;
  490
  491                    let mut initialization_options = Self::initialization_options_for_adapter(
  492                        adapter.adapter.clone(),
  493                        &delegate,
  494                    )
  495                    .await?;
  496
  497                    match (&mut initialization_options, override_options) {
  498                        (Some(initialization_options), Some(override_options)) => {
  499                            merge_json_value_into(override_options, initialization_options);
  500                        }
  501                        (None, override_options) => initialization_options = override_options,
  502                        _ => {}
  503                    }
  504
  505                    let initialization_params = cx.update(|cx| {
  506                        let mut params =
  507                            language_server.default_initialize_params(pull_diagnostics, cx);
  508                        params.initialization_options = initialization_options;
  509                        adapter.adapter.prepare_initialize_params(params, cx)
  510                    })??;
  511
  512                    Self::setup_lsp_messages(
  513                        lsp_store.clone(),
  514                        &language_server,
  515                        delegate.clone(),
  516                        adapter.clone(),
  517                    );
  518
  519                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  520                        settings: workspace_config,
  521                    };
  522                    let language_server = cx
  523                        .update(|cx| {
  524                            language_server.initialize(
  525                                initialization_params,
  526                                Arc::new(did_change_configuration_params.clone()),
  527                                cx,
  528                            )
  529                        })?
  530                        .await
  531                        .inspect_err(|_| {
  532                            if let Some(lsp_store) = lsp_store.upgrade() {
  533                                lsp_store
  534                                    .update(cx, |lsp_store, cx| {
  535                                        lsp_store.cleanup_lsp_data(server_id);
  536                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  537                                    })
  538                                    .ok();
  539                            }
  540                        })?;
  541
  542                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  543                        did_change_configuration_params,
  544                    )?;
  545
  546                    anyhow::Ok(language_server)
  547                }
  548                .await;
  549
  550                match result {
  551                    Ok(server) => {
  552                        lsp_store
  553                            .update(cx, |lsp_store, cx| {
  554                                lsp_store.insert_newly_running_language_server(
  555                                    adapter,
  556                                    server.clone(),
  557                                    server_id,
  558                                    key,
  559                                    pending_workspace_folders,
  560                                    cx,
  561                                );
  562                            })
  563                            .ok();
  564                        stderr_capture.lock().take();
  565                        Some(server)
  566                    }
  567
  568                    Err(err) => {
  569                        let log = stderr_capture.lock().take().unwrap_or_default();
  570                        delegate.update_status(
  571                            adapter.name(),
  572                            BinaryStatus::Failed {
  573                                error: if log.is_empty() {
  574                                    format!("{err:#}")
  575                                } else {
  576                                    format!("{err:#}\n-- stderr --\n{log}")
  577                                },
  578                            },
  579                        );
  580                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  581                        if !log.is_empty() {
  582                            log::error!("server stderr: {log}");
  583                        }
  584                        None
  585                    }
  586                }
  587            })
  588        };
  589        let state = LanguageServerState::Starting {
  590            startup,
  591            pending_workspace_folders,
  592        };
  593
  594        if update_binary_status {
  595            self.languages
  596                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  597        }
  598
  599        self.language_servers.insert(server_id, state);
  600        self.language_server_ids
  601            .entry(key)
  602            .or_insert(UnifiedLanguageServer {
  603                id: server_id,
  604                project_roots: Default::default(),
  605            });
  606        server_id
  607    }
  608
  609    fn get_language_server_binary(
  610        &self,
  611        worktree_abs_path: Arc<Path>,
  612        adapter: Arc<CachedLspAdapter>,
  613        settings: Arc<LspSettings>,
  614        toolchain: Option<Toolchain>,
  615        delegate: Arc<dyn LspAdapterDelegate>,
  616        allow_binary_download: bool,
  617        untrusted_worktree_task: Option<Receiver<()>>,
  618        cx: &mut App,
  619    ) -> Task<Result<LanguageServerBinary>> {
  620        if let Some(settings) = &settings.binary
  621            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  622        {
  623            let settings = settings.clone();
  624            let languages = self.languages.clone();
  625            return cx.background_spawn(async move {
  626                if let Some(untrusted_worktree_task) = untrusted_worktree_task {
  627                    log::info!(
  628                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  629                        adapter.name(),
  630                    );
  631                    untrusted_worktree_task.recv().await.ok();
  632                    log::info!(
  633                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  634                        adapter.name(),
  635                    );
  636                    languages
  637                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  638                }
  639                let mut env = delegate.shell_env().await;
  640                env.extend(settings.env.unwrap_or_default());
  641
  642                Ok(LanguageServerBinary {
  643                    path: delegate.resolve_executable_path(path),
  644                    env: Some(env),
  645                    arguments: settings
  646                        .arguments
  647                        .unwrap_or_default()
  648                        .iter()
  649                        .map(Into::into)
  650                        .collect(),
  651                })
  652            });
  653        }
  654        let lsp_binary_options = LanguageServerBinaryOptions {
  655            allow_path_lookup: !settings
  656                .binary
  657                .as_ref()
  658                .and_then(|b| b.ignore_system_version)
  659                .unwrap_or_default(),
  660            allow_binary_download,
  661            pre_release: settings
  662                .fetch
  663                .as_ref()
  664                .and_then(|f| f.pre_release)
  665                .unwrap_or(false),
  666        };
  667
  668        cx.spawn(async move |cx| {
  669            if let Some(untrusted_worktree_task) = untrusted_worktree_task {
  670                log::info!(
  671                    "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  672                    adapter.name(),
  673                );
  674                untrusted_worktree_task.recv().await.ok();
  675                log::info!(
  676                    "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  677                    adapter.name(),
  678                );
  679            }
  680
  681            let (existing_binary, maybe_download_binary) = adapter
  682                .clone()
  683                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  684                .await
  685                .await;
  686
  687            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  688
  689            let mut binary = match (existing_binary, maybe_download_binary) {
  690                (binary, None) => binary?,
  691                (Err(_), Some(downloader)) => downloader.await?,
  692                (Ok(existing_binary), Some(downloader)) => {
  693                    let mut download_timeout = cx
  694                        .background_executor()
  695                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  696                        .fuse();
  697                    let mut downloader = downloader.fuse();
  698                    futures::select! {
  699                        _ = download_timeout => {
  700                            // Return existing binary and kick the existing work to the background.
  701                            cx.spawn(async move |_| downloader.await).detach();
  702                            Ok(existing_binary)
  703                        },
  704                        downloaded_or_existing_binary = downloader => {
  705                            // If download fails, this results in the existing binary.
  706                            downloaded_or_existing_binary
  707                        }
  708                    }?
  709                }
  710            };
  711            let mut shell_env = delegate.shell_env().await;
  712
  713            shell_env.extend(binary.env.unwrap_or_default());
  714
  715            if let Some(settings) = settings.binary.as_ref() {
  716                if let Some(arguments) = &settings.arguments {
  717                    binary.arguments = arguments.iter().map(Into::into).collect();
  718                }
  719                if let Some(env) = &settings.env {
  720                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  721                }
  722            }
  723
  724            binary.env = Some(shell_env);
  725            Ok(binary)
  726        })
  727    }
  728
  729    fn setup_lsp_messages(
  730        lsp_store: WeakEntity<LspStore>,
  731        language_server: &LanguageServer,
  732        delegate: Arc<dyn LspAdapterDelegate>,
  733        adapter: Arc<CachedLspAdapter>,
  734    ) {
  735        let name = language_server.name();
  736        let server_id = language_server.server_id();
  737        language_server
  738            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  739                let adapter = adapter.clone();
  740                let this = lsp_store.clone();
  741                move |mut params, cx| {
  742                    let adapter = adapter.clone();
  743                    if let Some(this) = this.upgrade() {
  744                        this.update(cx, |this, cx| {
  745                            {
  746                                let buffer = params
  747                                    .uri
  748                                    .to_file_path()
  749                                    .map(|file_path| this.get_buffer(&file_path, cx))
  750                                    .ok()
  751                                    .flatten();
  752                                adapter.process_diagnostics(&mut params, server_id, buffer);
  753                            }
  754
  755                            this.merge_lsp_diagnostics(
  756                                DiagnosticSourceKind::Pushed,
  757                                vec![DocumentDiagnosticsUpdate {
  758                                    server_id,
  759                                    diagnostics: params,
  760                                    result_id: None,
  761                                    disk_based_sources: Cow::Borrowed(
  762                                        &adapter.disk_based_diagnostic_sources,
  763                                    ),
  764                                    registration_id: None,
  765                                }],
  766                                |_, diagnostic, cx| match diagnostic.source_kind {
  767                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  768                                        adapter.retain_old_diagnostic(diagnostic, cx)
  769                                    }
  770                                    DiagnosticSourceKind::Pulled => true,
  771                                },
  772                                cx,
  773                            )
  774                            .log_err();
  775                        })
  776                        .ok();
  777                    }
  778                }
  779            })
  780            .detach();
  781        language_server
  782            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  783                let adapter = adapter.adapter.clone();
  784                let delegate = delegate.clone();
  785                let this = lsp_store.clone();
  786                move |params, cx| {
  787                    let adapter = adapter.clone();
  788                    let delegate = delegate.clone();
  789                    let this = this.clone();
  790                    let mut cx = cx.clone();
  791                    async move {
  792                        let toolchain_for_id = this
  793                            .update(&mut cx, |this, _| {
  794                                this.as_local()?.language_server_ids.iter().find_map(
  795                                    |(seed, value)| {
  796                                        (value.id == server_id).then(|| seed.toolchain.clone())
  797                                    },
  798                                )
  799                            })?
  800                            .context("Expected the LSP store to be in a local mode")?;
  801
  802                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  803                        for item in &params.items {
  804                            let scope_uri = item.scope_uri.clone();
  805                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  806                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  807                            else {
  808                                // We've already queried workspace configuration of this URI.
  809                                continue;
  810                            };
  811                            let workspace_config = Self::workspace_configuration_for_adapter(
  812                                adapter.clone(),
  813                                &delegate,
  814                                toolchain_for_id.clone(),
  815                                scope_uri,
  816                                &mut cx,
  817                            )
  818                            .await?;
  819                            new_scope_uri.insert(workspace_config);
  820                        }
  821
  822                        Ok(params
  823                            .items
  824                            .into_iter()
  825                            .filter_map(|item| {
  826                                let workspace_config =
  827                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  828                                if let Some(section) = &item.section {
  829                                    Some(
  830                                        workspace_config
  831                                            .get(section)
  832                                            .cloned()
  833                                            .unwrap_or(serde_json::Value::Null),
  834                                    )
  835                                } else {
  836                                    Some(workspace_config.clone())
  837                                }
  838                            })
  839                            .collect())
  840                    }
  841                }
  842            })
  843            .detach();
  844
  845        language_server
  846            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  847                let this = lsp_store.clone();
  848                move |_, cx| {
  849                    let this = this.clone();
  850                    let cx = cx.clone();
  851                    async move {
  852                        let Some(server) =
  853                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  854                        else {
  855                            return Ok(None);
  856                        };
  857                        let root = server.workspace_folders();
  858                        Ok(Some(
  859                            root.into_iter()
  860                                .map(|uri| WorkspaceFolder {
  861                                    uri,
  862                                    name: Default::default(),
  863                                })
  864                                .collect(),
  865                        ))
  866                    }
  867                }
  868            })
  869            .detach();
  870        // Even though we don't have handling for these requests, respond to them to
  871        // avoid stalling any language server like `gopls` which waits for a response
  872        // to these requests when initializing.
  873        language_server
  874            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  875                let this = lsp_store.clone();
  876                move |params, cx| {
  877                    let this = this.clone();
  878                    let mut cx = cx.clone();
  879                    async move {
  880                        this.update(&mut cx, |this, _| {
  881                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  882                            {
  883                                status
  884                                    .progress_tokens
  885                                    .insert(ProgressToken::from_lsp(params.token));
  886                            }
  887                        })?;
  888
  889                        Ok(())
  890                    }
  891                }
  892            })
  893            .detach();
  894
  895        language_server
  896            .on_request::<lsp::request::RegisterCapability, _, _>({
  897                let lsp_store = lsp_store.clone();
  898                move |params, cx| {
  899                    let lsp_store = lsp_store.clone();
  900                    let mut cx = cx.clone();
  901                    async move {
  902                        lsp_store
  903                            .update(&mut cx, |lsp_store, cx| {
  904                                if lsp_store.as_local().is_some() {
  905                                    match lsp_store
  906                                        .register_server_capabilities(server_id, params, cx)
  907                                    {
  908                                        Ok(()) => {}
  909                                        Err(e) => {
  910                                            log::error!(
  911                                                "Failed to register server capabilities: {e:#}"
  912                                            );
  913                                        }
  914                                    };
  915                                }
  916                            })
  917                            .ok();
  918                        Ok(())
  919                    }
  920                }
  921            })
  922            .detach();
  923
  924        language_server
  925            .on_request::<lsp::request::UnregisterCapability, _, _>({
  926                let lsp_store = lsp_store.clone();
  927                move |params, cx| {
  928                    let lsp_store = lsp_store.clone();
  929                    let mut cx = cx.clone();
  930                    async move {
  931                        lsp_store
  932                            .update(&mut cx, |lsp_store, cx| {
  933                                if lsp_store.as_local().is_some() {
  934                                    match lsp_store
  935                                        .unregister_server_capabilities(server_id, params, cx)
  936                                    {
  937                                        Ok(()) => {}
  938                                        Err(e) => {
  939                                            log::error!(
  940                                                "Failed to unregister server capabilities: {e:#}"
  941                                            );
  942                                        }
  943                                    }
  944                                }
  945                            })
  946                            .ok();
  947                        Ok(())
  948                    }
  949                }
  950            })
  951            .detach();
  952
  953        language_server
  954            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  955                let this = lsp_store.clone();
  956                move |params, cx| {
  957                    let mut cx = cx.clone();
  958                    let this = this.clone();
  959                    async move {
  960                        LocalLspStore::on_lsp_workspace_edit(
  961                            this.clone(),
  962                            params,
  963                            server_id,
  964                            &mut cx,
  965                        )
  966                        .await
  967                    }
  968                }
  969            })
  970            .detach();
  971
  972        language_server
  973            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  974                let lsp_store = lsp_store.clone();
  975                let request_id = Arc::new(AtomicUsize::new(0));
  976                move |(), cx| {
  977                    let lsp_store = lsp_store.clone();
  978                    let request_id = request_id.clone();
  979                    let mut cx = cx.clone();
  980                    async move {
  981                        lsp_store
  982                            .update(&mut cx, |lsp_store, cx| {
  983                                let request_id =
  984                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
  985                                cx.emit(LspStoreEvent::RefreshInlayHints {
  986                                    server_id,
  987                                    request_id,
  988                                });
  989                                lsp_store
  990                                    .downstream_client
  991                                    .as_ref()
  992                                    .map(|(client, project_id)| {
  993                                        client.send(proto::RefreshInlayHints {
  994                                            project_id: *project_id,
  995                                            server_id: server_id.to_proto(),
  996                                            request_id: request_id.map(|id| id as u64),
  997                                        })
  998                                    })
  999                            })?
 1000                            .transpose()?;
 1001                        Ok(())
 1002                    }
 1003                }
 1004            })
 1005            .detach();
 1006
 1007        language_server
 1008            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1009                let this = lsp_store.clone();
 1010                move |(), cx| {
 1011                    let this = this.clone();
 1012                    let mut cx = cx.clone();
 1013                    async move {
 1014                        this.update(&mut cx, |this, cx| {
 1015                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1016                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1017                                client.send(proto::RefreshCodeLens {
 1018                                    project_id: *project_id,
 1019                                })
 1020                            })
 1021                        })?
 1022                        .transpose()?;
 1023                        Ok(())
 1024                    }
 1025                }
 1026            })
 1027            .detach();
 1028
 1029        language_server
 1030            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1031                let this = lsp_store.clone();
 1032                move |(), cx| {
 1033                    let this = this.clone();
 1034                    let mut cx = cx.clone();
 1035                    async move {
 1036                        this.update(&mut cx, |lsp_store, _| {
 1037                            lsp_store.pull_workspace_diagnostics(server_id);
 1038                            lsp_store
 1039                                .downstream_client
 1040                                .as_ref()
 1041                                .map(|(client, project_id)| {
 1042                                    client.send(proto::PullWorkspaceDiagnostics {
 1043                                        project_id: *project_id,
 1044                                        server_id: server_id.to_proto(),
 1045                                    })
 1046                                })
 1047                        })?
 1048                        .transpose()?;
 1049                        Ok(())
 1050                    }
 1051                }
 1052            })
 1053            .detach();
 1054
 1055        language_server
 1056            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1057                let this = lsp_store.clone();
 1058                let name = name.to_string();
 1059                let adapter = adapter.clone();
 1060                move |params, cx| {
 1061                    let this = this.clone();
 1062                    let name = name.to_string();
 1063                    let adapter = adapter.clone();
 1064                    let mut cx = cx.clone();
 1065                    async move {
 1066                        let actions = params.actions.unwrap_or_default();
 1067                        let message = params.message.clone();
 1068                        let (tx, rx) = smol::channel::bounded(1);
 1069                        let request = LanguageServerPromptRequest {
 1070                            level: match params.typ {
 1071                                lsp::MessageType::ERROR => PromptLevel::Critical,
 1072                                lsp::MessageType::WARNING => PromptLevel::Warning,
 1073                                _ => PromptLevel::Info,
 1074                            },
 1075                            message: params.message,
 1076                            actions,
 1077                            response_channel: tx,
 1078                            lsp_name: name.clone(),
 1079                        };
 1080
 1081                        let did_update = this
 1082                            .update(&mut cx, |_, cx| {
 1083                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1084                            })
 1085                            .is_ok();
 1086                        if did_update {
 1087                            let response = rx.recv().await.ok();
 1088                            if let Some(ref selected_action) = response {
 1089                                let context = language::PromptResponseContext {
 1090                                    message,
 1091                                    selected_action: selected_action.clone(),
 1092                                };
 1093                                adapter.process_prompt_response(&context, &mut cx)
 1094                            }
 1095
 1096                            Ok(response)
 1097                        } else {
 1098                            Ok(None)
 1099                        }
 1100                    }
 1101                }
 1102            })
 1103            .detach();
 1104        language_server
 1105            .on_notification::<lsp::notification::ShowMessage, _>({
 1106                let this = lsp_store.clone();
 1107                let name = name.to_string();
 1108                move |params, cx| {
 1109                    let this = this.clone();
 1110                    let name = name.to_string();
 1111                    let mut cx = cx.clone();
 1112
 1113                    let (tx, _) = smol::channel::bounded(1);
 1114                    let request = LanguageServerPromptRequest {
 1115                        level: match params.typ {
 1116                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1117                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1118                            _ => PromptLevel::Info,
 1119                        },
 1120                        message: params.message,
 1121                        actions: vec![],
 1122                        response_channel: tx,
 1123                        lsp_name: name,
 1124                    };
 1125
 1126                    let _ = this.update(&mut cx, |_, cx| {
 1127                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1128                    });
 1129                }
 1130            })
 1131            .detach();
 1132
 1133        let disk_based_diagnostics_progress_token =
 1134            adapter.disk_based_diagnostics_progress_token.clone();
 1135
 1136        language_server
 1137            .on_notification::<lsp::notification::Progress, _>({
 1138                let this = lsp_store.clone();
 1139                move |params, cx| {
 1140                    if let Some(this) = this.upgrade() {
 1141                        this.update(cx, |this, cx| {
 1142                            this.on_lsp_progress(
 1143                                params,
 1144                                server_id,
 1145                                disk_based_diagnostics_progress_token.clone(),
 1146                                cx,
 1147                            );
 1148                        })
 1149                        .ok();
 1150                    }
 1151                }
 1152            })
 1153            .detach();
 1154
 1155        language_server
 1156            .on_notification::<lsp::notification::LogMessage, _>({
 1157                let this = lsp_store.clone();
 1158                move |params, cx| {
 1159                    if let Some(this) = this.upgrade() {
 1160                        this.update(cx, |_, cx| {
 1161                            cx.emit(LspStoreEvent::LanguageServerLog(
 1162                                server_id,
 1163                                LanguageServerLogType::Log(params.typ),
 1164                                params.message,
 1165                            ));
 1166                        })
 1167                        .ok();
 1168                    }
 1169                }
 1170            })
 1171            .detach();
 1172
 1173        language_server
 1174            .on_notification::<lsp::notification::LogTrace, _>({
 1175                let this = lsp_store.clone();
 1176                move |params, cx| {
 1177                    let mut cx = cx.clone();
 1178                    if let Some(this) = this.upgrade() {
 1179                        this.update(&mut cx, |_, cx| {
 1180                            cx.emit(LspStoreEvent::LanguageServerLog(
 1181                                server_id,
 1182                                LanguageServerLogType::Trace {
 1183                                    verbose_info: params.verbose,
 1184                                },
 1185                                params.message,
 1186                            ));
 1187                        })
 1188                        .ok();
 1189                    }
 1190                }
 1191            })
 1192            .detach();
 1193
 1194        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1195        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1196        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1197        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1198    }
 1199
 1200    fn shutdown_language_servers_on_quit(
 1201        &mut self,
 1202        _: &mut Context<LspStore>,
 1203    ) -> impl Future<Output = ()> + use<> {
 1204        let shutdown_futures = self
 1205            .language_servers
 1206            .drain()
 1207            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1208            .collect::<Vec<_>>();
 1209
 1210        async move {
 1211            join_all(shutdown_futures).await;
 1212        }
 1213    }
 1214
 1215    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1216        match server_state {
 1217            LanguageServerState::Running { server, .. } => {
 1218                if let Some(shutdown) = server.shutdown() {
 1219                    shutdown.await;
 1220                }
 1221            }
 1222            LanguageServerState::Starting { startup, .. } => {
 1223                if let Some(server) = startup.await
 1224                    && let Some(shutdown) = server.shutdown()
 1225                {
 1226                    shutdown.await;
 1227                }
 1228            }
 1229        }
 1230        Ok(())
 1231    }
 1232
 1233    fn language_servers_for_worktree(
 1234        &self,
 1235        worktree_id: WorktreeId,
 1236    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1237        self.language_server_ids
 1238            .iter()
 1239            .filter_map(move |(seed, state)| {
 1240                if seed.worktree_id != worktree_id {
 1241                    return None;
 1242                }
 1243
 1244                if let Some(LanguageServerState::Running { server, .. }) =
 1245                    self.language_servers.get(&state.id)
 1246                {
 1247                    Some(server)
 1248                } else {
 1249                    None
 1250                }
 1251            })
 1252    }
 1253
 1254    fn language_server_ids_for_project_path(
 1255        &self,
 1256        project_path: ProjectPath,
 1257        language: &Language,
 1258        cx: &mut App,
 1259    ) -> Vec<LanguageServerId> {
 1260        let Some(worktree) = self
 1261            .worktree_store
 1262            .read(cx)
 1263            .worktree_for_id(project_path.worktree_id, cx)
 1264        else {
 1265            return Vec::new();
 1266        };
 1267        let delegate: Arc<dyn ManifestDelegate> =
 1268            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1269
 1270        self.lsp_tree
 1271            .get(
 1272                project_path,
 1273                language.name(),
 1274                language.manifest(),
 1275                &delegate,
 1276                cx,
 1277            )
 1278            .collect::<Vec<_>>()
 1279    }
 1280
 1281    fn language_server_ids_for_buffer(
 1282        &self,
 1283        buffer: &Buffer,
 1284        cx: &mut App,
 1285    ) -> Vec<LanguageServerId> {
 1286        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1287            let worktree_id = file.worktree_id(cx);
 1288
 1289            let path: Arc<RelPath> = file
 1290                .path()
 1291                .parent()
 1292                .map(Arc::from)
 1293                .unwrap_or_else(|| file.path().clone());
 1294            let worktree_path = ProjectPath { worktree_id, path };
 1295            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1296        } else {
 1297            Vec::new()
 1298        }
 1299    }
 1300
 1301    fn language_servers_for_buffer<'a>(
 1302        &'a self,
 1303        buffer: &'a Buffer,
 1304        cx: &'a mut App,
 1305    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1306        self.language_server_ids_for_buffer(buffer, cx)
 1307            .into_iter()
 1308            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1309                LanguageServerState::Running {
 1310                    adapter, server, ..
 1311                } => Some((adapter, server)),
 1312                _ => None,
 1313            })
 1314    }
 1315
 1316    async fn execute_code_action_kind_locally(
 1317        lsp_store: WeakEntity<LspStore>,
 1318        mut buffers: Vec<Entity<Buffer>>,
 1319        kind: CodeActionKind,
 1320        push_to_history: bool,
 1321        cx: &mut AsyncApp,
 1322    ) -> anyhow::Result<ProjectTransaction> {
 1323        // Do not allow multiple concurrent code actions requests for the
 1324        // same buffer.
 1325        lsp_store.update(cx, |this, cx| {
 1326            let this = this.as_local_mut().unwrap();
 1327            buffers.retain(|buffer| {
 1328                this.buffers_being_formatted
 1329                    .insert(buffer.read(cx).remote_id())
 1330            });
 1331        })?;
 1332        let _cleanup = defer({
 1333            let this = lsp_store.clone();
 1334            let mut cx = cx.clone();
 1335            let buffers = &buffers;
 1336            move || {
 1337                this.update(&mut cx, |this, cx| {
 1338                    let this = this.as_local_mut().unwrap();
 1339                    for buffer in buffers {
 1340                        this.buffers_being_formatted
 1341                            .remove(&buffer.read(cx).remote_id());
 1342                    }
 1343                })
 1344                .ok();
 1345            }
 1346        });
 1347        let mut project_transaction = ProjectTransaction::default();
 1348
 1349        for buffer in &buffers {
 1350            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1351                buffer.update(cx, |buffer, cx| {
 1352                    lsp_store
 1353                        .as_local()
 1354                        .unwrap()
 1355                        .language_servers_for_buffer(buffer, cx)
 1356                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1357                        .collect::<Vec<_>>()
 1358                })
 1359            })?;
 1360            for (_, language_server) in adapters_and_servers.iter() {
 1361                let actions = Self::get_server_code_actions_from_action_kinds(
 1362                    &lsp_store,
 1363                    language_server.server_id(),
 1364                    vec![kind.clone()],
 1365                    buffer,
 1366                    cx,
 1367                )
 1368                .await?;
 1369                Self::execute_code_actions_on_server(
 1370                    &lsp_store,
 1371                    language_server,
 1372                    actions,
 1373                    push_to_history,
 1374                    &mut project_transaction,
 1375                    cx,
 1376                )
 1377                .await?;
 1378            }
 1379        }
 1380        Ok(project_transaction)
 1381    }
 1382
 1383    async fn format_locally(
 1384        lsp_store: WeakEntity<LspStore>,
 1385        mut buffers: Vec<FormattableBuffer>,
 1386        push_to_history: bool,
 1387        trigger: FormatTrigger,
 1388        logger: zlog::Logger,
 1389        cx: &mut AsyncApp,
 1390    ) -> anyhow::Result<ProjectTransaction> {
 1391        // Do not allow multiple concurrent formatting requests for the
 1392        // same buffer.
 1393        lsp_store.update(cx, |this, cx| {
 1394            let this = this.as_local_mut().unwrap();
 1395            buffers.retain(|buffer| {
 1396                this.buffers_being_formatted
 1397                    .insert(buffer.handle.read(cx).remote_id())
 1398            });
 1399        })?;
 1400
 1401        let _cleanup = defer({
 1402            let this = lsp_store.clone();
 1403            let mut cx = cx.clone();
 1404            let buffers = &buffers;
 1405            move || {
 1406                this.update(&mut cx, |this, cx| {
 1407                    let this = this.as_local_mut().unwrap();
 1408                    for buffer in buffers {
 1409                        this.buffers_being_formatted
 1410                            .remove(&buffer.handle.read(cx).remote_id());
 1411                    }
 1412                })
 1413                .ok();
 1414            }
 1415        });
 1416
 1417        let mut project_transaction = ProjectTransaction::default();
 1418
 1419        for buffer in &buffers {
 1420            zlog::debug!(
 1421                logger =>
 1422                "formatting buffer '{:?}'",
 1423                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1424            );
 1425            // Create an empty transaction to hold all of the formatting edits.
 1426            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1427                // ensure no transactions created while formatting are
 1428                // grouped with the previous transaction in the history
 1429                // based on the transaction group interval
 1430                buffer.finalize_last_transaction();
 1431                buffer
 1432                    .start_transaction()
 1433                    .context("transaction already open")?;
 1434                buffer.end_transaction(cx);
 1435                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1436                buffer.finalize_last_transaction();
 1437                anyhow::Ok(transaction_id)
 1438            })??;
 1439
 1440            let result = Self::format_buffer_locally(
 1441                lsp_store.clone(),
 1442                buffer,
 1443                formatting_transaction_id,
 1444                trigger,
 1445                logger,
 1446                cx,
 1447            )
 1448            .await;
 1449
 1450            buffer.handle.update(cx, |buffer, cx| {
 1451                let Some(formatting_transaction) =
 1452                    buffer.get_transaction(formatting_transaction_id).cloned()
 1453                else {
 1454                    zlog::warn!(logger => "no formatting transaction");
 1455                    return;
 1456                };
 1457                if formatting_transaction.edit_ids.is_empty() {
 1458                    zlog::debug!(logger => "no changes made while formatting");
 1459                    buffer.forget_transaction(formatting_transaction_id);
 1460                    return;
 1461                }
 1462                if !push_to_history {
 1463                    zlog::trace!(logger => "forgetting format transaction");
 1464                    buffer.forget_transaction(formatting_transaction.id);
 1465                }
 1466                project_transaction
 1467                    .0
 1468                    .insert(cx.entity(), formatting_transaction);
 1469            })?;
 1470
 1471            result?;
 1472        }
 1473
 1474        Ok(project_transaction)
 1475    }
 1476
 1477    async fn format_buffer_locally(
 1478        lsp_store: WeakEntity<LspStore>,
 1479        buffer: &FormattableBuffer,
 1480        formatting_transaction_id: clock::Lamport,
 1481        trigger: FormatTrigger,
 1482        logger: zlog::Logger,
 1483        cx: &mut AsyncApp,
 1484    ) -> Result<()> {
 1485        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1486            buffer.handle.update(cx, |buffer, cx| {
 1487                let adapters_and_servers = lsp_store
 1488                    .as_local()
 1489                    .unwrap()
 1490                    .language_servers_for_buffer(buffer, cx)
 1491                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1492                    .collect::<Vec<_>>();
 1493                let settings =
 1494                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1495                        .into_owned();
 1496                (adapters_and_servers, settings)
 1497            })
 1498        })?;
 1499
 1500        /// Apply edits to the buffer that will become part of the formatting transaction.
 1501        /// Fails if the buffer has been edited since the start of that transaction.
 1502        fn extend_formatting_transaction(
 1503            buffer: &FormattableBuffer,
 1504            formatting_transaction_id: text::TransactionId,
 1505            cx: &mut AsyncApp,
 1506            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1507        ) -> anyhow::Result<()> {
 1508            buffer.handle.update(cx, |buffer, cx| {
 1509                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1510                if last_transaction_id != Some(formatting_transaction_id) {
 1511                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1512                }
 1513                buffer.start_transaction();
 1514                operation(buffer, cx);
 1515                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1516                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1517                }
 1518                Ok(())
 1519            })?
 1520        }
 1521
 1522        // handle whitespace formatting
 1523        if settings.remove_trailing_whitespace_on_save {
 1524            zlog::trace!(logger => "removing trailing whitespace");
 1525            let diff = buffer
 1526                .handle
 1527                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1528                .await;
 1529            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1530                buffer.apply_diff(diff, cx);
 1531            })?;
 1532        }
 1533
 1534        if settings.ensure_final_newline_on_save {
 1535            zlog::trace!(logger => "ensuring final newline");
 1536            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1537                buffer.ensure_final_newline(cx);
 1538            })?;
 1539        }
 1540
 1541        // Formatter for `code_actions_on_format` that runs before
 1542        // the rest of the formatters
 1543        let mut code_actions_on_format_formatters = None;
 1544        let should_run_code_actions_on_format = !matches!(
 1545            (trigger, &settings.format_on_save),
 1546            (FormatTrigger::Save, &FormatOnSave::Off)
 1547        );
 1548        if should_run_code_actions_on_format {
 1549            let have_code_actions_to_run_on_format = settings
 1550                .code_actions_on_format
 1551                .values()
 1552                .any(|enabled| *enabled);
 1553            if have_code_actions_to_run_on_format {
 1554                zlog::trace!(logger => "going to run code actions on format");
 1555                code_actions_on_format_formatters = Some(
 1556                    settings
 1557                        .code_actions_on_format
 1558                        .iter()
 1559                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1560                        .cloned()
 1561                        .map(Formatter::CodeAction)
 1562                        .collect::<Vec<_>>(),
 1563                );
 1564            }
 1565        }
 1566
 1567        let formatters = match (trigger, &settings.format_on_save) {
 1568            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1569            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1570                settings.formatter.as_ref()
 1571            }
 1572        };
 1573
 1574        let formatters = code_actions_on_format_formatters
 1575            .iter()
 1576            .flatten()
 1577            .chain(formatters);
 1578
 1579        for formatter in formatters {
 1580            let formatter = if formatter == &Formatter::Auto {
 1581                if settings.prettier.allowed {
 1582                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1583                    &Formatter::Prettier
 1584                } else {
 1585                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1586                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1587                }
 1588            } else {
 1589                formatter
 1590            };
 1591            match formatter {
 1592                Formatter::Auto => unreachable!("Auto resolved above"),
 1593                Formatter::Prettier => {
 1594                    let logger = zlog::scoped!(logger => "prettier");
 1595                    zlog::trace!(logger => "formatting");
 1596                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1597
 1598                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1599                        lsp_store.prettier_store().unwrap().downgrade()
 1600                    })?;
 1601                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1602                        .await
 1603                        .transpose()?;
 1604                    let Some(diff) = diff else {
 1605                        zlog::trace!(logger => "No changes");
 1606                        continue;
 1607                    };
 1608
 1609                    extend_formatting_transaction(
 1610                        buffer,
 1611                        formatting_transaction_id,
 1612                        cx,
 1613                        |buffer, cx| {
 1614                            buffer.apply_diff(diff, cx);
 1615                        },
 1616                    )?;
 1617                }
 1618                Formatter::External { command, arguments } => {
 1619                    let logger = zlog::scoped!(logger => "command");
 1620                    zlog::trace!(logger => "formatting");
 1621                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1622
 1623                    let diff = Self::format_via_external_command(
 1624                        buffer,
 1625                        command.as_ref(),
 1626                        arguments.as_deref(),
 1627                        cx,
 1628                    )
 1629                    .await
 1630                    .with_context(|| {
 1631                        format!("Failed to format buffer via external command: {}", command)
 1632                    })?;
 1633                    let Some(diff) = diff else {
 1634                        zlog::trace!(logger => "No changes");
 1635                        continue;
 1636                    };
 1637
 1638                    extend_formatting_transaction(
 1639                        buffer,
 1640                        formatting_transaction_id,
 1641                        cx,
 1642                        |buffer, cx| {
 1643                            buffer.apply_diff(diff, cx);
 1644                        },
 1645                    )?;
 1646                }
 1647                Formatter::LanguageServer(specifier) => {
 1648                    let logger = zlog::scoped!(logger => "language-server");
 1649                    zlog::trace!(logger => "formatting");
 1650                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1651
 1652                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1653                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1654                        continue;
 1655                    };
 1656
 1657                    let language_server = match specifier {
 1658                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1659                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1660                                if adapter.name.0.as_ref() == name {
 1661                                    Some(server.clone())
 1662                                } else {
 1663                                    None
 1664                                }
 1665                            })
 1666                        }
 1667                        settings::LanguageServerFormatterSpecifier::Current => {
 1668                            adapters_and_servers.first().map(|e| e.1.clone())
 1669                        }
 1670                    };
 1671
 1672                    let Some(language_server) = language_server else {
 1673                        log::debug!(
 1674                            "No language server found to format buffer '{:?}'. Skipping",
 1675                            buffer_path_abs.as_path().to_string_lossy()
 1676                        );
 1677                        continue;
 1678                    };
 1679
 1680                    zlog::trace!(
 1681                        logger =>
 1682                        "Formatting buffer '{:?}' using language server '{:?}'",
 1683                        buffer_path_abs.as_path().to_string_lossy(),
 1684                        language_server.name()
 1685                    );
 1686
 1687                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1688                        zlog::trace!(logger => "formatting ranges");
 1689                        Self::format_ranges_via_lsp(
 1690                            &lsp_store,
 1691                            &buffer.handle,
 1692                            ranges,
 1693                            buffer_path_abs,
 1694                            &language_server,
 1695                            &settings,
 1696                            cx,
 1697                        )
 1698                        .await
 1699                        .context("Failed to format ranges via language server")?
 1700                    } else {
 1701                        zlog::trace!(logger => "formatting full");
 1702                        Self::format_via_lsp(
 1703                            &lsp_store,
 1704                            &buffer.handle,
 1705                            buffer_path_abs,
 1706                            &language_server,
 1707                            &settings,
 1708                            cx,
 1709                        )
 1710                        .await
 1711                        .context("failed to format via language server")?
 1712                    };
 1713
 1714                    if edits.is_empty() {
 1715                        zlog::trace!(logger => "No changes");
 1716                        continue;
 1717                    }
 1718                    extend_formatting_transaction(
 1719                        buffer,
 1720                        formatting_transaction_id,
 1721                        cx,
 1722                        |buffer, cx| {
 1723                            buffer.edit(edits, None, cx);
 1724                        },
 1725                    )?;
 1726                }
 1727                Formatter::CodeAction(code_action_name) => {
 1728                    let logger = zlog::scoped!(logger => "code-actions");
 1729                    zlog::trace!(logger => "formatting");
 1730                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1731
 1732                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1733                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1734                        continue;
 1735                    };
 1736
 1737                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1738                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1739
 1740                    let mut actions_and_servers = Vec::new();
 1741
 1742                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1743                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1744                            &lsp_store,
 1745                            language_server.server_id(),
 1746                            vec![code_action_kind.clone()],
 1747                            &buffer.handle,
 1748                            cx,
 1749                        )
 1750                        .await
 1751                        .with_context(|| {
 1752                            format!(
 1753                                "Failed to resolve code action {:?} with language server {}",
 1754                                code_action_kind,
 1755                                language_server.name()
 1756                            )
 1757                        });
 1758                        let Ok(actions) = actions_result else {
 1759                            // note: it may be better to set result to the error and break formatters here
 1760                            // but for now we try to execute the actions that we can resolve and skip the rest
 1761                            zlog::error!(
 1762                                logger =>
 1763                                "Failed to resolve code action {:?} with language server {}",
 1764                                code_action_kind,
 1765                                language_server.name()
 1766                            );
 1767                            continue;
 1768                        };
 1769                        for action in actions {
 1770                            actions_and_servers.push((action, index));
 1771                        }
 1772                    }
 1773
 1774                    if actions_and_servers.is_empty() {
 1775                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1776                        continue;
 1777                    }
 1778
 1779                    'actions: for (mut action, server_index) in actions_and_servers {
 1780                        let server = &adapters_and_servers[server_index].1;
 1781
 1782                        let describe_code_action = |action: &CodeAction| {
 1783                            format!(
 1784                                "code action '{}' with title \"{}\" on server {}",
 1785                                action
 1786                                    .lsp_action
 1787                                    .action_kind()
 1788                                    .unwrap_or("unknown".into())
 1789                                    .as_str(),
 1790                                action.lsp_action.title(),
 1791                                server.name(),
 1792                            )
 1793                        };
 1794
 1795                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1796
 1797                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1798                            zlog::error!(
 1799                                logger =>
 1800                                "Failed to resolve {}. Error: {}",
 1801                                describe_code_action(&action),
 1802                                err
 1803                            );
 1804                            continue;
 1805                        }
 1806
 1807                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1808                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1809                            // but filters out and logs warnings for code actions that require unreasonably
 1810                            // difficult handling on our part, such as:
 1811                            // - applying edits that call commands
 1812                            //   which can result in arbitrary workspace edits being sent from the server that
 1813                            //   have no way of being tied back to the command that initiated them (i.e. we
 1814                            //   can't know which edits are part of the format request, or if the server is done sending
 1815                            //   actions in response to the command)
 1816                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1817                            //   as we then would need to handle such changes correctly in the local history as well
 1818                            //   as the remote history through the ProjectTransaction
 1819                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1820                            // Supporting these actions is not impossible, but not supported as of yet.
 1821                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1822                                zlog::trace!(
 1823                                    logger =>
 1824                                    "No changes for code action. Skipping {}",
 1825                                    describe_code_action(&action),
 1826                                );
 1827                                continue;
 1828                            }
 1829
 1830                            let mut operations = Vec::new();
 1831                            if let Some(document_changes) = edit.document_changes {
 1832                                match document_changes {
 1833                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1834                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1835                                    ),
 1836                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1837                                }
 1838                            } else if let Some(changes) = edit.changes {
 1839                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1840                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1841                                        text_document:
 1842                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1843                                                uri,
 1844                                                version: None,
 1845                                            },
 1846                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1847                                    })
 1848                                }));
 1849                            }
 1850
 1851                            let mut edits = Vec::with_capacity(operations.len());
 1852
 1853                            if operations.is_empty() {
 1854                                zlog::trace!(
 1855                                    logger =>
 1856                                    "No changes for code action. Skipping {}",
 1857                                    describe_code_action(&action),
 1858                                );
 1859                                continue;
 1860                            }
 1861                            for operation in operations {
 1862                                let op = match operation {
 1863                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1864                                    lsp::DocumentChangeOperation::Op(_) => {
 1865                                        zlog::warn!(
 1866                                            logger =>
 1867                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1868                                            describe_code_action(&action),
 1869                                        );
 1870                                        continue 'actions;
 1871                                    }
 1872                                };
 1873                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1874                                    zlog::warn!(
 1875                                        logger =>
 1876                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1877                                        &op.text_document.uri,
 1878                                        describe_code_action(&action),
 1879                                    );
 1880                                    continue 'actions;
 1881                                };
 1882                                if &file_path != buffer_path_abs {
 1883                                    zlog::warn!(
 1884                                        logger =>
 1885                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1886                                        file_path,
 1887                                        buffer_path_abs,
 1888                                        describe_code_action(&action),
 1889                                    );
 1890                                    continue 'actions;
 1891                                }
 1892
 1893                                let mut lsp_edits = Vec::new();
 1894                                for edit in op.edits {
 1895                                    match edit {
 1896                                        Edit::Plain(edit) => {
 1897                                            if !lsp_edits.contains(&edit) {
 1898                                                lsp_edits.push(edit);
 1899                                            }
 1900                                        }
 1901                                        Edit::Annotated(edit) => {
 1902                                            if !lsp_edits.contains(&edit.text_edit) {
 1903                                                lsp_edits.push(edit.text_edit);
 1904                                            }
 1905                                        }
 1906                                        Edit::Snippet(_) => {
 1907                                            zlog::warn!(
 1908                                                logger =>
 1909                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1910                                                describe_code_action(&action),
 1911                                            );
 1912                                            continue 'actions;
 1913                                        }
 1914                                    }
 1915                                }
 1916                                let edits_result = lsp_store
 1917                                    .update(cx, |lsp_store, cx| {
 1918                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1919                                            &buffer.handle,
 1920                                            lsp_edits,
 1921                                            server.server_id(),
 1922                                            op.text_document.version,
 1923                                            cx,
 1924                                        )
 1925                                    })?
 1926                                    .await;
 1927                                let Ok(resolved_edits) = edits_result else {
 1928                                    zlog::warn!(
 1929                                        logger =>
 1930                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1931                                        buffer_path_abs.as_path(),
 1932                                        describe_code_action(&action),
 1933                                    );
 1934                                    continue 'actions;
 1935                                };
 1936                                edits.extend(resolved_edits);
 1937                            }
 1938
 1939                            if edits.is_empty() {
 1940                                zlog::warn!(logger => "No edits resolved from LSP");
 1941                                continue;
 1942                            }
 1943
 1944                            extend_formatting_transaction(
 1945                                buffer,
 1946                                formatting_transaction_id,
 1947                                cx,
 1948                                |buffer, cx| {
 1949                                    zlog::info!(
 1950                                        "Applying edits {edits:?}. Content: {:?}",
 1951                                        buffer.text()
 1952                                    );
 1953                                    buffer.edit(edits, None, cx);
 1954                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1955                                },
 1956                            )?;
 1957                        }
 1958
 1959                        if let Some(command) = action.lsp_action.command() {
 1960                            zlog::warn!(
 1961                                logger =>
 1962                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1963                                &command.command,
 1964                            );
 1965
 1966                            // bail early if command is invalid
 1967                            let server_capabilities = server.capabilities();
 1968                            let available_commands = server_capabilities
 1969                                .execute_command_provider
 1970                                .as_ref()
 1971                                .map(|options| options.commands.as_slice())
 1972                                .unwrap_or_default();
 1973                            if !available_commands.contains(&command.command) {
 1974                                zlog::warn!(
 1975                                    logger =>
 1976                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1977                                    command.command,
 1978                                    server.name(),
 1979                                );
 1980                                continue;
 1981                            }
 1982
 1983                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1984                            extend_formatting_transaction(
 1985                                buffer,
 1986                                formatting_transaction_id,
 1987                                cx,
 1988                                |_, _| {},
 1989                            )?;
 1990                            zlog::info!(logger => "Executing command {}", &command.command);
 1991
 1992                            lsp_store.update(cx, |this, _| {
 1993                                this.as_local_mut()
 1994                                    .unwrap()
 1995                                    .last_workspace_edits_by_language_server
 1996                                    .remove(&server.server_id());
 1997                            })?;
 1998
 1999                            let execute_command_result = server
 2000                                .request::<lsp::request::ExecuteCommand>(
 2001                                    lsp::ExecuteCommandParams {
 2002                                        command: command.command.clone(),
 2003                                        arguments: command.arguments.clone().unwrap_or_default(),
 2004                                        ..Default::default()
 2005                                    },
 2006                                )
 2007                                .await
 2008                                .into_response();
 2009
 2010                            if execute_command_result.is_err() {
 2011                                zlog::error!(
 2012                                    logger =>
 2013                                    "Failed to execute command '{}' as part of {}",
 2014                                    &command.command,
 2015                                    describe_code_action(&action),
 2016                                );
 2017                                continue 'actions;
 2018                            }
 2019
 2020                            let mut project_transaction_command =
 2021                                lsp_store.update(cx, |this, _| {
 2022                                    this.as_local_mut()
 2023                                        .unwrap()
 2024                                        .last_workspace_edits_by_language_server
 2025                                        .remove(&server.server_id())
 2026                                        .unwrap_or_default()
 2027                                })?;
 2028
 2029                            if let Some(transaction) =
 2030                                project_transaction_command.0.remove(&buffer.handle)
 2031                            {
 2032                                zlog::trace!(
 2033                                    logger =>
 2034                                    "Successfully captured {} edits that resulted from command {}",
 2035                                    transaction.edit_ids.len(),
 2036                                    &command.command,
 2037                                );
 2038                                let transaction_id_project_transaction = transaction.id;
 2039                                buffer.handle.update(cx, |buffer, _| {
 2040                                    // it may have been removed from history if push_to_history was
 2041                                    // false in deserialize_workspace_edit. If so push it so we
 2042                                    // can merge it with the format transaction
 2043                                    // and pop the combined transaction off the history stack
 2044                                    // later if push_to_history is false
 2045                                    if buffer.get_transaction(transaction.id).is_none() {
 2046                                        buffer.push_transaction(transaction, Instant::now());
 2047                                    }
 2048                                    buffer.merge_transactions(
 2049                                        transaction_id_project_transaction,
 2050                                        formatting_transaction_id,
 2051                                    );
 2052                                })?;
 2053                            }
 2054
 2055                            if !project_transaction_command.0.is_empty() {
 2056                                let mut extra_buffers = String::new();
 2057                                for buffer in project_transaction_command.0.keys() {
 2058                                    buffer
 2059                                        .read_with(cx, |b, cx| {
 2060                                            if let Some(path) = b.project_path(cx) {
 2061                                                if !extra_buffers.is_empty() {
 2062                                                    extra_buffers.push_str(", ");
 2063                                                }
 2064                                                extra_buffers.push_str(path.path.as_unix_str());
 2065                                            }
 2066                                        })
 2067                                        .ok();
 2068                                }
 2069                                zlog::warn!(
 2070                                    logger =>
 2071                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2072                                    &command.command,
 2073                                    extra_buffers,
 2074                                );
 2075                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2076                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2077                                // add it so it's included, and merge it into the format transaction when its created later
 2078                            }
 2079                        }
 2080                    }
 2081                }
 2082            }
 2083        }
 2084
 2085        Ok(())
 2086    }
 2087
 2088    pub async fn format_ranges_via_lsp(
 2089        this: &WeakEntity<LspStore>,
 2090        buffer_handle: &Entity<Buffer>,
 2091        ranges: &[Range<Anchor>],
 2092        abs_path: &Path,
 2093        language_server: &Arc<LanguageServer>,
 2094        settings: &LanguageSettings,
 2095        cx: &mut AsyncApp,
 2096    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2097        let capabilities = &language_server.capabilities();
 2098        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2099        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2100            anyhow::bail!(
 2101                "{} language server does not support range formatting",
 2102                language_server.name()
 2103            );
 2104        }
 2105
 2106        let uri = file_path_to_lsp_url(abs_path)?;
 2107        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2108
 2109        let lsp_edits = {
 2110            let mut lsp_ranges = Vec::new();
 2111            this.update(cx, |_this, cx| {
 2112                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2113                // not have been sent to the language server. This seems like a fairly systemic
 2114                // issue, though, the resolution probably is not specific to formatting.
 2115                //
 2116                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2117                // LSP.
 2118                let snapshot = buffer_handle.read(cx).snapshot();
 2119                for range in ranges {
 2120                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2121                }
 2122                anyhow::Ok(())
 2123            })??;
 2124
 2125            let mut edits = None;
 2126            for range in lsp_ranges {
 2127                if let Some(mut edit) = language_server
 2128                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2129                        text_document: text_document.clone(),
 2130                        range,
 2131                        options: lsp_command::lsp_formatting_options(settings),
 2132                        work_done_progress_params: Default::default(),
 2133                    })
 2134                    .await
 2135                    .into_response()?
 2136                {
 2137                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2138                }
 2139            }
 2140            edits
 2141        };
 2142
 2143        if let Some(lsp_edits) = lsp_edits {
 2144            this.update(cx, |this, cx| {
 2145                this.as_local_mut().unwrap().edits_from_lsp(
 2146                    buffer_handle,
 2147                    lsp_edits,
 2148                    language_server.server_id(),
 2149                    None,
 2150                    cx,
 2151                )
 2152            })?
 2153            .await
 2154        } else {
 2155            Ok(Vec::with_capacity(0))
 2156        }
 2157    }
 2158
 2159    async fn format_via_lsp(
 2160        this: &WeakEntity<LspStore>,
 2161        buffer: &Entity<Buffer>,
 2162        abs_path: &Path,
 2163        language_server: &Arc<LanguageServer>,
 2164        settings: &LanguageSettings,
 2165        cx: &mut AsyncApp,
 2166    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2167        let logger = zlog::scoped!("lsp_format");
 2168        zlog::debug!(logger => "Formatting via LSP");
 2169
 2170        let uri = file_path_to_lsp_url(abs_path)?;
 2171        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2172        let capabilities = &language_server.capabilities();
 2173
 2174        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2175        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2176
 2177        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2178            let _timer = zlog::time!(logger => "format-full");
 2179            language_server
 2180                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2181                    text_document,
 2182                    options: lsp_command::lsp_formatting_options(settings),
 2183                    work_done_progress_params: Default::default(),
 2184                })
 2185                .await
 2186                .into_response()?
 2187        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2188            let _timer = zlog::time!(logger => "format-range");
 2189            let buffer_start = lsp::Position::new(0, 0);
 2190            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2191            language_server
 2192                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2193                    text_document: text_document.clone(),
 2194                    range: lsp::Range::new(buffer_start, buffer_end),
 2195                    options: lsp_command::lsp_formatting_options(settings),
 2196                    work_done_progress_params: Default::default(),
 2197                })
 2198                .await
 2199                .into_response()?
 2200        } else {
 2201            None
 2202        };
 2203
 2204        if let Some(lsp_edits) = lsp_edits {
 2205            this.update(cx, |this, cx| {
 2206                this.as_local_mut().unwrap().edits_from_lsp(
 2207                    buffer,
 2208                    lsp_edits,
 2209                    language_server.server_id(),
 2210                    None,
 2211                    cx,
 2212                )
 2213            })?
 2214            .await
 2215        } else {
 2216            Ok(Vec::with_capacity(0))
 2217        }
 2218    }
 2219
 2220    async fn format_via_external_command(
 2221        buffer: &FormattableBuffer,
 2222        command: &str,
 2223        arguments: Option<&[String]>,
 2224        cx: &mut AsyncApp,
 2225    ) -> Result<Option<Diff>> {
 2226        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2227            let file = File::from_dyn(buffer.file())?;
 2228            let worktree = file.worktree.read(cx);
 2229            let mut worktree_path = worktree.abs_path().to_path_buf();
 2230            if worktree.root_entry()?.is_file() {
 2231                worktree_path.pop();
 2232            }
 2233            Some(worktree_path)
 2234        })?;
 2235
 2236        let mut child = util::command::new_smol_command(command);
 2237
 2238        if let Some(buffer_env) = buffer.env.as_ref() {
 2239            child.envs(buffer_env);
 2240        }
 2241
 2242        if let Some(working_dir_path) = working_dir_path {
 2243            child.current_dir(working_dir_path);
 2244        }
 2245
 2246        if let Some(arguments) = arguments {
 2247            child.args(arguments.iter().map(|arg| {
 2248                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2249                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2250                } else {
 2251                    arg.replace("{buffer_path}", "Untitled")
 2252                }
 2253            }));
 2254        }
 2255
 2256        let mut child = child
 2257            .stdin(smol::process::Stdio::piped())
 2258            .stdout(smol::process::Stdio::piped())
 2259            .stderr(smol::process::Stdio::piped())
 2260            .spawn()?;
 2261
 2262        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2263        let text = buffer
 2264            .handle
 2265            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2266        for chunk in text.chunks() {
 2267            stdin.write_all(chunk.as_bytes()).await?;
 2268        }
 2269        stdin.flush().await?;
 2270
 2271        let output = child.output().await?;
 2272        anyhow::ensure!(
 2273            output.status.success(),
 2274            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2275            output.status.code(),
 2276            String::from_utf8_lossy(&output.stdout),
 2277            String::from_utf8_lossy(&output.stderr),
 2278        );
 2279
 2280        let stdout = String::from_utf8(output.stdout)?;
 2281        Ok(Some(
 2282            buffer
 2283                .handle
 2284                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2285                .await,
 2286        ))
 2287    }
 2288
 2289    async fn try_resolve_code_action(
 2290        lang_server: &LanguageServer,
 2291        action: &mut CodeAction,
 2292    ) -> anyhow::Result<()> {
 2293        match &mut action.lsp_action {
 2294            LspAction::Action(lsp_action) => {
 2295                if !action.resolved
 2296                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2297                    && lsp_action.data.is_some()
 2298                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2299                {
 2300                    **lsp_action = lang_server
 2301                        .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2302                        .await
 2303                        .into_response()?;
 2304                }
 2305            }
 2306            LspAction::CodeLens(lens) => {
 2307                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2308                    *lens = lang_server
 2309                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2310                        .await
 2311                        .into_response()?;
 2312                }
 2313            }
 2314            LspAction::Command(_) => {}
 2315        }
 2316
 2317        action.resolved = true;
 2318        anyhow::Ok(())
 2319    }
 2320
 2321    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2322        let buffer = buffer_handle.read(cx);
 2323
 2324        let file = buffer.file().cloned();
 2325
 2326        let Some(file) = File::from_dyn(file.as_ref()) else {
 2327            return;
 2328        };
 2329        if !file.is_local() {
 2330            return;
 2331        }
 2332        let path = ProjectPath::from_file(file, cx);
 2333        let worktree_id = file.worktree_id(cx);
 2334        let language = buffer.language().cloned();
 2335
 2336        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2337            for (server_id, diagnostics) in
 2338                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2339            {
 2340                self.update_buffer_diagnostics(
 2341                    buffer_handle,
 2342                    server_id,
 2343                    None,
 2344                    None,
 2345                    None,
 2346                    Vec::new(),
 2347                    diagnostics,
 2348                    cx,
 2349                )
 2350                .log_err();
 2351            }
 2352        }
 2353        let Some(language) = language else {
 2354            return;
 2355        };
 2356        let Some(snapshot) = self
 2357            .worktree_store
 2358            .read(cx)
 2359            .worktree_for_id(worktree_id, cx)
 2360            .map(|worktree| worktree.read(cx).snapshot())
 2361        else {
 2362            return;
 2363        };
 2364        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2365
 2366        for server_id in
 2367            self.lsp_tree
 2368                .get(path, language.name(), language.manifest(), &delegate, cx)
 2369        {
 2370            let server = self
 2371                .language_servers
 2372                .get(&server_id)
 2373                .and_then(|server_state| {
 2374                    if let LanguageServerState::Running { server, .. } = server_state {
 2375                        Some(server.clone())
 2376                    } else {
 2377                        None
 2378                    }
 2379                });
 2380            let server = match server {
 2381                Some(server) => server,
 2382                None => continue,
 2383            };
 2384
 2385            buffer_handle.update(cx, |buffer, cx| {
 2386                buffer.set_completion_triggers(
 2387                    server.server_id(),
 2388                    server
 2389                        .capabilities()
 2390                        .completion_provider
 2391                        .as_ref()
 2392                        .and_then(|provider| {
 2393                            provider
 2394                                .trigger_characters
 2395                                .as_ref()
 2396                                .map(|characters| characters.iter().cloned().collect())
 2397                        })
 2398                        .unwrap_or_default(),
 2399                    cx,
 2400                );
 2401            });
 2402        }
 2403    }
 2404
 2405    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2406        buffer.update(cx, |buffer, cx| {
 2407            let Some(language) = buffer.language() else {
 2408                return;
 2409            };
 2410            let path = ProjectPath {
 2411                worktree_id: old_file.worktree_id(cx),
 2412                path: old_file.path.clone(),
 2413            };
 2414            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2415                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2416                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2417            }
 2418        });
 2419    }
 2420
 2421    fn update_buffer_diagnostics(
 2422        &mut self,
 2423        buffer: &Entity<Buffer>,
 2424        server_id: LanguageServerId,
 2425        registration_id: Option<Option<SharedString>>,
 2426        result_id: Option<SharedString>,
 2427        version: Option<i32>,
 2428        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2429        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2430        cx: &mut Context<LspStore>,
 2431    ) -> Result<()> {
 2432        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2433            Ordering::Equal
 2434                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2435                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2436                .then_with(|| a.severity.cmp(&b.severity))
 2437                .then_with(|| a.message.cmp(&b.message))
 2438        }
 2439
 2440        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2441        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2442        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2443
 2444        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2445            Ordering::Equal
 2446                .then_with(|| a.range.start.cmp(&b.range.start))
 2447                .then_with(|| b.range.end.cmp(&a.range.end))
 2448                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2449        });
 2450
 2451        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2452
 2453        let edits_since_save = std::cell::LazyCell::new(|| {
 2454            let saved_version = buffer.read(cx).saved_version();
 2455            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2456        });
 2457
 2458        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2459
 2460        for (new_diagnostic, entry) in diagnostics {
 2461            let start;
 2462            let end;
 2463            if new_diagnostic && entry.diagnostic.is_disk_based {
 2464                // Some diagnostics are based on files on disk instead of buffers'
 2465                // current contents. Adjust these diagnostics' ranges to reflect
 2466                // any unsaved edits.
 2467                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2468                // and were properly adjusted on reuse.
 2469                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2470                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2471            } else {
 2472                start = entry.range.start;
 2473                end = entry.range.end;
 2474            }
 2475
 2476            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2477                ..snapshot.clip_point_utf16(end, Bias::Right);
 2478
 2479            // Expand empty ranges by one codepoint
 2480            if range.start == range.end {
 2481                // This will be go to the next boundary when being clipped
 2482                range.end.column += 1;
 2483                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2484                if range.start == range.end && range.end.column > 0 {
 2485                    range.start.column -= 1;
 2486                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2487                }
 2488            }
 2489
 2490            sanitized_diagnostics.push(DiagnosticEntry {
 2491                range,
 2492                diagnostic: entry.diagnostic,
 2493            });
 2494        }
 2495        drop(edits_since_save);
 2496
 2497        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2498        buffer.update(cx, |buffer, cx| {
 2499            if let Some(registration_id) = registration_id {
 2500                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2501                    self.buffer_pull_diagnostics_result_ids
 2502                        .entry(server_id)
 2503                        .or_default()
 2504                        .entry(registration_id)
 2505                        .or_default()
 2506                        .insert(abs_path, result_id);
 2507                }
 2508            }
 2509
 2510            buffer.update_diagnostics(server_id, set, cx)
 2511        });
 2512
 2513        Ok(())
 2514    }
 2515
 2516    fn register_language_server_for_invisible_worktree(
 2517        &mut self,
 2518        worktree: &Entity<Worktree>,
 2519        language_server_id: LanguageServerId,
 2520        cx: &mut App,
 2521    ) {
 2522        let worktree = worktree.read(cx);
 2523        let worktree_id = worktree.id();
 2524        debug_assert!(!worktree.is_visible());
 2525        let Some(mut origin_seed) = self
 2526            .language_server_ids
 2527            .iter()
 2528            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2529        else {
 2530            return;
 2531        };
 2532        origin_seed.worktree_id = worktree_id;
 2533        self.language_server_ids
 2534            .entry(origin_seed)
 2535            .or_insert_with(|| UnifiedLanguageServer {
 2536                id: language_server_id,
 2537                project_roots: Default::default(),
 2538            });
 2539    }
 2540
 2541    fn register_buffer_with_language_servers(
 2542        &mut self,
 2543        buffer_handle: &Entity<Buffer>,
 2544        only_register_servers: HashSet<LanguageServerSelector>,
 2545        cx: &mut Context<LspStore>,
 2546    ) {
 2547        let buffer = buffer_handle.read(cx);
 2548        let buffer_id = buffer.remote_id();
 2549
 2550        let Some(file) = File::from_dyn(buffer.file()) else {
 2551            return;
 2552        };
 2553        if !file.is_local() {
 2554            return;
 2555        }
 2556
 2557        let abs_path = file.abs_path(cx);
 2558        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2559            return;
 2560        };
 2561        let initial_snapshot = buffer.text_snapshot();
 2562        let worktree_id = file.worktree_id(cx);
 2563
 2564        let Some(language) = buffer.language().cloned() else {
 2565            return;
 2566        };
 2567        let path: Arc<RelPath> = file
 2568            .path()
 2569            .parent()
 2570            .map(Arc::from)
 2571            .unwrap_or_else(|| file.path().clone());
 2572        let Some(worktree) = self
 2573            .worktree_store
 2574            .read(cx)
 2575            .worktree_for_id(worktree_id, cx)
 2576        else {
 2577            return;
 2578        };
 2579        let language_name = language.name();
 2580        let (reused, delegate, servers) = self
 2581            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2582            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2583            .unwrap_or_else(|| {
 2584                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2585                let delegate: Arc<dyn ManifestDelegate> =
 2586                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2587
 2588                let servers = self
 2589                    .lsp_tree
 2590                    .walk(
 2591                        ProjectPath { worktree_id, path },
 2592                        language.name(),
 2593                        language.manifest(),
 2594                        &delegate,
 2595                        cx,
 2596                    )
 2597                    .collect::<Vec<_>>();
 2598                (false, lsp_delegate, servers)
 2599            });
 2600        let servers_and_adapters = servers
 2601            .into_iter()
 2602            .filter_map(|server_node| {
 2603                if reused && server_node.server_id().is_none() {
 2604                    return None;
 2605                }
 2606                if !only_register_servers.is_empty() {
 2607                    if let Some(server_id) = server_node.server_id()
 2608                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2609                    {
 2610                        return None;
 2611                    }
 2612                    if let Some(name) = server_node.name()
 2613                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2614                    {
 2615                        return None;
 2616                    }
 2617                }
 2618
 2619                let server_id = server_node.server_id_or_init(|disposition| {
 2620                    let path = &disposition.path;
 2621
 2622                    {
 2623                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2624
 2625                        let server_id = self.get_or_insert_language_server(
 2626                            &worktree,
 2627                            delegate.clone(),
 2628                            disposition,
 2629                            &language_name,
 2630                            cx,
 2631                        );
 2632
 2633                        if let Some(state) = self.language_servers.get(&server_id)
 2634                            && let Ok(uri) = uri
 2635                        {
 2636                            state.add_workspace_folder(uri);
 2637                        };
 2638                        server_id
 2639                    }
 2640                })?;
 2641                let server_state = self.language_servers.get(&server_id)?;
 2642                if let LanguageServerState::Running {
 2643                    server, adapter, ..
 2644                } = server_state
 2645                {
 2646                    Some((server.clone(), adapter.clone()))
 2647                } else {
 2648                    None
 2649                }
 2650            })
 2651            .collect::<Vec<_>>();
 2652        for (server, adapter) in servers_and_adapters {
 2653            buffer_handle.update(cx, |buffer, cx| {
 2654                buffer.set_completion_triggers(
 2655                    server.server_id(),
 2656                    server
 2657                        .capabilities()
 2658                        .completion_provider
 2659                        .as_ref()
 2660                        .and_then(|provider| {
 2661                            provider
 2662                                .trigger_characters
 2663                                .as_ref()
 2664                                .map(|characters| characters.iter().cloned().collect())
 2665                        })
 2666                        .unwrap_or_default(),
 2667                    cx,
 2668                );
 2669            });
 2670
 2671            let snapshot = LspBufferSnapshot {
 2672                version: 0,
 2673                snapshot: initial_snapshot.clone(),
 2674            };
 2675
 2676            let mut registered = false;
 2677            self.buffer_snapshots
 2678                .entry(buffer_id)
 2679                .or_default()
 2680                .entry(server.server_id())
 2681                .or_insert_with(|| {
 2682                    registered = true;
 2683                    server.register_buffer(
 2684                        uri.clone(),
 2685                        adapter.language_id(&language.name()),
 2686                        0,
 2687                        initial_snapshot.text(),
 2688                    );
 2689
 2690                    vec![snapshot]
 2691                });
 2692
 2693            self.buffers_opened_in_servers
 2694                .entry(buffer_id)
 2695                .or_default()
 2696                .insert(server.server_id());
 2697            if registered {
 2698                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2699                    language_server_id: server.server_id(),
 2700                    name: None,
 2701                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2702                        proto::RegisteredForBuffer {
 2703                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2704                            buffer_id: buffer_id.to_proto(),
 2705                        },
 2706                    ),
 2707                });
 2708            }
 2709        }
 2710    }
 2711
 2712    fn reuse_existing_language_server<'lang_name>(
 2713        &self,
 2714        server_tree: &LanguageServerTree,
 2715        worktree: &Entity<Worktree>,
 2716        language_name: &'lang_name LanguageName,
 2717        cx: &mut App,
 2718    ) -> Option<(
 2719        Arc<LocalLspAdapterDelegate>,
 2720        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2721    )> {
 2722        if worktree.read(cx).is_visible() {
 2723            return None;
 2724        }
 2725
 2726        let worktree_store = self.worktree_store.read(cx);
 2727        let servers = server_tree
 2728            .instances
 2729            .iter()
 2730            .filter(|(worktree_id, _)| {
 2731                worktree_store
 2732                    .worktree_for_id(**worktree_id, cx)
 2733                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2734            })
 2735            .flat_map(|(worktree_id, servers)| {
 2736                servers
 2737                    .roots
 2738                    .iter()
 2739                    .flat_map(|(_, language_servers)| language_servers)
 2740                    .map(move |(_, (server_node, server_languages))| {
 2741                        (worktree_id, server_node, server_languages)
 2742                    })
 2743                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2744                    .map(|(worktree_id, server_node, _)| {
 2745                        (
 2746                            *worktree_id,
 2747                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2748                        )
 2749                    })
 2750            })
 2751            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2752                acc.entry(worktree_id)
 2753                    .or_insert_with(Vec::new)
 2754                    .push(server_node);
 2755                acc
 2756            })
 2757            .into_values()
 2758            .max_by_key(|servers| servers.len())?;
 2759
 2760        let worktree_id = worktree.read(cx).id();
 2761        let apply = move |tree: &mut LanguageServerTree| {
 2762            for server_node in &servers {
 2763                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2764            }
 2765            servers
 2766        };
 2767
 2768        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2769        Some((delegate, apply))
 2770    }
 2771
 2772    pub(crate) fn unregister_old_buffer_from_language_servers(
 2773        &mut self,
 2774        buffer: &Entity<Buffer>,
 2775        old_file: &File,
 2776        cx: &mut App,
 2777    ) {
 2778        let old_path = match old_file.as_local() {
 2779            Some(local) => local.abs_path(cx),
 2780            None => return,
 2781        };
 2782
 2783        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2784            debug_panic!("{old_path:?} is not parseable as an URI");
 2785            return;
 2786        };
 2787        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2788    }
 2789
 2790    pub(crate) fn unregister_buffer_from_language_servers(
 2791        &mut self,
 2792        buffer: &Entity<Buffer>,
 2793        file_url: &lsp::Uri,
 2794        cx: &mut App,
 2795    ) {
 2796        buffer.update(cx, |buffer, cx| {
 2797            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2798
 2799            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2800                if snapshots
 2801                    .as_mut()
 2802                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2803                {
 2804                    language_server.unregister_buffer(file_url.clone());
 2805                }
 2806            }
 2807        });
 2808    }
 2809
 2810    fn buffer_snapshot_for_lsp_version(
 2811        &mut self,
 2812        buffer: &Entity<Buffer>,
 2813        server_id: LanguageServerId,
 2814        version: Option<i32>,
 2815        cx: &App,
 2816    ) -> Result<TextBufferSnapshot> {
 2817        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2818
 2819        if let Some(version) = version {
 2820            let buffer_id = buffer.read(cx).remote_id();
 2821            let snapshots = if let Some(snapshots) = self
 2822                .buffer_snapshots
 2823                .get_mut(&buffer_id)
 2824                .and_then(|m| m.get_mut(&server_id))
 2825            {
 2826                snapshots
 2827            } else if version == 0 {
 2828                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2829                // We detect this case and treat it as if the version was `None`.
 2830                return Ok(buffer.read(cx).text_snapshot());
 2831            } else {
 2832                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2833            };
 2834
 2835            let found_snapshot = snapshots
 2836                    .binary_search_by_key(&version, |e| e.version)
 2837                    .map(|ix| snapshots[ix].snapshot.clone())
 2838                    .map_err(|_| {
 2839                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2840                    })?;
 2841
 2842            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2843            Ok(found_snapshot)
 2844        } else {
 2845            Ok((buffer.read(cx)).text_snapshot())
 2846        }
 2847    }
 2848
 2849    async fn get_server_code_actions_from_action_kinds(
 2850        lsp_store: &WeakEntity<LspStore>,
 2851        language_server_id: LanguageServerId,
 2852        code_action_kinds: Vec<lsp::CodeActionKind>,
 2853        buffer: &Entity<Buffer>,
 2854        cx: &mut AsyncApp,
 2855    ) -> Result<Vec<CodeAction>> {
 2856        let actions = lsp_store
 2857            .update(cx, move |this, cx| {
 2858                let request = GetCodeActions {
 2859                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 2860                    kinds: Some(code_action_kinds),
 2861                };
 2862                let server = LanguageServerToQuery::Other(language_server_id);
 2863                this.request_lsp(buffer.clone(), server, request, cx)
 2864            })?
 2865            .await?;
 2866        Ok(actions)
 2867    }
 2868
 2869    pub async fn execute_code_actions_on_server(
 2870        lsp_store: &WeakEntity<LspStore>,
 2871        language_server: &Arc<LanguageServer>,
 2872
 2873        actions: Vec<CodeAction>,
 2874        push_to_history: bool,
 2875        project_transaction: &mut ProjectTransaction,
 2876        cx: &mut AsyncApp,
 2877    ) -> anyhow::Result<()> {
 2878        for mut action in actions {
 2879            Self::try_resolve_code_action(language_server, &mut action)
 2880                .await
 2881                .context("resolving a formatting code action")?;
 2882
 2883            if let Some(edit) = action.lsp_action.edit() {
 2884                if edit.changes.is_none() && edit.document_changes.is_none() {
 2885                    continue;
 2886                }
 2887
 2888                let new = Self::deserialize_workspace_edit(
 2889                    lsp_store.upgrade().context("project dropped")?,
 2890                    edit.clone(),
 2891                    push_to_history,
 2892                    language_server.clone(),
 2893                    cx,
 2894                )
 2895                .await?;
 2896                project_transaction.0.extend(new.0);
 2897            }
 2898
 2899            if let Some(command) = action.lsp_action.command() {
 2900                let server_capabilities = language_server.capabilities();
 2901                let available_commands = server_capabilities
 2902                    .execute_command_provider
 2903                    .as_ref()
 2904                    .map(|options| options.commands.as_slice())
 2905                    .unwrap_or_default();
 2906                if available_commands.contains(&command.command) {
 2907                    lsp_store.update(cx, |lsp_store, _| {
 2908                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2909                            mode.last_workspace_edits_by_language_server
 2910                                .remove(&language_server.server_id());
 2911                        }
 2912                    })?;
 2913
 2914                    language_server
 2915                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2916                            command: command.command.clone(),
 2917                            arguments: command.arguments.clone().unwrap_or_default(),
 2918                            ..Default::default()
 2919                        })
 2920                        .await
 2921                        .into_response()
 2922                        .context("execute command")?;
 2923
 2924                    lsp_store.update(cx, |this, _| {
 2925                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2926                            project_transaction.0.extend(
 2927                                mode.last_workspace_edits_by_language_server
 2928                                    .remove(&language_server.server_id())
 2929                                    .unwrap_or_default()
 2930                                    .0,
 2931                            )
 2932                        }
 2933                    })?;
 2934                } else {
 2935                    log::warn!(
 2936                        "Cannot execute a command {} not listed in the language server capabilities",
 2937                        command.command
 2938                    )
 2939                }
 2940            }
 2941        }
 2942        Ok(())
 2943    }
 2944
 2945    pub async fn deserialize_text_edits(
 2946        this: Entity<LspStore>,
 2947        buffer_to_edit: Entity<Buffer>,
 2948        edits: Vec<lsp::TextEdit>,
 2949        push_to_history: bool,
 2950        _: Arc<CachedLspAdapter>,
 2951        language_server: Arc<LanguageServer>,
 2952        cx: &mut AsyncApp,
 2953    ) -> Result<Option<Transaction>> {
 2954        let edits = this
 2955            .update(cx, |this, cx| {
 2956                this.as_local_mut().unwrap().edits_from_lsp(
 2957                    &buffer_to_edit,
 2958                    edits,
 2959                    language_server.server_id(),
 2960                    None,
 2961                    cx,
 2962                )
 2963            })?
 2964            .await?;
 2965
 2966        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2967            buffer.finalize_last_transaction();
 2968            buffer.start_transaction();
 2969            for (range, text) in edits {
 2970                buffer.edit([(range, text)], None, cx);
 2971            }
 2972
 2973            if buffer.end_transaction(cx).is_some() {
 2974                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2975                if !push_to_history {
 2976                    buffer.forget_transaction(transaction.id);
 2977                }
 2978                Some(transaction)
 2979            } else {
 2980                None
 2981            }
 2982        })?;
 2983
 2984        Ok(transaction)
 2985    }
 2986
 2987    #[allow(clippy::type_complexity)]
 2988    pub(crate) fn edits_from_lsp(
 2989        &mut self,
 2990        buffer: &Entity<Buffer>,
 2991        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2992        server_id: LanguageServerId,
 2993        version: Option<i32>,
 2994        cx: &mut Context<LspStore>,
 2995    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2996        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2997        cx.background_spawn(async move {
 2998            let snapshot = snapshot?;
 2999            let mut lsp_edits = lsp_edits
 3000                .into_iter()
 3001                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3002                .collect::<Vec<_>>();
 3003
 3004            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 3005
 3006            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3007            let mut edits = Vec::new();
 3008            while let Some((range, mut new_text)) = lsp_edits.next() {
 3009                // Clip invalid ranges provided by the language server.
 3010                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3011                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3012
 3013                // Combine any LSP edits that are adjacent.
 3014                //
 3015                // Also, combine LSP edits that are separated from each other by only
 3016                // a newline. This is important because for some code actions,
 3017                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3018                // are separated by unchanged newline characters.
 3019                //
 3020                // In order for the diffing logic below to work properly, any edits that
 3021                // cancel each other out must be combined into one.
 3022                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3023                    if next_range.start.0 > range.end {
 3024                        if next_range.start.0.row > range.end.row + 1
 3025                            || next_range.start.0.column > 0
 3026                            || snapshot.clip_point_utf16(
 3027                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3028                                Bias::Left,
 3029                            ) > range.end
 3030                        {
 3031                            break;
 3032                        }
 3033                        new_text.push('\n');
 3034                    }
 3035                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3036                    new_text.push_str(next_text);
 3037                    lsp_edits.next();
 3038                }
 3039
 3040                // For multiline edits, perform a diff of the old and new text so that
 3041                // we can identify the changes more precisely, preserving the locations
 3042                // of any anchors positioned in the unchanged regions.
 3043                if range.end.row > range.start.row {
 3044                    let offset = range.start.to_offset(&snapshot);
 3045                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3046                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3047                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3048                        (
 3049                            snapshot.anchor_after(offset + range.start)
 3050                                ..snapshot.anchor_before(offset + range.end),
 3051                            replacement,
 3052                        )
 3053                    }));
 3054                } else if range.end == range.start {
 3055                    let anchor = snapshot.anchor_after(range.start);
 3056                    edits.push((anchor..anchor, new_text.into()));
 3057                } else {
 3058                    let edit_start = snapshot.anchor_after(range.start);
 3059                    let edit_end = snapshot.anchor_before(range.end);
 3060                    edits.push((edit_start..edit_end, new_text.into()));
 3061                }
 3062            }
 3063
 3064            Ok(edits)
 3065        })
 3066    }
 3067
 3068    pub(crate) async fn deserialize_workspace_edit(
 3069        this: Entity<LspStore>,
 3070        edit: lsp::WorkspaceEdit,
 3071        push_to_history: bool,
 3072        language_server: Arc<LanguageServer>,
 3073        cx: &mut AsyncApp,
 3074    ) -> Result<ProjectTransaction> {
 3075        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 3076
 3077        let mut operations = Vec::new();
 3078        if let Some(document_changes) = edit.document_changes {
 3079            match document_changes {
 3080                lsp::DocumentChanges::Edits(edits) => {
 3081                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3082                }
 3083                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3084            }
 3085        } else if let Some(changes) = edit.changes {
 3086            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3087                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3088                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3089                        uri,
 3090                        version: None,
 3091                    },
 3092                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3093                })
 3094            }));
 3095        }
 3096
 3097        let mut project_transaction = ProjectTransaction::default();
 3098        for operation in operations {
 3099            match operation {
 3100                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3101                    let abs_path = op
 3102                        .uri
 3103                        .to_file_path()
 3104                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3105
 3106                    if let Some(parent_path) = abs_path.parent() {
 3107                        fs.create_dir(parent_path).await?;
 3108                    }
 3109                    if abs_path.ends_with("/") {
 3110                        fs.create_dir(&abs_path).await?;
 3111                    } else {
 3112                        fs.create_file(
 3113                            &abs_path,
 3114                            op.options
 3115                                .map(|options| fs::CreateOptions {
 3116                                    overwrite: options.overwrite.unwrap_or(false),
 3117                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3118                                })
 3119                                .unwrap_or_default(),
 3120                        )
 3121                        .await?;
 3122                    }
 3123                }
 3124
 3125                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3126                    let source_abs_path = op
 3127                        .old_uri
 3128                        .to_file_path()
 3129                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3130                    let target_abs_path = op
 3131                        .new_uri
 3132                        .to_file_path()
 3133                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3134
 3135                    let options = fs::RenameOptions {
 3136                        overwrite: op
 3137                            .options
 3138                            .as_ref()
 3139                            .and_then(|options| options.overwrite)
 3140                            .unwrap_or(false),
 3141                        ignore_if_exists: op
 3142                            .options
 3143                            .as_ref()
 3144                            .and_then(|options| options.ignore_if_exists)
 3145                            .unwrap_or(false),
 3146                        create_parents: true,
 3147                    };
 3148
 3149                    fs.rename(&source_abs_path, &target_abs_path, options)
 3150                        .await?;
 3151                }
 3152
 3153                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3154                    let abs_path = op
 3155                        .uri
 3156                        .to_file_path()
 3157                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3158                    let options = op
 3159                        .options
 3160                        .map(|options| fs::RemoveOptions {
 3161                            recursive: options.recursive.unwrap_or(false),
 3162                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3163                        })
 3164                        .unwrap_or_default();
 3165                    if abs_path.ends_with("/") {
 3166                        fs.remove_dir(&abs_path, options).await?;
 3167                    } else {
 3168                        fs.remove_file(&abs_path, options).await?;
 3169                    }
 3170                }
 3171
 3172                lsp::DocumentChangeOperation::Edit(op) => {
 3173                    let buffer_to_edit = this
 3174                        .update(cx, |this, cx| {
 3175                            this.open_local_buffer_via_lsp(
 3176                                op.text_document.uri.clone(),
 3177                                language_server.server_id(),
 3178                                cx,
 3179                            )
 3180                        })?
 3181                        .await?;
 3182
 3183                    let edits = this
 3184                        .update(cx, |this, cx| {
 3185                            let path = buffer_to_edit.read(cx).project_path(cx);
 3186                            let active_entry = this.active_entry;
 3187                            let is_active_entry = path.is_some_and(|project_path| {
 3188                                this.worktree_store
 3189                                    .read(cx)
 3190                                    .entry_for_path(&project_path, cx)
 3191                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3192                            });
 3193                            let local = this.as_local_mut().unwrap();
 3194
 3195                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3196                            for edit in op.edits {
 3197                                match edit {
 3198                                    Edit::Plain(edit) => {
 3199                                        if !edits.contains(&edit) {
 3200                                            edits.push(edit)
 3201                                        }
 3202                                    }
 3203                                    Edit::Annotated(edit) => {
 3204                                        if !edits.contains(&edit.text_edit) {
 3205                                            edits.push(edit.text_edit)
 3206                                        }
 3207                                    }
 3208                                    Edit::Snippet(edit) => {
 3209                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3210                                        else {
 3211                                            continue;
 3212                                        };
 3213
 3214                                        if is_active_entry {
 3215                                            snippet_edits.push((edit.range, snippet));
 3216                                        } else {
 3217                                            // Since this buffer is not focused, apply a normal edit.
 3218                                            let new_edit = TextEdit {
 3219                                                range: edit.range,
 3220                                                new_text: snippet.text,
 3221                                            };
 3222                                            if !edits.contains(&new_edit) {
 3223                                                edits.push(new_edit);
 3224                                            }
 3225                                        }
 3226                                    }
 3227                                }
 3228                            }
 3229                            if !snippet_edits.is_empty() {
 3230                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3231                                let version = if let Some(buffer_version) = op.text_document.version
 3232                                {
 3233                                    local
 3234                                        .buffer_snapshot_for_lsp_version(
 3235                                            &buffer_to_edit,
 3236                                            language_server.server_id(),
 3237                                            Some(buffer_version),
 3238                                            cx,
 3239                                        )
 3240                                        .ok()
 3241                                        .map(|snapshot| snapshot.version)
 3242                                } else {
 3243                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3244                                };
 3245
 3246                                let most_recent_edit =
 3247                                    version.and_then(|version| version.most_recent());
 3248                                // Check if the edit that triggered that edit has been made by this participant.
 3249
 3250                                if let Some(most_recent_edit) = most_recent_edit {
 3251                                    cx.emit(LspStoreEvent::SnippetEdit {
 3252                                        buffer_id,
 3253                                        edits: snippet_edits,
 3254                                        most_recent_edit,
 3255                                    });
 3256                                }
 3257                            }
 3258
 3259                            local.edits_from_lsp(
 3260                                &buffer_to_edit,
 3261                                edits,
 3262                                language_server.server_id(),
 3263                                op.text_document.version,
 3264                                cx,
 3265                            )
 3266                        })?
 3267                        .await?;
 3268
 3269                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3270                        buffer.finalize_last_transaction();
 3271                        buffer.start_transaction();
 3272                        for (range, text) in edits {
 3273                            buffer.edit([(range, text)], None, cx);
 3274                        }
 3275
 3276                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3277                            if push_to_history {
 3278                                buffer.finalize_last_transaction();
 3279                                buffer.get_transaction(transaction_id).cloned()
 3280                            } else {
 3281                                buffer.forget_transaction(transaction_id)
 3282                            }
 3283                        })
 3284                    })?;
 3285                    if let Some(transaction) = transaction {
 3286                        project_transaction.0.insert(buffer_to_edit, transaction);
 3287                    }
 3288                }
 3289            }
 3290        }
 3291
 3292        Ok(project_transaction)
 3293    }
 3294
 3295    async fn on_lsp_workspace_edit(
 3296        this: WeakEntity<LspStore>,
 3297        params: lsp::ApplyWorkspaceEditParams,
 3298        server_id: LanguageServerId,
 3299        cx: &mut AsyncApp,
 3300    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3301        let this = this.upgrade().context("project project closed")?;
 3302        let language_server = this
 3303            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3304            .context("language server not found")?;
 3305        let transaction = Self::deserialize_workspace_edit(
 3306            this.clone(),
 3307            params.edit,
 3308            true,
 3309            language_server.clone(),
 3310            cx,
 3311        )
 3312        .await
 3313        .log_err();
 3314        this.update(cx, |this, cx| {
 3315            if let Some(transaction) = transaction {
 3316                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3317
 3318                this.as_local_mut()
 3319                    .unwrap()
 3320                    .last_workspace_edits_by_language_server
 3321                    .insert(server_id, transaction);
 3322            }
 3323        })?;
 3324        Ok(lsp::ApplyWorkspaceEditResponse {
 3325            applied: true,
 3326            failed_change: None,
 3327            failure_reason: None,
 3328        })
 3329    }
 3330
 3331    fn remove_worktree(
 3332        &mut self,
 3333        id_to_remove: WorktreeId,
 3334        cx: &mut Context<LspStore>,
 3335    ) -> Vec<LanguageServerId> {
 3336        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3337        self.diagnostics.remove(&id_to_remove);
 3338        self.prettier_store.update(cx, |prettier_store, cx| {
 3339            prettier_store.remove_worktree(id_to_remove, cx);
 3340        });
 3341
 3342        let mut servers_to_remove = BTreeSet::default();
 3343        let mut servers_to_preserve = HashSet::default();
 3344        for (seed, state) in &self.language_server_ids {
 3345            if seed.worktree_id == id_to_remove {
 3346                servers_to_remove.insert(state.id);
 3347            } else {
 3348                servers_to_preserve.insert(state.id);
 3349            }
 3350        }
 3351        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3352        self.language_server_ids
 3353            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3354        for server_id_to_remove in &servers_to_remove {
 3355            self.language_server_watched_paths
 3356                .remove(server_id_to_remove);
 3357            self.language_server_paths_watched_for_rename
 3358                .remove(server_id_to_remove);
 3359            self.last_workspace_edits_by_language_server
 3360                .remove(server_id_to_remove);
 3361            self.language_servers.remove(server_id_to_remove);
 3362            self.buffer_pull_diagnostics_result_ids
 3363                .remove(server_id_to_remove);
 3364            self.workspace_pull_diagnostics_result_ids
 3365                .remove(server_id_to_remove);
 3366            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3367                buffer_servers.remove(server_id_to_remove);
 3368            }
 3369            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3370        }
 3371        servers_to_remove.into_iter().collect()
 3372    }
 3373
 3374    fn rebuild_watched_paths_inner<'a>(
 3375        &'a self,
 3376        language_server_id: LanguageServerId,
 3377        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3378        cx: &mut Context<LspStore>,
 3379    ) -> LanguageServerWatchedPathsBuilder {
 3380        let worktrees = self
 3381            .worktree_store
 3382            .read(cx)
 3383            .worktrees()
 3384            .filter_map(|worktree| {
 3385                self.language_servers_for_worktree(worktree.read(cx).id())
 3386                    .find(|server| server.server_id() == language_server_id)
 3387                    .map(|_| worktree)
 3388            })
 3389            .collect::<Vec<_>>();
 3390
 3391        let mut worktree_globs = HashMap::default();
 3392        let mut abs_globs = HashMap::default();
 3393        log::trace!(
 3394            "Processing new watcher paths for language server with id {}",
 3395            language_server_id
 3396        );
 3397
 3398        for watcher in watchers {
 3399            if let Some((worktree, literal_prefix, pattern)) =
 3400                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3401            {
 3402                worktree.update(cx, |worktree, _| {
 3403                    if let Some((tree, glob)) =
 3404                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3405                    {
 3406                        tree.add_path_prefix_to_scan(literal_prefix);
 3407                        worktree_globs
 3408                            .entry(tree.id())
 3409                            .or_insert_with(GlobSetBuilder::new)
 3410                            .add(glob);
 3411                    }
 3412                });
 3413            } else {
 3414                let (path, pattern) = match &watcher.glob_pattern {
 3415                    lsp::GlobPattern::String(s) => {
 3416                        let watcher_path = SanitizedPath::new(s);
 3417                        let path = glob_literal_prefix(watcher_path.as_path());
 3418                        let pattern = watcher_path
 3419                            .as_path()
 3420                            .strip_prefix(&path)
 3421                            .map(|p| p.to_string_lossy().into_owned())
 3422                            .unwrap_or_else(|e| {
 3423                                debug_panic!(
 3424                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3425                                    s,
 3426                                    path.display(),
 3427                                    e
 3428                                );
 3429                                watcher_path.as_path().to_string_lossy().into_owned()
 3430                            });
 3431                        (path, pattern)
 3432                    }
 3433                    lsp::GlobPattern::Relative(rp) => {
 3434                        let Ok(mut base_uri) = match &rp.base_uri {
 3435                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3436                            lsp::OneOf::Right(base_uri) => base_uri,
 3437                        }
 3438                        .to_file_path() else {
 3439                            continue;
 3440                        };
 3441
 3442                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3443                        let pattern = Path::new(&rp.pattern)
 3444                            .strip_prefix(&path)
 3445                            .map(|p| p.to_string_lossy().into_owned())
 3446                            .unwrap_or_else(|e| {
 3447                                debug_panic!(
 3448                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3449                                    rp.pattern,
 3450                                    path.display(),
 3451                                    e
 3452                                );
 3453                                rp.pattern.clone()
 3454                            });
 3455                        base_uri.push(path);
 3456                        (base_uri, pattern)
 3457                    }
 3458                };
 3459
 3460                if let Some(glob) = Glob::new(&pattern).log_err() {
 3461                    if !path
 3462                        .components()
 3463                        .any(|c| matches!(c, path::Component::Normal(_)))
 3464                    {
 3465                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3466                        // rather than adding a new watcher for `/`.
 3467                        for worktree in &worktrees {
 3468                            worktree_globs
 3469                                .entry(worktree.read(cx).id())
 3470                                .or_insert_with(GlobSetBuilder::new)
 3471                                .add(glob.clone());
 3472                        }
 3473                    } else {
 3474                        abs_globs
 3475                            .entry(path.into())
 3476                            .or_insert_with(GlobSetBuilder::new)
 3477                            .add(glob);
 3478                    }
 3479                }
 3480            }
 3481        }
 3482
 3483        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3484        for (worktree_id, builder) in worktree_globs {
 3485            if let Ok(globset) = builder.build() {
 3486                watch_builder.watch_worktree(worktree_id, globset);
 3487            }
 3488        }
 3489        for (abs_path, builder) in abs_globs {
 3490            if let Ok(globset) = builder.build() {
 3491                watch_builder.watch_abs_path(abs_path, globset);
 3492            }
 3493        }
 3494        watch_builder
 3495    }
 3496
 3497    fn worktree_and_path_for_file_watcher(
 3498        worktrees: &[Entity<Worktree>],
 3499        watcher: &FileSystemWatcher,
 3500        cx: &App,
 3501    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3502        worktrees.iter().find_map(|worktree| {
 3503            let tree = worktree.read(cx);
 3504            let worktree_root_path = tree.abs_path();
 3505            let path_style = tree.path_style();
 3506            match &watcher.glob_pattern {
 3507                lsp::GlobPattern::String(s) => {
 3508                    let watcher_path = SanitizedPath::new(s);
 3509                    let relative = watcher_path
 3510                        .as_path()
 3511                        .strip_prefix(&worktree_root_path)
 3512                        .ok()?;
 3513                    let literal_prefix = glob_literal_prefix(relative);
 3514                    Some((
 3515                        worktree.clone(),
 3516                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3517                        relative.to_string_lossy().into_owned(),
 3518                    ))
 3519                }
 3520                lsp::GlobPattern::Relative(rp) => {
 3521                    let base_uri = match &rp.base_uri {
 3522                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3523                        lsp::OneOf::Right(base_uri) => base_uri,
 3524                    }
 3525                    .to_file_path()
 3526                    .ok()?;
 3527                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3528                    let mut literal_prefix = relative.to_owned();
 3529                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3530                    Some((
 3531                        worktree.clone(),
 3532                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3533                        rp.pattern.clone(),
 3534                    ))
 3535                }
 3536            }
 3537        })
 3538    }
 3539
 3540    fn rebuild_watched_paths(
 3541        &mut self,
 3542        language_server_id: LanguageServerId,
 3543        cx: &mut Context<LspStore>,
 3544    ) {
 3545        let Some(registrations) = self
 3546            .language_server_dynamic_registrations
 3547            .get(&language_server_id)
 3548        else {
 3549            return;
 3550        };
 3551
 3552        let watch_builder = self.rebuild_watched_paths_inner(
 3553            language_server_id,
 3554            registrations.did_change_watched_files.values().flatten(),
 3555            cx,
 3556        );
 3557        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3558        self.language_server_watched_paths
 3559            .insert(language_server_id, watcher);
 3560
 3561        cx.notify();
 3562    }
 3563
 3564    fn on_lsp_did_change_watched_files(
 3565        &mut self,
 3566        language_server_id: LanguageServerId,
 3567        registration_id: &str,
 3568        params: DidChangeWatchedFilesRegistrationOptions,
 3569        cx: &mut Context<LspStore>,
 3570    ) {
 3571        let registrations = self
 3572            .language_server_dynamic_registrations
 3573            .entry(language_server_id)
 3574            .or_default();
 3575
 3576        registrations
 3577            .did_change_watched_files
 3578            .insert(registration_id.to_string(), params.watchers);
 3579
 3580        self.rebuild_watched_paths(language_server_id, cx);
 3581    }
 3582
 3583    fn on_lsp_unregister_did_change_watched_files(
 3584        &mut self,
 3585        language_server_id: LanguageServerId,
 3586        registration_id: &str,
 3587        cx: &mut Context<LspStore>,
 3588    ) {
 3589        let registrations = self
 3590            .language_server_dynamic_registrations
 3591            .entry(language_server_id)
 3592            .or_default();
 3593
 3594        if registrations
 3595            .did_change_watched_files
 3596            .remove(registration_id)
 3597            .is_some()
 3598        {
 3599            log::info!(
 3600                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3601                language_server_id,
 3602                registration_id
 3603            );
 3604        } else {
 3605            log::warn!(
 3606                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3607                language_server_id,
 3608                registration_id
 3609            );
 3610        }
 3611
 3612        self.rebuild_watched_paths(language_server_id, cx);
 3613    }
 3614
 3615    async fn initialization_options_for_adapter(
 3616        adapter: Arc<dyn LspAdapter>,
 3617        delegate: &Arc<dyn LspAdapterDelegate>,
 3618    ) -> Result<Option<serde_json::Value>> {
 3619        let Some(mut initialization_config) =
 3620            adapter.clone().initialization_options(delegate).await?
 3621        else {
 3622            return Ok(None);
 3623        };
 3624
 3625        for other_adapter in delegate.registered_lsp_adapters() {
 3626            if other_adapter.name() == adapter.name() {
 3627                continue;
 3628            }
 3629            if let Ok(Some(target_config)) = other_adapter
 3630                .clone()
 3631                .additional_initialization_options(adapter.name(), delegate)
 3632                .await
 3633            {
 3634                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3635            }
 3636        }
 3637
 3638        Ok(Some(initialization_config))
 3639    }
 3640
 3641    async fn workspace_configuration_for_adapter(
 3642        adapter: Arc<dyn LspAdapter>,
 3643        delegate: &Arc<dyn LspAdapterDelegate>,
 3644        toolchain: Option<Toolchain>,
 3645        requested_uri: Option<Uri>,
 3646        cx: &mut AsyncApp,
 3647    ) -> Result<serde_json::Value> {
 3648        let mut workspace_config = adapter
 3649            .clone()
 3650            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3651            .await?;
 3652
 3653        for other_adapter in delegate.registered_lsp_adapters() {
 3654            if other_adapter.name() == adapter.name() {
 3655                continue;
 3656            }
 3657            if let Ok(Some(target_config)) = other_adapter
 3658                .clone()
 3659                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3660                .await
 3661            {
 3662                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3663            }
 3664        }
 3665
 3666        Ok(workspace_config)
 3667    }
 3668
 3669    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3670        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3671            Some(server.clone())
 3672        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3673            Some(Arc::clone(server))
 3674        } else {
 3675            None
 3676        }
 3677    }
 3678}
 3679
 3680fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3681    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3682        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3683            language_server_id: server.server_id(),
 3684            name: Some(server.name()),
 3685            message: proto::update_language_server::Variant::MetadataUpdated(
 3686                proto::ServerMetadataUpdated {
 3687                    capabilities: Some(capabilities),
 3688                    binary: Some(proto::LanguageServerBinaryInfo {
 3689                        path: server.binary().path.to_string_lossy().into_owned(),
 3690                        arguments: server
 3691                            .binary()
 3692                            .arguments
 3693                            .iter()
 3694                            .map(|arg| arg.to_string_lossy().into_owned())
 3695                            .collect(),
 3696                    }),
 3697                    configuration: serde_json::to_string(server.configuration()).ok(),
 3698                    workspace_folders: server
 3699                        .workspace_folders()
 3700                        .iter()
 3701                        .map(|uri| uri.to_string())
 3702                        .collect(),
 3703                },
 3704            ),
 3705        });
 3706    }
 3707}
 3708
 3709#[derive(Debug)]
 3710pub struct FormattableBuffer {
 3711    handle: Entity<Buffer>,
 3712    abs_path: Option<PathBuf>,
 3713    env: Option<HashMap<String, String>>,
 3714    ranges: Option<Vec<Range<Anchor>>>,
 3715}
 3716
 3717pub struct RemoteLspStore {
 3718    upstream_client: Option<AnyProtoClient>,
 3719    upstream_project_id: u64,
 3720}
 3721
 3722pub(crate) enum LspStoreMode {
 3723    Local(LocalLspStore),   // ssh host and collab host
 3724    Remote(RemoteLspStore), // collab guest
 3725}
 3726
 3727impl LspStoreMode {
 3728    fn is_local(&self) -> bool {
 3729        matches!(self, LspStoreMode::Local(_))
 3730    }
 3731}
 3732
 3733pub struct LspStore {
 3734    mode: LspStoreMode,
 3735    last_formatting_failure: Option<String>,
 3736    downstream_client: Option<(AnyProtoClient, u64)>,
 3737    nonce: u128,
 3738    buffer_store: Entity<BufferStore>,
 3739    worktree_store: Entity<WorktreeStore>,
 3740    pub languages: Arc<LanguageRegistry>,
 3741    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3742    active_entry: Option<ProjectEntryId>,
 3743    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3744    _maintain_buffer_languages: Task<()>,
 3745    diagnostic_summaries:
 3746        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3747    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3748    lsp_data: HashMap<BufferId, BufferLspData>,
 3749    next_hint_id: Arc<AtomicUsize>,
 3750}
 3751
 3752#[derive(Debug)]
 3753pub struct BufferLspData {
 3754    buffer_version: Global,
 3755    document_colors: Option<DocumentColorData>,
 3756    code_lens: Option<CodeLensData>,
 3757    inlay_hints: BufferInlayHints,
 3758    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3759    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3760}
 3761
 3762#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3763struct LspKey {
 3764    request_type: TypeId,
 3765    server_queried: Option<LanguageServerId>,
 3766}
 3767
 3768impl BufferLspData {
 3769    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3770        Self {
 3771            buffer_version: buffer.read(cx).version(),
 3772            document_colors: None,
 3773            code_lens: None,
 3774            inlay_hints: BufferInlayHints::new(buffer, cx),
 3775            lsp_requests: HashMap::default(),
 3776            chunk_lsp_requests: HashMap::default(),
 3777        }
 3778    }
 3779
 3780    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3781        if let Some(document_colors) = &mut self.document_colors {
 3782            document_colors.colors.remove(&for_server);
 3783            document_colors.cache_version += 1;
 3784        }
 3785
 3786        if let Some(code_lens) = &mut self.code_lens {
 3787            code_lens.lens.remove(&for_server);
 3788        }
 3789
 3790        self.inlay_hints.remove_server_data(for_server);
 3791    }
 3792
 3793    #[cfg(any(test, feature = "test-support"))]
 3794    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3795        &self.inlay_hints
 3796    }
 3797}
 3798
 3799#[derive(Debug, Default, Clone)]
 3800pub struct DocumentColors {
 3801    pub colors: HashSet<DocumentColor>,
 3802    pub cache_version: Option<usize>,
 3803}
 3804
 3805type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3806type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3807
 3808#[derive(Debug, Default)]
 3809struct DocumentColorData {
 3810    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3811    cache_version: usize,
 3812    colors_update: Option<(Global, DocumentColorTask)>,
 3813}
 3814
 3815#[derive(Debug, Default)]
 3816struct CodeLensData {
 3817    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3818    update: Option<(Global, CodeLensTask)>,
 3819}
 3820
 3821#[derive(Debug)]
 3822pub enum LspStoreEvent {
 3823    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3824    LanguageServerRemoved(LanguageServerId),
 3825    LanguageServerUpdate {
 3826        language_server_id: LanguageServerId,
 3827        name: Option<LanguageServerName>,
 3828        message: proto::update_language_server::Variant,
 3829    },
 3830    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3831    LanguageServerPrompt(LanguageServerPromptRequest),
 3832    LanguageDetected {
 3833        buffer: Entity<Buffer>,
 3834        new_language: Option<Arc<Language>>,
 3835    },
 3836    Notification(String),
 3837    RefreshInlayHints {
 3838        server_id: LanguageServerId,
 3839        request_id: Option<usize>,
 3840    },
 3841    RefreshCodeLens,
 3842    DiagnosticsUpdated {
 3843        server_id: LanguageServerId,
 3844        paths: Vec<ProjectPath>,
 3845    },
 3846    DiskBasedDiagnosticsStarted {
 3847        language_server_id: LanguageServerId,
 3848    },
 3849    DiskBasedDiagnosticsFinished {
 3850        language_server_id: LanguageServerId,
 3851    },
 3852    SnippetEdit {
 3853        buffer_id: BufferId,
 3854        edits: Vec<(lsp::Range, Snippet)>,
 3855        most_recent_edit: clock::Lamport,
 3856    },
 3857    WorkspaceEditApplied(ProjectTransaction),
 3858}
 3859
 3860#[derive(Clone, Debug, Serialize)]
 3861pub struct LanguageServerStatus {
 3862    pub name: LanguageServerName,
 3863    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3864    pub has_pending_diagnostic_updates: bool,
 3865    pub progress_tokens: HashSet<ProgressToken>,
 3866    pub worktree: Option<WorktreeId>,
 3867    pub binary: Option<LanguageServerBinary>,
 3868    pub configuration: Option<Value>,
 3869    pub workspace_folders: BTreeSet<Uri>,
 3870}
 3871
 3872#[derive(Clone, Debug)]
 3873struct CoreSymbol {
 3874    pub language_server_name: LanguageServerName,
 3875    pub source_worktree_id: WorktreeId,
 3876    pub source_language_server_id: LanguageServerId,
 3877    pub path: SymbolLocation,
 3878    pub name: String,
 3879    pub kind: lsp::SymbolKind,
 3880    pub range: Range<Unclipped<PointUtf16>>,
 3881}
 3882
 3883#[derive(Clone, Debug, PartialEq, Eq)]
 3884pub enum SymbolLocation {
 3885    InProject(ProjectPath),
 3886    OutsideProject {
 3887        abs_path: Arc<Path>,
 3888        signature: [u8; 32],
 3889    },
 3890}
 3891
 3892impl SymbolLocation {
 3893    fn file_name(&self) -> Option<&str> {
 3894        match self {
 3895            Self::InProject(path) => path.path.file_name(),
 3896            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3897        }
 3898    }
 3899}
 3900
 3901impl LspStore {
 3902    pub fn init(client: &AnyProtoClient) {
 3903        client.add_entity_request_handler(Self::handle_lsp_query);
 3904        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3905        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3906        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3907        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3908        client.add_entity_message_handler(Self::handle_start_language_server);
 3909        client.add_entity_message_handler(Self::handle_update_language_server);
 3910        client.add_entity_message_handler(Self::handle_language_server_log);
 3911        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3912        client.add_entity_request_handler(Self::handle_format_buffers);
 3913        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3914        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3915        client.add_entity_request_handler(Self::handle_apply_code_action);
 3916        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3917        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3918        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3919        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3920        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3921        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3922        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3923        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3924        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3925        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3926        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3927        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3928        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3929        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3930        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3931        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3932        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3933
 3934        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3935        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3936        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3937        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3938        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3939        client.add_entity_request_handler(
 3940            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3941        );
 3942        client.add_entity_request_handler(
 3943            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3944        );
 3945        client.add_entity_request_handler(
 3946            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3947        );
 3948    }
 3949
 3950    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3951        match &self.mode {
 3952            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3953            _ => None,
 3954        }
 3955    }
 3956
 3957    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3958        match &self.mode {
 3959            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3960            _ => None,
 3961        }
 3962    }
 3963
 3964    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3965        match &mut self.mode {
 3966            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3967            _ => None,
 3968        }
 3969    }
 3970
 3971    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3972        match &self.mode {
 3973            LspStoreMode::Remote(RemoteLspStore {
 3974                upstream_client: Some(upstream_client),
 3975                upstream_project_id,
 3976                ..
 3977            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3978
 3979            LspStoreMode::Remote(RemoteLspStore {
 3980                upstream_client: None,
 3981                ..
 3982            }) => None,
 3983            LspStoreMode::Local(_) => None,
 3984        }
 3985    }
 3986
 3987    pub fn new_local(
 3988        buffer_store: Entity<BufferStore>,
 3989        worktree_store: Entity<WorktreeStore>,
 3990        prettier_store: Entity<PrettierStore>,
 3991        toolchain_store: Entity<LocalToolchainStore>,
 3992        environment: Entity<ProjectEnvironment>,
 3993        manifest_tree: Entity<ManifestTree>,
 3994        languages: Arc<LanguageRegistry>,
 3995        http_client: Arc<dyn HttpClient>,
 3996        fs: Arc<dyn Fs>,
 3997        cx: &mut Context<Self>,
 3998    ) -> Self {
 3999        let yarn = YarnPathStore::new(fs.clone(), cx);
 4000        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4001            .detach();
 4002        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4003            .detach();
 4004        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4005            .detach();
 4006        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4007            .detach();
 4008        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4009            .detach();
 4010        subscribe_to_binary_statuses(&languages, cx).detach();
 4011
 4012        let _maintain_workspace_config = {
 4013            let (sender, receiver) = watch::channel();
 4014            (Self::maintain_workspace_config(receiver, cx), sender)
 4015        };
 4016
 4017        Self {
 4018            mode: LspStoreMode::Local(LocalLspStore {
 4019                weak: cx.weak_entity(),
 4020                worktree_store: worktree_store.clone(),
 4021
 4022                supplementary_language_servers: Default::default(),
 4023                languages: languages.clone(),
 4024                language_server_ids: Default::default(),
 4025                language_servers: Default::default(),
 4026                last_workspace_edits_by_language_server: Default::default(),
 4027                language_server_watched_paths: Default::default(),
 4028                language_server_paths_watched_for_rename: Default::default(),
 4029                language_server_dynamic_registrations: Default::default(),
 4030                buffers_being_formatted: Default::default(),
 4031                buffer_snapshots: Default::default(),
 4032                prettier_store,
 4033                environment,
 4034                http_client,
 4035                fs,
 4036                yarn,
 4037                next_diagnostic_group_id: Default::default(),
 4038                diagnostics: Default::default(),
 4039                _subscription: cx.on_app_quit(|this, cx| {
 4040                    this.as_local_mut()
 4041                        .unwrap()
 4042                        .shutdown_language_servers_on_quit(cx)
 4043                }),
 4044                lsp_tree: LanguageServerTree::new(
 4045                    manifest_tree,
 4046                    languages.clone(),
 4047                    toolchain_store.clone(),
 4048                ),
 4049                toolchain_store,
 4050                registered_buffers: HashMap::default(),
 4051                buffers_opened_in_servers: HashMap::default(),
 4052                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4053                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4054                restricted_worktrees_tasks: HashMap::default(),
 4055                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4056                    .manifest_file_names(),
 4057            }),
 4058            last_formatting_failure: None,
 4059            downstream_client: None,
 4060            buffer_store,
 4061            worktree_store,
 4062            languages: languages.clone(),
 4063            language_server_statuses: Default::default(),
 4064            nonce: StdRng::from_os_rng().random(),
 4065            diagnostic_summaries: HashMap::default(),
 4066            lsp_server_capabilities: HashMap::default(),
 4067            lsp_data: HashMap::default(),
 4068            next_hint_id: Arc::default(),
 4069            active_entry: None,
 4070            _maintain_workspace_config,
 4071            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4072        }
 4073    }
 4074
 4075    fn send_lsp_proto_request<R: LspCommand>(
 4076        &self,
 4077        buffer: Entity<Buffer>,
 4078        client: AnyProtoClient,
 4079        upstream_project_id: u64,
 4080        request: R,
 4081        cx: &mut Context<LspStore>,
 4082    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4083        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4084            return Task::ready(Ok(R::Response::default()));
 4085        }
 4086        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4087        cx.spawn(async move |this, cx| {
 4088            let response = client.request(message).await?;
 4089            let this = this.upgrade().context("project dropped")?;
 4090            request
 4091                .response_from_proto(response, this, buffer, cx.clone())
 4092                .await
 4093        })
 4094    }
 4095
 4096    pub(super) fn new_remote(
 4097        buffer_store: Entity<BufferStore>,
 4098        worktree_store: Entity<WorktreeStore>,
 4099        languages: Arc<LanguageRegistry>,
 4100        upstream_client: AnyProtoClient,
 4101        project_id: u64,
 4102        cx: &mut Context<Self>,
 4103    ) -> Self {
 4104        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4105            .detach();
 4106        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4107            .detach();
 4108        subscribe_to_binary_statuses(&languages, cx).detach();
 4109        let _maintain_workspace_config = {
 4110            let (sender, receiver) = watch::channel();
 4111            (Self::maintain_workspace_config(receiver, cx), sender)
 4112        };
 4113        Self {
 4114            mode: LspStoreMode::Remote(RemoteLspStore {
 4115                upstream_client: Some(upstream_client),
 4116                upstream_project_id: project_id,
 4117            }),
 4118            downstream_client: None,
 4119            last_formatting_failure: None,
 4120            buffer_store,
 4121            worktree_store,
 4122            languages: languages.clone(),
 4123            language_server_statuses: Default::default(),
 4124            nonce: StdRng::from_os_rng().random(),
 4125            diagnostic_summaries: HashMap::default(),
 4126            lsp_server_capabilities: HashMap::default(),
 4127            next_hint_id: Arc::default(),
 4128            lsp_data: HashMap::default(),
 4129            active_entry: None,
 4130
 4131            _maintain_workspace_config,
 4132            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4133        }
 4134    }
 4135
 4136    fn on_buffer_store_event(
 4137        &mut self,
 4138        _: Entity<BufferStore>,
 4139        event: &BufferStoreEvent,
 4140        cx: &mut Context<Self>,
 4141    ) {
 4142        match event {
 4143            BufferStoreEvent::BufferAdded(buffer) => {
 4144                self.on_buffer_added(buffer, cx).log_err();
 4145            }
 4146            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4147                let buffer_id = buffer.read(cx).remote_id();
 4148                if let Some(local) = self.as_local_mut()
 4149                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4150                {
 4151                    local.reset_buffer(buffer, old_file, cx);
 4152
 4153                    if local.registered_buffers.contains_key(&buffer_id) {
 4154                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4155                    }
 4156                }
 4157
 4158                self.detect_language_for_buffer(buffer, cx);
 4159                if let Some(local) = self.as_local_mut() {
 4160                    local.initialize_buffer(buffer, cx);
 4161                    if local.registered_buffers.contains_key(&buffer_id) {
 4162                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4163                    }
 4164                }
 4165            }
 4166            _ => {}
 4167        }
 4168    }
 4169
 4170    fn on_worktree_store_event(
 4171        &mut self,
 4172        _: Entity<WorktreeStore>,
 4173        event: &WorktreeStoreEvent,
 4174        cx: &mut Context<Self>,
 4175    ) {
 4176        match event {
 4177            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4178                if !worktree.read(cx).is_local() {
 4179                    return;
 4180                }
 4181                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4182                    worktree::Event::UpdatedEntries(changes) => {
 4183                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4184                    }
 4185                    worktree::Event::UpdatedGitRepositories(_)
 4186                    | worktree::Event::DeletedEntry(_) => {}
 4187                })
 4188                .detach()
 4189            }
 4190            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4191            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4192                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4193            }
 4194            WorktreeStoreEvent::WorktreeReleased(..)
 4195            | WorktreeStoreEvent::WorktreeOrderChanged
 4196            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4197            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4198            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4199        }
 4200    }
 4201
 4202    fn on_prettier_store_event(
 4203        &mut self,
 4204        _: Entity<PrettierStore>,
 4205        event: &PrettierStoreEvent,
 4206        cx: &mut Context<Self>,
 4207    ) {
 4208        match event {
 4209            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4210                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4211            }
 4212            PrettierStoreEvent::LanguageServerAdded {
 4213                new_server_id,
 4214                name,
 4215                prettier_server,
 4216            } => {
 4217                self.register_supplementary_language_server(
 4218                    *new_server_id,
 4219                    name.clone(),
 4220                    prettier_server.clone(),
 4221                    cx,
 4222                );
 4223            }
 4224        }
 4225    }
 4226
 4227    fn on_toolchain_store_event(
 4228        &mut self,
 4229        _: Entity<LocalToolchainStore>,
 4230        event: &ToolchainStoreEvent,
 4231        _: &mut Context<Self>,
 4232    ) {
 4233        if let ToolchainStoreEvent::ToolchainActivated = event {
 4234            self.request_workspace_config_refresh()
 4235        }
 4236    }
 4237
 4238    fn request_workspace_config_refresh(&mut self) {
 4239        *self._maintain_workspace_config.1.borrow_mut() = ();
 4240    }
 4241
 4242    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4243        self.as_local().map(|local| local.prettier_store.clone())
 4244    }
 4245
 4246    fn on_buffer_event(
 4247        &mut self,
 4248        buffer: Entity<Buffer>,
 4249        event: &language::BufferEvent,
 4250        cx: &mut Context<Self>,
 4251    ) {
 4252        match event {
 4253            language::BufferEvent::Edited => {
 4254                self.on_buffer_edited(buffer, cx);
 4255            }
 4256
 4257            language::BufferEvent::Saved => {
 4258                self.on_buffer_saved(buffer, cx);
 4259            }
 4260
 4261            _ => {}
 4262        }
 4263    }
 4264
 4265    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4266        buffer
 4267            .read(cx)
 4268            .set_language_registry(self.languages.clone());
 4269
 4270        cx.subscribe(buffer, |this, buffer, event, cx| {
 4271            this.on_buffer_event(buffer, event, cx);
 4272        })
 4273        .detach();
 4274
 4275        self.detect_language_for_buffer(buffer, cx);
 4276        if let Some(local) = self.as_local_mut() {
 4277            local.initialize_buffer(buffer, cx);
 4278        }
 4279
 4280        Ok(())
 4281    }
 4282
 4283    pub(crate) fn register_buffer_with_language_servers(
 4284        &mut self,
 4285        buffer: &Entity<Buffer>,
 4286        only_register_servers: HashSet<LanguageServerSelector>,
 4287        ignore_refcounts: bool,
 4288        cx: &mut Context<Self>,
 4289    ) -> OpenLspBufferHandle {
 4290        let buffer_id = buffer.read(cx).remote_id();
 4291        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4292        if let Some(local) = self.as_local_mut() {
 4293            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4294            if !ignore_refcounts {
 4295                *refcount += 1;
 4296            }
 4297
 4298            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4299            // 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
 4300            // 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
 4301            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4302            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4303                return handle;
 4304            };
 4305            if !file.is_local() {
 4306                return handle;
 4307            }
 4308
 4309            if ignore_refcounts || *refcount == 1 {
 4310                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4311            }
 4312            if !ignore_refcounts {
 4313                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4314                    let refcount = {
 4315                        let local = lsp_store.as_local_mut().unwrap();
 4316                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4317                            debug_panic!("bad refcounting");
 4318                            return;
 4319                        };
 4320
 4321                        *refcount -= 1;
 4322                        *refcount
 4323                    };
 4324                    if refcount == 0 {
 4325                        lsp_store.lsp_data.remove(&buffer_id);
 4326                        let local = lsp_store.as_local_mut().unwrap();
 4327                        local.registered_buffers.remove(&buffer_id);
 4328
 4329                        local.buffers_opened_in_servers.remove(&buffer_id);
 4330                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4331                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4332
 4333                            let buffer_abs_path = file.abs_path(cx);
 4334                            for (_, buffer_pull_diagnostics_result_ids) in
 4335                                &mut local.buffer_pull_diagnostics_result_ids
 4336                            {
 4337                                buffer_pull_diagnostics_result_ids.retain(
 4338                                    |_, buffer_result_ids| {
 4339                                        buffer_result_ids.remove(&buffer_abs_path);
 4340                                        !buffer_result_ids.is_empty()
 4341                                    },
 4342                                );
 4343                            }
 4344
 4345                            let diagnostic_updates = local
 4346                                .language_servers
 4347                                .keys()
 4348                                .cloned()
 4349                                .map(|server_id| DocumentDiagnosticsUpdate {
 4350                                    diagnostics: DocumentDiagnostics {
 4351                                        document_abs_path: buffer_abs_path.clone(),
 4352                                        version: None,
 4353                                        diagnostics: Vec::new(),
 4354                                    },
 4355                                    result_id: None,
 4356                                    registration_id: None,
 4357                                    server_id: server_id,
 4358                                    disk_based_sources: Cow::Borrowed(&[]),
 4359                                })
 4360                                .collect::<Vec<_>>();
 4361
 4362                            lsp_store
 4363                                .merge_diagnostic_entries(
 4364                                    diagnostic_updates,
 4365                                    |_, diagnostic, _| {
 4366                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4367                                    },
 4368                                    cx,
 4369                                )
 4370                                .context("Clearing diagnostics for the closed buffer")
 4371                                .log_err();
 4372                        }
 4373                    }
 4374                })
 4375                .detach();
 4376            }
 4377        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4378            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4379            cx.background_spawn(async move {
 4380                upstream_client
 4381                    .request(proto::RegisterBufferWithLanguageServers {
 4382                        project_id: upstream_project_id,
 4383                        buffer_id,
 4384                        only_servers: only_register_servers
 4385                            .into_iter()
 4386                            .map(|selector| {
 4387                                let selector = match selector {
 4388                                    LanguageServerSelector::Id(language_server_id) => {
 4389                                        proto::language_server_selector::Selector::ServerId(
 4390                                            language_server_id.to_proto(),
 4391                                        )
 4392                                    }
 4393                                    LanguageServerSelector::Name(language_server_name) => {
 4394                                        proto::language_server_selector::Selector::Name(
 4395                                            language_server_name.to_string(),
 4396                                        )
 4397                                    }
 4398                                };
 4399                                proto::LanguageServerSelector {
 4400                                    selector: Some(selector),
 4401                                }
 4402                            })
 4403                            .collect(),
 4404                    })
 4405                    .await
 4406            })
 4407            .detach();
 4408        } else {
 4409            // Our remote connection got closed
 4410        }
 4411        handle
 4412    }
 4413
 4414    fn maintain_buffer_languages(
 4415        languages: Arc<LanguageRegistry>,
 4416        cx: &mut Context<Self>,
 4417    ) -> Task<()> {
 4418        let mut subscription = languages.subscribe();
 4419        let mut prev_reload_count = languages.reload_count();
 4420        cx.spawn(async move |this, cx| {
 4421            while let Some(()) = subscription.next().await {
 4422                if let Some(this) = this.upgrade() {
 4423                    // If the language registry has been reloaded, then remove and
 4424                    // re-assign the languages on all open buffers.
 4425                    let reload_count = languages.reload_count();
 4426                    if reload_count > prev_reload_count {
 4427                        prev_reload_count = reload_count;
 4428                        this.update(cx, |this, cx| {
 4429                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4430                                for buffer in buffer_store.buffers() {
 4431                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4432                                    {
 4433                                        buffer.update(cx, |buffer, cx| {
 4434                                            buffer.set_language_async(None, cx)
 4435                                        });
 4436                                        if let Some(local) = this.as_local_mut() {
 4437                                            local.reset_buffer(&buffer, &f, cx);
 4438
 4439                                            if local
 4440                                                .registered_buffers
 4441                                                .contains_key(&buffer.read(cx).remote_id())
 4442                                                && let Some(file_url) =
 4443                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4444                                            {
 4445                                                local.unregister_buffer_from_language_servers(
 4446                                                    &buffer, &file_url, cx,
 4447                                                );
 4448                                            }
 4449                                        }
 4450                                    }
 4451                                }
 4452                            });
 4453                        })
 4454                        .ok();
 4455                    }
 4456
 4457                    this.update(cx, |this, cx| {
 4458                        let mut plain_text_buffers = Vec::new();
 4459                        let mut buffers_with_unknown_injections = Vec::new();
 4460                        for handle in this.buffer_store.read(cx).buffers() {
 4461                            let buffer = handle.read(cx);
 4462                            if buffer.language().is_none()
 4463                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4464                            {
 4465                                plain_text_buffers.push(handle);
 4466                            } else if buffer.contains_unknown_injections() {
 4467                                buffers_with_unknown_injections.push(handle);
 4468                            }
 4469                        }
 4470
 4471                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4472                        // and reused later in the invisible worktrees.
 4473                        plain_text_buffers.sort_by_key(|buffer| {
 4474                            Reverse(
 4475                                File::from_dyn(buffer.read(cx).file())
 4476                                    .map(|file| file.worktree.read(cx).is_visible()),
 4477                            )
 4478                        });
 4479
 4480                        for buffer in plain_text_buffers {
 4481                            this.detect_language_for_buffer(&buffer, cx);
 4482                            if let Some(local) = this.as_local_mut() {
 4483                                local.initialize_buffer(&buffer, cx);
 4484                                if local
 4485                                    .registered_buffers
 4486                                    .contains_key(&buffer.read(cx).remote_id())
 4487                                {
 4488                                    local.register_buffer_with_language_servers(
 4489                                        &buffer,
 4490                                        HashSet::default(),
 4491                                        cx,
 4492                                    );
 4493                                }
 4494                            }
 4495                        }
 4496
 4497                        for buffer in buffers_with_unknown_injections {
 4498                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4499                        }
 4500                    })
 4501                    .ok();
 4502                }
 4503            }
 4504        })
 4505    }
 4506
 4507    fn detect_language_for_buffer(
 4508        &mut self,
 4509        buffer_handle: &Entity<Buffer>,
 4510        cx: &mut Context<Self>,
 4511    ) -> Option<language::AvailableLanguage> {
 4512        // If the buffer has a language, set it and start the language server if we haven't already.
 4513        let buffer = buffer_handle.read(cx);
 4514        let file = buffer.file()?;
 4515
 4516        let content = buffer.as_rope();
 4517        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4518        if let Some(available_language) = &available_language {
 4519            if let Some(Ok(Ok(new_language))) = self
 4520                .languages
 4521                .load_language(available_language)
 4522                .now_or_never()
 4523            {
 4524                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4525            }
 4526        } else {
 4527            cx.emit(LspStoreEvent::LanguageDetected {
 4528                buffer: buffer_handle.clone(),
 4529                new_language: None,
 4530            });
 4531        }
 4532
 4533        available_language
 4534    }
 4535
 4536    pub(crate) fn set_language_for_buffer(
 4537        &mut self,
 4538        buffer_entity: &Entity<Buffer>,
 4539        new_language: Arc<Language>,
 4540        cx: &mut Context<Self>,
 4541    ) {
 4542        let buffer = buffer_entity.read(cx);
 4543        let buffer_file = buffer.file().cloned();
 4544        let buffer_id = buffer.remote_id();
 4545        if let Some(local_store) = self.as_local_mut()
 4546            && local_store.registered_buffers.contains_key(&buffer_id)
 4547            && let Some(abs_path) =
 4548                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4549            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4550        {
 4551            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4552        }
 4553        buffer_entity.update(cx, |buffer, cx| {
 4554            if buffer
 4555                .language()
 4556                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4557            {
 4558                buffer.set_language_async(Some(new_language.clone()), cx);
 4559            }
 4560        });
 4561
 4562        let settings =
 4563            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4564        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4565
 4566        let worktree_id = if let Some(file) = buffer_file {
 4567            let worktree = file.worktree.clone();
 4568
 4569            if let Some(local) = self.as_local_mut()
 4570                && local.registered_buffers.contains_key(&buffer_id)
 4571            {
 4572                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4573            }
 4574            Some(worktree.read(cx).id())
 4575        } else {
 4576            None
 4577        };
 4578
 4579        if settings.prettier.allowed
 4580            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4581        {
 4582            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4583            if let Some(prettier_store) = prettier_store {
 4584                prettier_store.update(cx, |prettier_store, cx| {
 4585                    prettier_store.install_default_prettier(
 4586                        worktree_id,
 4587                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4588                        cx,
 4589                    )
 4590                })
 4591            }
 4592        }
 4593
 4594        cx.emit(LspStoreEvent::LanguageDetected {
 4595            buffer: buffer_entity.clone(),
 4596            new_language: Some(new_language),
 4597        })
 4598    }
 4599
 4600    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4601        self.buffer_store.clone()
 4602    }
 4603
 4604    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4605        self.active_entry = active_entry;
 4606    }
 4607
 4608    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4609        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4610            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4611        {
 4612            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4613                summaries
 4614                    .iter()
 4615                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4616            });
 4617            if let Some(summary) = summaries.next() {
 4618                client
 4619                    .send(proto::UpdateDiagnosticSummary {
 4620                        project_id: downstream_project_id,
 4621                        worktree_id: worktree.id().to_proto(),
 4622                        summary: Some(summary),
 4623                        more_summaries: summaries.collect(),
 4624                    })
 4625                    .log_err();
 4626            }
 4627        }
 4628    }
 4629
 4630    fn is_capable_for_proto_request<R>(
 4631        &self,
 4632        buffer: &Entity<Buffer>,
 4633        request: &R,
 4634        cx: &App,
 4635    ) -> bool
 4636    where
 4637        R: LspCommand,
 4638    {
 4639        self.check_if_capable_for_proto_request(
 4640            buffer,
 4641            |capabilities| {
 4642                request.check_capabilities(AdapterServerCapabilities {
 4643                    server_capabilities: capabilities.clone(),
 4644                    code_action_kinds: None,
 4645                })
 4646            },
 4647            cx,
 4648        )
 4649    }
 4650
 4651    fn check_if_capable_for_proto_request<F>(
 4652        &self,
 4653        buffer: &Entity<Buffer>,
 4654        check: F,
 4655        cx: &App,
 4656    ) -> bool
 4657    where
 4658        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4659    {
 4660        let Some(language) = buffer.read(cx).language().cloned() else {
 4661            return false;
 4662        };
 4663        let relevant_language_servers = self
 4664            .languages
 4665            .lsp_adapters(&language.name())
 4666            .into_iter()
 4667            .map(|lsp_adapter| lsp_adapter.name())
 4668            .collect::<HashSet<_>>();
 4669        self.language_server_statuses
 4670            .iter()
 4671            .filter_map(|(server_id, server_status)| {
 4672                relevant_language_servers
 4673                    .contains(&server_status.name)
 4674                    .then_some(server_id)
 4675            })
 4676            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4677            .any(check)
 4678    }
 4679
 4680    fn all_capable_for_proto_request<F>(
 4681        &self,
 4682        buffer: &Entity<Buffer>,
 4683        mut check: F,
 4684        cx: &App,
 4685    ) -> Vec<lsp::LanguageServerId>
 4686    where
 4687        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4688    {
 4689        let Some(language) = buffer.read(cx).language().cloned() else {
 4690            return Vec::default();
 4691        };
 4692        let relevant_language_servers = self
 4693            .languages
 4694            .lsp_adapters(&language.name())
 4695            .into_iter()
 4696            .map(|lsp_adapter| lsp_adapter.name())
 4697            .collect::<HashSet<_>>();
 4698        self.language_server_statuses
 4699            .iter()
 4700            .filter_map(|(server_id, server_status)| {
 4701                relevant_language_servers
 4702                    .contains(&server_status.name)
 4703                    .then_some((server_id, &server_status.name))
 4704            })
 4705            .filter_map(|(server_id, server_name)| {
 4706                self.lsp_server_capabilities
 4707                    .get(server_id)
 4708                    .map(|c| (server_id, server_name, c))
 4709            })
 4710            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4711            .map(|(server_id, _, _)| *server_id)
 4712            .collect()
 4713    }
 4714
 4715    pub fn request_lsp<R>(
 4716        &mut self,
 4717        buffer: Entity<Buffer>,
 4718        server: LanguageServerToQuery,
 4719        request: R,
 4720        cx: &mut Context<Self>,
 4721    ) -> Task<Result<R::Response>>
 4722    where
 4723        R: LspCommand,
 4724        <R::LspRequest as lsp::request::Request>::Result: Send,
 4725        <R::LspRequest as lsp::request::Request>::Params: Send,
 4726    {
 4727        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4728            return self.send_lsp_proto_request(
 4729                buffer,
 4730                upstream_client,
 4731                upstream_project_id,
 4732                request,
 4733                cx,
 4734            );
 4735        }
 4736
 4737        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4738            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4739                local
 4740                    .language_servers_for_buffer(buffer, cx)
 4741                    .find(|(_, server)| {
 4742                        request.check_capabilities(server.adapter_server_capabilities())
 4743                    })
 4744                    .map(|(_, server)| server.clone())
 4745            }),
 4746            LanguageServerToQuery::Other(id) => self
 4747                .language_server_for_local_buffer(buffer, id, cx)
 4748                .and_then(|(_, server)| {
 4749                    request
 4750                        .check_capabilities(server.adapter_server_capabilities())
 4751                        .then(|| Arc::clone(server))
 4752                }),
 4753        }) else {
 4754            return Task::ready(Ok(Default::default()));
 4755        };
 4756
 4757        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4758
 4759        let Some(file) = file else {
 4760            return Task::ready(Ok(Default::default()));
 4761        };
 4762
 4763        let lsp_params = match request.to_lsp_params_or_response(
 4764            &file.abs_path(cx),
 4765            buffer.read(cx),
 4766            &language_server,
 4767            cx,
 4768        ) {
 4769            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4770            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4771            Err(err) => {
 4772                let message = format!(
 4773                    "{} via {} failed: {}",
 4774                    request.display_name(),
 4775                    language_server.name(),
 4776                    err
 4777                );
 4778                // rust-analyzer likes to error with this when its still loading up
 4779                if !message.ends_with("content modified") {
 4780                    log::warn!("{message}");
 4781                }
 4782                return Task::ready(Err(anyhow!(message)));
 4783            }
 4784        };
 4785
 4786        let status = request.status();
 4787        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4788            return Task::ready(Ok(Default::default()));
 4789        }
 4790        cx.spawn(async move |this, cx| {
 4791            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4792
 4793            let id = lsp_request.id();
 4794            let _cleanup = if status.is_some() {
 4795                cx.update(|cx| {
 4796                    this.update(cx, |this, cx| {
 4797                        this.on_lsp_work_start(
 4798                            language_server.server_id(),
 4799                            ProgressToken::Number(id),
 4800                            LanguageServerProgress {
 4801                                is_disk_based_diagnostics_progress: false,
 4802                                is_cancellable: false,
 4803                                title: None,
 4804                                message: status.clone(),
 4805                                percentage: None,
 4806                                last_update_at: cx.background_executor().now(),
 4807                            },
 4808                            cx,
 4809                        );
 4810                    })
 4811                })
 4812                .log_err();
 4813
 4814                Some(defer(|| {
 4815                    cx.update(|cx| {
 4816                        this.update(cx, |this, cx| {
 4817                            this.on_lsp_work_end(
 4818                                language_server.server_id(),
 4819                                ProgressToken::Number(id),
 4820                                cx,
 4821                            );
 4822                        })
 4823                    })
 4824                    .log_err();
 4825                }))
 4826            } else {
 4827                None
 4828            };
 4829
 4830            let result = lsp_request.await.into_response();
 4831
 4832            let response = result.map_err(|err| {
 4833                let message = format!(
 4834                    "{} via {} failed: {}",
 4835                    request.display_name(),
 4836                    language_server.name(),
 4837                    err
 4838                );
 4839                // rust-analyzer likes to error with this when its still loading up
 4840                if !message.ends_with("content modified") {
 4841                    log::warn!("{message}");
 4842                }
 4843                anyhow::anyhow!(message)
 4844            })?;
 4845
 4846            request
 4847                .response_from_lsp(
 4848                    response,
 4849                    this.upgrade().context("no app context")?,
 4850                    buffer,
 4851                    language_server.server_id(),
 4852                    cx.clone(),
 4853                )
 4854                .await
 4855        })
 4856    }
 4857
 4858    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4859        let mut language_formatters_to_check = Vec::new();
 4860        for buffer in self.buffer_store.read(cx).buffers() {
 4861            let buffer = buffer.read(cx);
 4862            let buffer_file = File::from_dyn(buffer.file());
 4863            let buffer_language = buffer.language();
 4864            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4865            if buffer_language.is_some() {
 4866                language_formatters_to_check.push((
 4867                    buffer_file.map(|f| f.worktree_id(cx)),
 4868                    settings.into_owned(),
 4869                ));
 4870            }
 4871        }
 4872
 4873        self.request_workspace_config_refresh();
 4874
 4875        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4876            prettier_store.update(cx, |prettier_store, cx| {
 4877                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4878            })
 4879        }
 4880
 4881        cx.notify();
 4882    }
 4883
 4884    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4885        let buffer_store = self.buffer_store.clone();
 4886        let Some(local) = self.as_local_mut() else {
 4887            return;
 4888        };
 4889        let mut adapters = BTreeMap::default();
 4890        let get_adapter = {
 4891            let languages = local.languages.clone();
 4892            let environment = local.environment.clone();
 4893            let weak = local.weak.clone();
 4894            let worktree_store = local.worktree_store.clone();
 4895            let http_client = local.http_client.clone();
 4896            let fs = local.fs.clone();
 4897            move |worktree_id, cx: &mut App| {
 4898                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4899                Some(LocalLspAdapterDelegate::new(
 4900                    languages.clone(),
 4901                    &environment,
 4902                    weak.clone(),
 4903                    &worktree,
 4904                    http_client.clone(),
 4905                    fs.clone(),
 4906                    cx,
 4907                ))
 4908            }
 4909        };
 4910
 4911        let mut messages_to_report = Vec::new();
 4912        let (new_tree, to_stop) = {
 4913            let mut rebase = local.lsp_tree.rebase();
 4914            let buffers = buffer_store
 4915                .read(cx)
 4916                .buffers()
 4917                .filter_map(|buffer| {
 4918                    let raw_buffer = buffer.read(cx);
 4919                    if !local
 4920                        .registered_buffers
 4921                        .contains_key(&raw_buffer.remote_id())
 4922                    {
 4923                        return None;
 4924                    }
 4925                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4926                    let language = raw_buffer.language().cloned()?;
 4927                    Some((file, language, raw_buffer.remote_id()))
 4928                })
 4929                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4930            for (file, language, buffer_id) in buffers {
 4931                let worktree_id = file.worktree_id(cx);
 4932                let Some(worktree) = local
 4933                    .worktree_store
 4934                    .read(cx)
 4935                    .worktree_for_id(worktree_id, cx)
 4936                else {
 4937                    continue;
 4938                };
 4939
 4940                if let Some((_, apply)) = local.reuse_existing_language_server(
 4941                    rebase.server_tree(),
 4942                    &worktree,
 4943                    &language.name(),
 4944                    cx,
 4945                ) {
 4946                    (apply)(rebase.server_tree());
 4947                } else if let Some(lsp_delegate) = adapters
 4948                    .entry(worktree_id)
 4949                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4950                    .clone()
 4951                {
 4952                    let delegate =
 4953                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4954                    let path = file
 4955                        .path()
 4956                        .parent()
 4957                        .map(Arc::from)
 4958                        .unwrap_or_else(|| file.path().clone());
 4959                    let worktree_path = ProjectPath { worktree_id, path };
 4960                    let abs_path = file.abs_path(cx);
 4961                    let nodes = rebase
 4962                        .walk(
 4963                            worktree_path,
 4964                            language.name(),
 4965                            language.manifest(),
 4966                            delegate.clone(),
 4967                            cx,
 4968                        )
 4969                        .collect::<Vec<_>>();
 4970                    for node in nodes {
 4971                        let server_id = node.server_id_or_init(|disposition| {
 4972                            let path = &disposition.path;
 4973                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4974                            let key = LanguageServerSeed {
 4975                                worktree_id,
 4976                                name: disposition.server_name.clone(),
 4977                                settings: disposition.settings.clone(),
 4978                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4979                                    path.worktree_id,
 4980                                    &path.path,
 4981                                    language.name(),
 4982                                ),
 4983                            };
 4984                            local.language_server_ids.remove(&key);
 4985
 4986                            let server_id = local.get_or_insert_language_server(
 4987                                &worktree,
 4988                                lsp_delegate.clone(),
 4989                                disposition,
 4990                                &language.name(),
 4991                                cx,
 4992                            );
 4993                            if let Some(state) = local.language_servers.get(&server_id)
 4994                                && let Ok(uri) = uri
 4995                            {
 4996                                state.add_workspace_folder(uri);
 4997                            };
 4998                            server_id
 4999                        });
 5000
 5001                        if let Some(language_server_id) = server_id {
 5002                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5003                                language_server_id,
 5004                                name: node.name(),
 5005                                message:
 5006                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5007                                        proto::RegisteredForBuffer {
 5008                                            buffer_abs_path: abs_path
 5009                                                .to_string_lossy()
 5010                                                .into_owned(),
 5011                                            buffer_id: buffer_id.to_proto(),
 5012                                        },
 5013                                    ),
 5014                            });
 5015                        }
 5016                    }
 5017                } else {
 5018                    continue;
 5019                }
 5020            }
 5021            rebase.finish()
 5022        };
 5023        for message in messages_to_report {
 5024            cx.emit(message);
 5025        }
 5026        local.lsp_tree = new_tree;
 5027        for (id, _) in to_stop {
 5028            self.stop_local_language_server(id, cx).detach();
 5029        }
 5030    }
 5031
 5032    pub fn apply_code_action(
 5033        &self,
 5034        buffer_handle: Entity<Buffer>,
 5035        mut action: CodeAction,
 5036        push_to_history: bool,
 5037        cx: &mut Context<Self>,
 5038    ) -> Task<Result<ProjectTransaction>> {
 5039        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5040            let request = proto::ApplyCodeAction {
 5041                project_id,
 5042                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5043                action: Some(Self::serialize_code_action(&action)),
 5044            };
 5045            let buffer_store = self.buffer_store();
 5046            cx.spawn(async move |_, cx| {
 5047                let response = upstream_client
 5048                    .request(request)
 5049                    .await?
 5050                    .transaction
 5051                    .context("missing transaction")?;
 5052
 5053                buffer_store
 5054                    .update(cx, |buffer_store, cx| {
 5055                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5056                    })?
 5057                    .await
 5058            })
 5059        } else if self.mode.is_local() {
 5060            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 5061                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5062                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 5063            }) else {
 5064                return Task::ready(Ok(ProjectTransaction::default()));
 5065            };
 5066            cx.spawn(async move |this,  cx| {
 5067                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 5068                    .await
 5069                    .context("resolving a code action")?;
 5070                if let Some(edit) = action.lsp_action.edit()
 5071                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5072                        return LocalLspStore::deserialize_workspace_edit(
 5073                            this.upgrade().context("no app present")?,
 5074                            edit.clone(),
 5075                            push_to_history,
 5076
 5077                            lang_server.clone(),
 5078                            cx,
 5079                        )
 5080                        .await;
 5081                    }
 5082
 5083                if let Some(command) = action.lsp_action.command() {
 5084                    let server_capabilities = lang_server.capabilities();
 5085                    let available_commands = server_capabilities
 5086                        .execute_command_provider
 5087                        .as_ref()
 5088                        .map(|options| options.commands.as_slice())
 5089                        .unwrap_or_default();
 5090                    if available_commands.contains(&command.command) {
 5091                        this.update(cx, |this, _| {
 5092                            this.as_local_mut()
 5093                                .unwrap()
 5094                                .last_workspace_edits_by_language_server
 5095                                .remove(&lang_server.server_id());
 5096                        })?;
 5097
 5098                        let _result = lang_server
 5099                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5100                                command: command.command.clone(),
 5101                                arguments: command.arguments.clone().unwrap_or_default(),
 5102                                ..lsp::ExecuteCommandParams::default()
 5103                            })
 5104                            .await.into_response()
 5105                            .context("execute command")?;
 5106
 5107                        return this.update(cx, |this, _| {
 5108                            this.as_local_mut()
 5109                                .unwrap()
 5110                                .last_workspace_edits_by_language_server
 5111                                .remove(&lang_server.server_id())
 5112                                .unwrap_or_default()
 5113                        });
 5114                    } else {
 5115                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5116                    }
 5117                }
 5118
 5119                Ok(ProjectTransaction::default())
 5120            })
 5121        } else {
 5122            Task::ready(Err(anyhow!("no upstream client and not local")))
 5123        }
 5124    }
 5125
 5126    pub fn apply_code_action_kind(
 5127        &mut self,
 5128        buffers: HashSet<Entity<Buffer>>,
 5129        kind: CodeActionKind,
 5130        push_to_history: bool,
 5131        cx: &mut Context<Self>,
 5132    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5133        if self.as_local().is_some() {
 5134            cx.spawn(async move |lsp_store, cx| {
 5135                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5136                let result = LocalLspStore::execute_code_action_kind_locally(
 5137                    lsp_store.clone(),
 5138                    buffers,
 5139                    kind,
 5140                    push_to_history,
 5141                    cx,
 5142                )
 5143                .await;
 5144                lsp_store.update(cx, |lsp_store, _| {
 5145                    lsp_store.update_last_formatting_failure(&result);
 5146                })?;
 5147                result
 5148            })
 5149        } else if let Some((client, project_id)) = self.upstream_client() {
 5150            let buffer_store = self.buffer_store();
 5151            cx.spawn(async move |lsp_store, cx| {
 5152                let result = client
 5153                    .request(proto::ApplyCodeActionKind {
 5154                        project_id,
 5155                        kind: kind.as_str().to_owned(),
 5156                        buffer_ids: buffers
 5157                            .iter()
 5158                            .map(|buffer| {
 5159                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5160                            })
 5161                            .collect::<Result<_>>()?,
 5162                    })
 5163                    .await
 5164                    .and_then(|result| result.transaction.context("missing transaction"));
 5165                lsp_store.update(cx, |lsp_store, _| {
 5166                    lsp_store.update_last_formatting_failure(&result);
 5167                })?;
 5168
 5169                let transaction_response = result?;
 5170                buffer_store
 5171                    .update(cx, |buffer_store, cx| {
 5172                        buffer_store.deserialize_project_transaction(
 5173                            transaction_response,
 5174                            push_to_history,
 5175                            cx,
 5176                        )
 5177                    })?
 5178                    .await
 5179            })
 5180        } else {
 5181            Task::ready(Ok(ProjectTransaction::default()))
 5182        }
 5183    }
 5184
 5185    pub fn resolved_hint(
 5186        &mut self,
 5187        buffer_id: BufferId,
 5188        id: InlayId,
 5189        cx: &mut Context<Self>,
 5190    ) -> Option<ResolvedHint> {
 5191        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5192
 5193        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5194        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5195        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5196        let (server_id, resolve_data) = match &hint.resolve_state {
 5197            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5198            ResolveState::Resolving => {
 5199                return Some(ResolvedHint::Resolving(
 5200                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5201                ));
 5202            }
 5203            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5204        };
 5205
 5206        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5207        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5208        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5209            id,
 5210            cx.spawn(async move |lsp_store, cx| {
 5211                let resolved_hint = resolve_task.await;
 5212                lsp_store
 5213                    .update(cx, |lsp_store, _| {
 5214                        if let Some(old_inlay_hint) = lsp_store
 5215                            .lsp_data
 5216                            .get_mut(&buffer_id)
 5217                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5218                        {
 5219                            match resolved_hint {
 5220                                Ok(resolved_hint) => {
 5221                                    *old_inlay_hint = resolved_hint;
 5222                                }
 5223                                Err(e) => {
 5224                                    old_inlay_hint.resolve_state =
 5225                                        ResolveState::CanResolve(server_id, resolve_data);
 5226                                    log::error!("Inlay hint resolve failed: {e:#}");
 5227                                }
 5228                            }
 5229                        }
 5230                    })
 5231                    .ok();
 5232            })
 5233            .shared(),
 5234        );
 5235        debug_assert!(
 5236            previous_task.is_none(),
 5237            "Did not change hint's resolve state after spawning its resolve"
 5238        );
 5239        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5240        None
 5241    }
 5242
 5243    fn resolve_inlay_hint(
 5244        &self,
 5245        mut hint: InlayHint,
 5246        buffer: Entity<Buffer>,
 5247        server_id: LanguageServerId,
 5248        cx: &mut Context<Self>,
 5249    ) -> Task<anyhow::Result<InlayHint>> {
 5250        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5251            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5252            {
 5253                hint.resolve_state = ResolveState::Resolved;
 5254                return Task::ready(Ok(hint));
 5255            }
 5256            let request = proto::ResolveInlayHint {
 5257                project_id,
 5258                buffer_id: buffer.read(cx).remote_id().into(),
 5259                language_server_id: server_id.0 as u64,
 5260                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5261            };
 5262            cx.background_spawn(async move {
 5263                let response = upstream_client
 5264                    .request(request)
 5265                    .await
 5266                    .context("inlay hints proto request")?;
 5267                match response.hint {
 5268                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5269                        .context("inlay hints proto resolve response conversion"),
 5270                    None => Ok(hint),
 5271                }
 5272            })
 5273        } else {
 5274            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5275                self.language_server_for_local_buffer(buffer, server_id, cx)
 5276                    .map(|(_, server)| server.clone())
 5277            }) else {
 5278                return Task::ready(Ok(hint));
 5279            };
 5280            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5281                return Task::ready(Ok(hint));
 5282            }
 5283            let buffer_snapshot = buffer.read(cx).snapshot();
 5284            cx.spawn(async move |_, cx| {
 5285                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5286                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5287                );
 5288                let resolved_hint = resolve_task
 5289                    .await
 5290                    .into_response()
 5291                    .context("inlay hint resolve LSP request")?;
 5292                let resolved_hint = InlayHints::lsp_to_project_hint(
 5293                    resolved_hint,
 5294                    &buffer,
 5295                    server_id,
 5296                    ResolveState::Resolved,
 5297                    false,
 5298                    cx,
 5299                )
 5300                .await?;
 5301                Ok(resolved_hint)
 5302            })
 5303        }
 5304    }
 5305
 5306    pub fn resolve_color_presentation(
 5307        &mut self,
 5308        mut color: DocumentColor,
 5309        buffer: Entity<Buffer>,
 5310        server_id: LanguageServerId,
 5311        cx: &mut Context<Self>,
 5312    ) -> Task<Result<DocumentColor>> {
 5313        if color.resolved {
 5314            return Task::ready(Ok(color));
 5315        }
 5316
 5317        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5318            let start = color.lsp_range.start;
 5319            let end = color.lsp_range.end;
 5320            let request = proto::GetColorPresentation {
 5321                project_id,
 5322                server_id: server_id.to_proto(),
 5323                buffer_id: buffer.read(cx).remote_id().into(),
 5324                color: Some(proto::ColorInformation {
 5325                    red: color.color.red,
 5326                    green: color.color.green,
 5327                    blue: color.color.blue,
 5328                    alpha: color.color.alpha,
 5329                    lsp_range_start: Some(proto::PointUtf16 {
 5330                        row: start.line,
 5331                        column: start.character,
 5332                    }),
 5333                    lsp_range_end: Some(proto::PointUtf16 {
 5334                        row: end.line,
 5335                        column: end.character,
 5336                    }),
 5337                }),
 5338            };
 5339            cx.background_spawn(async move {
 5340                let response = upstream_client
 5341                    .request(request)
 5342                    .await
 5343                    .context("color presentation proto request")?;
 5344                color.resolved = true;
 5345                color.color_presentations = response
 5346                    .presentations
 5347                    .into_iter()
 5348                    .map(|presentation| ColorPresentation {
 5349                        label: SharedString::from(presentation.label),
 5350                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5351                        additional_text_edits: presentation
 5352                            .additional_text_edits
 5353                            .into_iter()
 5354                            .filter_map(deserialize_lsp_edit)
 5355                            .collect(),
 5356                    })
 5357                    .collect();
 5358                Ok(color)
 5359            })
 5360        } else {
 5361            let path = match buffer
 5362                .update(cx, |buffer, cx| {
 5363                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5364                })
 5365                .context("buffer with the missing path")
 5366            {
 5367                Ok(path) => path,
 5368                Err(e) => return Task::ready(Err(e)),
 5369            };
 5370            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5371                self.language_server_for_local_buffer(buffer, server_id, cx)
 5372                    .map(|(_, server)| server.clone())
 5373            }) else {
 5374                return Task::ready(Ok(color));
 5375            };
 5376            cx.background_spawn(async move {
 5377                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5378                    lsp::ColorPresentationParams {
 5379                        text_document: make_text_document_identifier(&path)?,
 5380                        color: color.color,
 5381                        range: color.lsp_range,
 5382                        work_done_progress_params: Default::default(),
 5383                        partial_result_params: Default::default(),
 5384                    },
 5385                );
 5386                color.color_presentations = resolve_task
 5387                    .await
 5388                    .into_response()
 5389                    .context("color presentation resolve LSP request")?
 5390                    .into_iter()
 5391                    .map(|presentation| ColorPresentation {
 5392                        label: SharedString::from(presentation.label),
 5393                        text_edit: presentation.text_edit,
 5394                        additional_text_edits: presentation
 5395                            .additional_text_edits
 5396                            .unwrap_or_default(),
 5397                    })
 5398                    .collect();
 5399                color.resolved = true;
 5400                Ok(color)
 5401            })
 5402        }
 5403    }
 5404
 5405    pub(crate) fn linked_edits(
 5406        &mut self,
 5407        buffer: &Entity<Buffer>,
 5408        position: Anchor,
 5409        cx: &mut Context<Self>,
 5410    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5411        let snapshot = buffer.read(cx).snapshot();
 5412        let scope = snapshot.language_scope_at(position);
 5413        let Some(server_id) = self
 5414            .as_local()
 5415            .and_then(|local| {
 5416                buffer.update(cx, |buffer, cx| {
 5417                    local
 5418                        .language_servers_for_buffer(buffer, cx)
 5419                        .filter(|(_, server)| {
 5420                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5421                        })
 5422                        .filter(|(adapter, _)| {
 5423                            scope
 5424                                .as_ref()
 5425                                .map(|scope| scope.language_allowed(&adapter.name))
 5426                                .unwrap_or(true)
 5427                        })
 5428                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5429                        .next()
 5430                })
 5431            })
 5432            .or_else(|| {
 5433                self.upstream_client()
 5434                    .is_some()
 5435                    .then_some(LanguageServerToQuery::FirstCapable)
 5436            })
 5437            .filter(|_| {
 5438                maybe!({
 5439                    let language = buffer.read(cx).language_at(position)?;
 5440                    Some(
 5441                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5442                            .linked_edits,
 5443                    )
 5444                }) == Some(true)
 5445            })
 5446        else {
 5447            return Task::ready(Ok(Vec::new()));
 5448        };
 5449
 5450        self.request_lsp(
 5451            buffer.clone(),
 5452            server_id,
 5453            LinkedEditingRange { position },
 5454            cx,
 5455        )
 5456    }
 5457
 5458    fn apply_on_type_formatting(
 5459        &mut self,
 5460        buffer: Entity<Buffer>,
 5461        position: Anchor,
 5462        trigger: String,
 5463        cx: &mut Context<Self>,
 5464    ) -> Task<Result<Option<Transaction>>> {
 5465        if let Some((client, project_id)) = self.upstream_client() {
 5466            if !self.check_if_capable_for_proto_request(
 5467                &buffer,
 5468                |capabilities| {
 5469                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5470                },
 5471                cx,
 5472            ) {
 5473                return Task::ready(Ok(None));
 5474            }
 5475            let request = proto::OnTypeFormatting {
 5476                project_id,
 5477                buffer_id: buffer.read(cx).remote_id().into(),
 5478                position: Some(serialize_anchor(&position)),
 5479                trigger,
 5480                version: serialize_version(&buffer.read(cx).version()),
 5481            };
 5482            cx.background_spawn(async move {
 5483                client
 5484                    .request(request)
 5485                    .await?
 5486                    .transaction
 5487                    .map(language::proto::deserialize_transaction)
 5488                    .transpose()
 5489            })
 5490        } else if let Some(local) = self.as_local_mut() {
 5491            let buffer_id = buffer.read(cx).remote_id();
 5492            local.buffers_being_formatted.insert(buffer_id);
 5493            cx.spawn(async move |this, cx| {
 5494                let _cleanup = defer({
 5495                    let this = this.clone();
 5496                    let mut cx = cx.clone();
 5497                    move || {
 5498                        this.update(&mut cx, |this, _| {
 5499                            if let Some(local) = this.as_local_mut() {
 5500                                local.buffers_being_formatted.remove(&buffer_id);
 5501                            }
 5502                        })
 5503                        .ok();
 5504                    }
 5505                });
 5506
 5507                buffer
 5508                    .update(cx, |buffer, _| {
 5509                        buffer.wait_for_edits(Some(position.timestamp))
 5510                    })?
 5511                    .await?;
 5512                this.update(cx, |this, cx| {
 5513                    let position = position.to_point_utf16(buffer.read(cx));
 5514                    this.on_type_format(buffer, position, trigger, false, cx)
 5515                })?
 5516                .await
 5517            })
 5518        } else {
 5519            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5520        }
 5521    }
 5522
 5523    pub fn on_type_format<T: ToPointUtf16>(
 5524        &mut self,
 5525        buffer: Entity<Buffer>,
 5526        position: T,
 5527        trigger: String,
 5528        push_to_history: bool,
 5529        cx: &mut Context<Self>,
 5530    ) -> Task<Result<Option<Transaction>>> {
 5531        let position = position.to_point_utf16(buffer.read(cx));
 5532        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5533    }
 5534
 5535    fn on_type_format_impl(
 5536        &mut self,
 5537        buffer: Entity<Buffer>,
 5538        position: PointUtf16,
 5539        trigger: String,
 5540        push_to_history: bool,
 5541        cx: &mut Context<Self>,
 5542    ) -> Task<Result<Option<Transaction>>> {
 5543        let options = buffer.update(cx, |buffer, cx| {
 5544            lsp_command::lsp_formatting_options(
 5545                language_settings(
 5546                    buffer.language_at(position).map(|l| l.name()),
 5547                    buffer.file(),
 5548                    cx,
 5549                )
 5550                .as_ref(),
 5551            )
 5552        });
 5553
 5554        cx.spawn(async move |this, cx| {
 5555            if let Some(waiter) =
 5556                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5557            {
 5558                waiter.await?;
 5559            }
 5560            cx.update(|cx| {
 5561                this.update(cx, |this, cx| {
 5562                    this.request_lsp(
 5563                        buffer.clone(),
 5564                        LanguageServerToQuery::FirstCapable,
 5565                        OnTypeFormatting {
 5566                            position,
 5567                            trigger,
 5568                            options,
 5569                            push_to_history,
 5570                        },
 5571                        cx,
 5572                    )
 5573                })
 5574            })??
 5575            .await
 5576        })
 5577    }
 5578
 5579    pub fn definitions(
 5580        &mut self,
 5581        buffer: &Entity<Buffer>,
 5582        position: PointUtf16,
 5583        cx: &mut Context<Self>,
 5584    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5585        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5586            let request = GetDefinitions { position };
 5587            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5588                return Task::ready(Ok(None));
 5589            }
 5590            let request_task = upstream_client.request_lsp(
 5591                project_id,
 5592                None,
 5593                LSP_REQUEST_TIMEOUT,
 5594                cx.background_executor().clone(),
 5595                request.to_proto(project_id, buffer.read(cx)),
 5596            );
 5597            let buffer = buffer.clone();
 5598            cx.spawn(async move |weak_lsp_store, cx| {
 5599                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5600                    return Ok(None);
 5601                };
 5602                let Some(responses) = request_task.await? else {
 5603                    return Ok(None);
 5604                };
 5605                let actions = join_all(responses.payload.into_iter().map(|response| {
 5606                    GetDefinitions { position }.response_from_proto(
 5607                        response.response,
 5608                        lsp_store.clone(),
 5609                        buffer.clone(),
 5610                        cx.clone(),
 5611                    )
 5612                }))
 5613                .await;
 5614
 5615                Ok(Some(
 5616                    actions
 5617                        .into_iter()
 5618                        .collect::<Result<Vec<Vec<_>>>>()?
 5619                        .into_iter()
 5620                        .flatten()
 5621                        .dedup()
 5622                        .collect(),
 5623                ))
 5624            })
 5625        } else {
 5626            let definitions_task = self.request_multiple_lsp_locally(
 5627                buffer,
 5628                Some(position),
 5629                GetDefinitions { position },
 5630                cx,
 5631            );
 5632            cx.background_spawn(async move {
 5633                Ok(Some(
 5634                    definitions_task
 5635                        .await
 5636                        .into_iter()
 5637                        .flat_map(|(_, definitions)| definitions)
 5638                        .dedup()
 5639                        .collect(),
 5640                ))
 5641            })
 5642        }
 5643    }
 5644
 5645    pub fn declarations(
 5646        &mut self,
 5647        buffer: &Entity<Buffer>,
 5648        position: PointUtf16,
 5649        cx: &mut Context<Self>,
 5650    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5651        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5652            let request = GetDeclarations { position };
 5653            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5654                return Task::ready(Ok(None));
 5655            }
 5656            let request_task = upstream_client.request_lsp(
 5657                project_id,
 5658                None,
 5659                LSP_REQUEST_TIMEOUT,
 5660                cx.background_executor().clone(),
 5661                request.to_proto(project_id, buffer.read(cx)),
 5662            );
 5663            let buffer = buffer.clone();
 5664            cx.spawn(async move |weak_lsp_store, cx| {
 5665                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5666                    return Ok(None);
 5667                };
 5668                let Some(responses) = request_task.await? else {
 5669                    return Ok(None);
 5670                };
 5671                let actions = join_all(responses.payload.into_iter().map(|response| {
 5672                    GetDeclarations { position }.response_from_proto(
 5673                        response.response,
 5674                        lsp_store.clone(),
 5675                        buffer.clone(),
 5676                        cx.clone(),
 5677                    )
 5678                }))
 5679                .await;
 5680
 5681                Ok(Some(
 5682                    actions
 5683                        .into_iter()
 5684                        .collect::<Result<Vec<Vec<_>>>>()?
 5685                        .into_iter()
 5686                        .flatten()
 5687                        .dedup()
 5688                        .collect(),
 5689                ))
 5690            })
 5691        } else {
 5692            let declarations_task = self.request_multiple_lsp_locally(
 5693                buffer,
 5694                Some(position),
 5695                GetDeclarations { position },
 5696                cx,
 5697            );
 5698            cx.background_spawn(async move {
 5699                Ok(Some(
 5700                    declarations_task
 5701                        .await
 5702                        .into_iter()
 5703                        .flat_map(|(_, declarations)| declarations)
 5704                        .dedup()
 5705                        .collect(),
 5706                ))
 5707            })
 5708        }
 5709    }
 5710
 5711    pub fn type_definitions(
 5712        &mut self,
 5713        buffer: &Entity<Buffer>,
 5714        position: PointUtf16,
 5715        cx: &mut Context<Self>,
 5716    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5717        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5718            let request = GetTypeDefinitions { position };
 5719            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5720                return Task::ready(Ok(None));
 5721            }
 5722            let request_task = upstream_client.request_lsp(
 5723                project_id,
 5724                None,
 5725                LSP_REQUEST_TIMEOUT,
 5726                cx.background_executor().clone(),
 5727                request.to_proto(project_id, buffer.read(cx)),
 5728            );
 5729            let buffer = buffer.clone();
 5730            cx.spawn(async move |weak_lsp_store, cx| {
 5731                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5732                    return Ok(None);
 5733                };
 5734                let Some(responses) = request_task.await? else {
 5735                    return Ok(None);
 5736                };
 5737                let actions = join_all(responses.payload.into_iter().map(|response| {
 5738                    GetTypeDefinitions { position }.response_from_proto(
 5739                        response.response,
 5740                        lsp_store.clone(),
 5741                        buffer.clone(),
 5742                        cx.clone(),
 5743                    )
 5744                }))
 5745                .await;
 5746
 5747                Ok(Some(
 5748                    actions
 5749                        .into_iter()
 5750                        .collect::<Result<Vec<Vec<_>>>>()?
 5751                        .into_iter()
 5752                        .flatten()
 5753                        .dedup()
 5754                        .collect(),
 5755                ))
 5756            })
 5757        } else {
 5758            let type_definitions_task = self.request_multiple_lsp_locally(
 5759                buffer,
 5760                Some(position),
 5761                GetTypeDefinitions { position },
 5762                cx,
 5763            );
 5764            cx.background_spawn(async move {
 5765                Ok(Some(
 5766                    type_definitions_task
 5767                        .await
 5768                        .into_iter()
 5769                        .flat_map(|(_, type_definitions)| type_definitions)
 5770                        .dedup()
 5771                        .collect(),
 5772                ))
 5773            })
 5774        }
 5775    }
 5776
 5777    pub fn implementations(
 5778        &mut self,
 5779        buffer: &Entity<Buffer>,
 5780        position: PointUtf16,
 5781        cx: &mut Context<Self>,
 5782    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5783        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5784            let request = GetImplementations { position };
 5785            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5786                return Task::ready(Ok(None));
 5787            }
 5788            let request_task = upstream_client.request_lsp(
 5789                project_id,
 5790                None,
 5791                LSP_REQUEST_TIMEOUT,
 5792                cx.background_executor().clone(),
 5793                request.to_proto(project_id, buffer.read(cx)),
 5794            );
 5795            let buffer = buffer.clone();
 5796            cx.spawn(async move |weak_lsp_store, cx| {
 5797                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5798                    return Ok(None);
 5799                };
 5800                let Some(responses) = request_task.await? else {
 5801                    return Ok(None);
 5802                };
 5803                let actions = join_all(responses.payload.into_iter().map(|response| {
 5804                    GetImplementations { position }.response_from_proto(
 5805                        response.response,
 5806                        lsp_store.clone(),
 5807                        buffer.clone(),
 5808                        cx.clone(),
 5809                    )
 5810                }))
 5811                .await;
 5812
 5813                Ok(Some(
 5814                    actions
 5815                        .into_iter()
 5816                        .collect::<Result<Vec<Vec<_>>>>()?
 5817                        .into_iter()
 5818                        .flatten()
 5819                        .dedup()
 5820                        .collect(),
 5821                ))
 5822            })
 5823        } else {
 5824            let implementations_task = self.request_multiple_lsp_locally(
 5825                buffer,
 5826                Some(position),
 5827                GetImplementations { position },
 5828                cx,
 5829            );
 5830            cx.background_spawn(async move {
 5831                Ok(Some(
 5832                    implementations_task
 5833                        .await
 5834                        .into_iter()
 5835                        .flat_map(|(_, implementations)| implementations)
 5836                        .dedup()
 5837                        .collect(),
 5838                ))
 5839            })
 5840        }
 5841    }
 5842
 5843    pub fn references(
 5844        &mut self,
 5845        buffer: &Entity<Buffer>,
 5846        position: PointUtf16,
 5847        cx: &mut Context<Self>,
 5848    ) -> Task<Result<Option<Vec<Location>>>> {
 5849        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5850            let request = GetReferences { position };
 5851            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5852                return Task::ready(Ok(None));
 5853            }
 5854
 5855            let request_task = upstream_client.request_lsp(
 5856                project_id,
 5857                None,
 5858                LSP_REQUEST_TIMEOUT,
 5859                cx.background_executor().clone(),
 5860                request.to_proto(project_id, buffer.read(cx)),
 5861            );
 5862            let buffer = buffer.clone();
 5863            cx.spawn(async move |weak_lsp_store, cx| {
 5864                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5865                    return Ok(None);
 5866                };
 5867                let Some(responses) = request_task.await? else {
 5868                    return Ok(None);
 5869                };
 5870
 5871                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5872                    GetReferences { position }.response_from_proto(
 5873                        lsp_response.response,
 5874                        lsp_store.clone(),
 5875                        buffer.clone(),
 5876                        cx.clone(),
 5877                    )
 5878                }))
 5879                .await
 5880                .into_iter()
 5881                .collect::<Result<Vec<Vec<_>>>>()?
 5882                .into_iter()
 5883                .flatten()
 5884                .dedup()
 5885                .collect();
 5886                Ok(Some(locations))
 5887            })
 5888        } else {
 5889            let references_task = self.request_multiple_lsp_locally(
 5890                buffer,
 5891                Some(position),
 5892                GetReferences { position },
 5893                cx,
 5894            );
 5895            cx.background_spawn(async move {
 5896                Ok(Some(
 5897                    references_task
 5898                        .await
 5899                        .into_iter()
 5900                        .flat_map(|(_, references)| references)
 5901                        .dedup()
 5902                        .collect(),
 5903                ))
 5904            })
 5905        }
 5906    }
 5907
 5908    pub fn code_actions(
 5909        &mut self,
 5910        buffer: &Entity<Buffer>,
 5911        range: Range<Anchor>,
 5912        kinds: Option<Vec<CodeActionKind>>,
 5913        cx: &mut Context<Self>,
 5914    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5915        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5916            let request = GetCodeActions {
 5917                range: range.clone(),
 5918                kinds: kinds.clone(),
 5919            };
 5920            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5921                return Task::ready(Ok(None));
 5922            }
 5923            let request_task = upstream_client.request_lsp(
 5924                project_id,
 5925                None,
 5926                LSP_REQUEST_TIMEOUT,
 5927                cx.background_executor().clone(),
 5928                request.to_proto(project_id, buffer.read(cx)),
 5929            );
 5930            let buffer = buffer.clone();
 5931            cx.spawn(async move |weak_lsp_store, cx| {
 5932                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5933                    return Ok(None);
 5934                };
 5935                let Some(responses) = request_task.await? else {
 5936                    return Ok(None);
 5937                };
 5938                let actions = join_all(responses.payload.into_iter().map(|response| {
 5939                    GetCodeActions {
 5940                        range: range.clone(),
 5941                        kinds: kinds.clone(),
 5942                    }
 5943                    .response_from_proto(
 5944                        response.response,
 5945                        lsp_store.clone(),
 5946                        buffer.clone(),
 5947                        cx.clone(),
 5948                    )
 5949                }))
 5950                .await;
 5951
 5952                Ok(Some(
 5953                    actions
 5954                        .into_iter()
 5955                        .collect::<Result<Vec<Vec<_>>>>()?
 5956                        .into_iter()
 5957                        .flatten()
 5958                        .collect(),
 5959                ))
 5960            })
 5961        } else {
 5962            let all_actions_task = self.request_multiple_lsp_locally(
 5963                buffer,
 5964                Some(range.start),
 5965                GetCodeActions { range, kinds },
 5966                cx,
 5967            );
 5968            cx.background_spawn(async move {
 5969                Ok(Some(
 5970                    all_actions_task
 5971                        .await
 5972                        .into_iter()
 5973                        .flat_map(|(_, actions)| actions)
 5974                        .collect(),
 5975                ))
 5976            })
 5977        }
 5978    }
 5979
 5980    pub fn code_lens_actions(
 5981        &mut self,
 5982        buffer: &Entity<Buffer>,
 5983        cx: &mut Context<Self>,
 5984    ) -> CodeLensTask {
 5985        let version_queried_for = buffer.read(cx).version();
 5986        let buffer_id = buffer.read(cx).remote_id();
 5987        let existing_servers = self.as_local().map(|local| {
 5988            local
 5989                .buffers_opened_in_servers
 5990                .get(&buffer_id)
 5991                .cloned()
 5992                .unwrap_or_default()
 5993        });
 5994
 5995        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 5996            if let Some(cached_lens) = &lsp_data.code_lens {
 5997                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 5998                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 5999                        existing_servers != cached_lens.lens.keys().copied().collect()
 6000                    });
 6001                    if !has_different_servers {
 6002                        return Task::ready(Ok(Some(
 6003                            cached_lens.lens.values().flatten().cloned().collect(),
 6004                        )))
 6005                        .shared();
 6006                    }
 6007                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 6008                    if !version_queried_for.changed_since(updating_for) {
 6009                        return running_update.clone();
 6010                    }
 6011                }
 6012            }
 6013        }
 6014
 6015        let lens_lsp_data = self
 6016            .latest_lsp_data(buffer, cx)
 6017            .code_lens
 6018            .get_or_insert_default();
 6019        let buffer = buffer.clone();
 6020        let query_version_queried_for = version_queried_for.clone();
 6021        let new_task = cx
 6022            .spawn(async move |lsp_store, cx| {
 6023                cx.background_executor()
 6024                    .timer(Duration::from_millis(30))
 6025                    .await;
 6026                let fetched_lens = lsp_store
 6027                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 6028                    .map_err(Arc::new)?
 6029                    .await
 6030                    .context("fetching code lens")
 6031                    .map_err(Arc::new);
 6032                let fetched_lens = match fetched_lens {
 6033                    Ok(fetched_lens) => fetched_lens,
 6034                    Err(e) => {
 6035                        lsp_store
 6036                            .update(cx, |lsp_store, _| {
 6037                                if let Some(lens_lsp_data) = lsp_store
 6038                                    .lsp_data
 6039                                    .get_mut(&buffer_id)
 6040                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 6041                                {
 6042                                    lens_lsp_data.update = None;
 6043                                }
 6044                            })
 6045                            .ok();
 6046                        return Err(e);
 6047                    }
 6048                };
 6049
 6050                lsp_store
 6051                    .update(cx, |lsp_store, _| {
 6052                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 6053                        let code_lens = lsp_data.code_lens.as_mut()?;
 6054                        if let Some(fetched_lens) = fetched_lens {
 6055                            if lsp_data.buffer_version == query_version_queried_for {
 6056                                code_lens.lens.extend(fetched_lens);
 6057                            } else if !lsp_data
 6058                                .buffer_version
 6059                                .changed_since(&query_version_queried_for)
 6060                            {
 6061                                lsp_data.buffer_version = query_version_queried_for;
 6062                                code_lens.lens = fetched_lens;
 6063                            }
 6064                        }
 6065                        code_lens.update = None;
 6066                        Some(code_lens.lens.values().flatten().cloned().collect())
 6067                    })
 6068                    .map_err(Arc::new)
 6069            })
 6070            .shared();
 6071        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 6072        new_task
 6073    }
 6074
 6075    fn fetch_code_lens(
 6076        &mut self,
 6077        buffer: &Entity<Buffer>,
 6078        cx: &mut Context<Self>,
 6079    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 6080        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6081            let request = GetCodeLens;
 6082            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6083                return Task::ready(Ok(None));
 6084            }
 6085            let request_task = upstream_client.request_lsp(
 6086                project_id,
 6087                None,
 6088                LSP_REQUEST_TIMEOUT,
 6089                cx.background_executor().clone(),
 6090                request.to_proto(project_id, buffer.read(cx)),
 6091            );
 6092            let buffer = buffer.clone();
 6093            cx.spawn(async move |weak_lsp_store, cx| {
 6094                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6095                    return Ok(None);
 6096                };
 6097                let Some(responses) = request_task.await? else {
 6098                    return Ok(None);
 6099                };
 6100
 6101                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 6102                    let lsp_store = lsp_store.clone();
 6103                    let buffer = buffer.clone();
 6104                    let cx = cx.clone();
 6105                    async move {
 6106                        (
 6107                            LanguageServerId::from_proto(response.server_id),
 6108                            GetCodeLens
 6109                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6110                                .await,
 6111                        )
 6112                    }
 6113                }))
 6114                .await;
 6115
 6116                let mut has_errors = false;
 6117                let code_lens_actions = code_lens_actions
 6118                    .into_iter()
 6119                    .filter_map(|(server_id, code_lens)| match code_lens {
 6120                        Ok(code_lens) => Some((server_id, code_lens)),
 6121                        Err(e) => {
 6122                            has_errors = true;
 6123                            log::error!("{e:#}");
 6124                            None
 6125                        }
 6126                    })
 6127                    .collect::<HashMap<_, _>>();
 6128                anyhow::ensure!(
 6129                    !has_errors || !code_lens_actions.is_empty(),
 6130                    "Failed to fetch code lens"
 6131                );
 6132                Ok(Some(code_lens_actions))
 6133            })
 6134        } else {
 6135            let code_lens_actions_task =
 6136                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 6137            cx.background_spawn(async move {
 6138                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 6139            })
 6140        }
 6141    }
 6142
 6143    #[inline(never)]
 6144    pub fn completions(
 6145        &self,
 6146        buffer: &Entity<Buffer>,
 6147        position: PointUtf16,
 6148        context: CompletionContext,
 6149        cx: &mut Context<Self>,
 6150    ) -> Task<Result<Vec<CompletionResponse>>> {
 6151        let language_registry = self.languages.clone();
 6152
 6153        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6154            let snapshot = buffer.read(cx).snapshot();
 6155            let offset = position.to_offset(&snapshot);
 6156            let scope = snapshot.language_scope_at(offset);
 6157            let capable_lsps = self.all_capable_for_proto_request(
 6158                buffer,
 6159                |server_name, capabilities| {
 6160                    capabilities.completion_provider.is_some()
 6161                        && scope
 6162                            .as_ref()
 6163                            .map(|scope| scope.language_allowed(server_name))
 6164                            .unwrap_or(true)
 6165                },
 6166                cx,
 6167            );
 6168            if capable_lsps.is_empty() {
 6169                return Task::ready(Ok(Vec::new()));
 6170            }
 6171
 6172            let language = buffer.read(cx).language().cloned();
 6173
 6174            // In the future, we should provide project guests with the names of LSP adapters,
 6175            // so that they can use the correct LSP adapter when computing labels. For now,
 6176            // guests just use the first LSP adapter associated with the buffer's language.
 6177            let lsp_adapter = language.as_ref().and_then(|language| {
 6178                language_registry
 6179                    .lsp_adapters(&language.name())
 6180                    .first()
 6181                    .cloned()
 6182            });
 6183
 6184            let buffer = buffer.clone();
 6185
 6186            cx.spawn(async move |this, cx| {
 6187                let requests = join_all(
 6188                    capable_lsps
 6189                        .into_iter()
 6190                        .map(|id| {
 6191                            let request = GetCompletions {
 6192                                position,
 6193                                context: context.clone(),
 6194                                server_id: Some(id),
 6195                            };
 6196                            let buffer = buffer.clone();
 6197                            let language = language.clone();
 6198                            let lsp_adapter = lsp_adapter.clone();
 6199                            let upstream_client = upstream_client.clone();
 6200                            let response = this
 6201                                .update(cx, |this, cx| {
 6202                                    this.send_lsp_proto_request(
 6203                                        buffer,
 6204                                        upstream_client,
 6205                                        project_id,
 6206                                        request,
 6207                                        cx,
 6208                                    )
 6209                                })
 6210                                .log_err();
 6211                            async move {
 6212                                let response = response?.await.log_err()?;
 6213
 6214                                let completions = populate_labels_for_completions(
 6215                                    response.completions,
 6216                                    language,
 6217                                    lsp_adapter,
 6218                                )
 6219                                .await;
 6220
 6221                                Some(CompletionResponse {
 6222                                    completions,
 6223                                    display_options: CompletionDisplayOptions::default(),
 6224                                    is_incomplete: response.is_incomplete,
 6225                                })
 6226                            }
 6227                        })
 6228                        .collect::<Vec<_>>(),
 6229                );
 6230                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6231            })
 6232        } else if let Some(local) = self.as_local() {
 6233            let snapshot = buffer.read(cx).snapshot();
 6234            let offset = position.to_offset(&snapshot);
 6235            let scope = snapshot.language_scope_at(offset);
 6236            let language = snapshot.language().cloned();
 6237            let completion_settings = language_settings(
 6238                language.as_ref().map(|language| language.name()),
 6239                buffer.read(cx).file(),
 6240                cx,
 6241            )
 6242            .completions
 6243            .clone();
 6244            if !completion_settings.lsp {
 6245                return Task::ready(Ok(Vec::new()));
 6246            }
 6247
 6248            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6249                local
 6250                    .language_servers_for_buffer(buffer, cx)
 6251                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6252                    .filter(|(adapter, _)| {
 6253                        scope
 6254                            .as_ref()
 6255                            .map(|scope| scope.language_allowed(&adapter.name))
 6256                            .unwrap_or(true)
 6257                    })
 6258                    .map(|(_, server)| server.server_id())
 6259                    .collect()
 6260            });
 6261
 6262            let buffer = buffer.clone();
 6263            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6264            let lsp_timeout = if lsp_timeout > 0 {
 6265                Some(Duration::from_millis(lsp_timeout))
 6266            } else {
 6267                None
 6268            };
 6269            cx.spawn(async move |this,  cx| {
 6270                let mut tasks = Vec::with_capacity(server_ids.len());
 6271                this.update(cx, |lsp_store, cx| {
 6272                    for server_id in server_ids {
 6273                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6274                        let lsp_timeout = lsp_timeout
 6275                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6276                        let mut timeout = cx.background_spawn(async move {
 6277                            match lsp_timeout {
 6278                                Some(lsp_timeout) => {
 6279                                    lsp_timeout.await;
 6280                                    true
 6281                                },
 6282                                None => false,
 6283                            }
 6284                        }).fuse();
 6285                        let mut lsp_request = lsp_store.request_lsp(
 6286                            buffer.clone(),
 6287                            LanguageServerToQuery::Other(server_id),
 6288                            GetCompletions {
 6289                                position,
 6290                                context: context.clone(),
 6291                                server_id: Some(server_id),
 6292                            },
 6293                            cx,
 6294                        ).fuse();
 6295                        let new_task = cx.background_spawn(async move {
 6296                            select_biased! {
 6297                                response = lsp_request => anyhow::Ok(Some(response?)),
 6298                                timeout_happened = timeout => {
 6299                                    if timeout_happened {
 6300                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6301                                        Ok(None)
 6302                                    } else {
 6303                                        let completions = lsp_request.await?;
 6304                                        Ok(Some(completions))
 6305                                    }
 6306                                },
 6307                            }
 6308                        });
 6309                        tasks.push((lsp_adapter, new_task));
 6310                    }
 6311                })?;
 6312
 6313                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6314                    let completion_response = task.await.ok()??;
 6315                    let completions = populate_labels_for_completions(
 6316                            completion_response.completions,
 6317                            language.clone(),
 6318                            lsp_adapter,
 6319                        )
 6320                        .await;
 6321                    Some(CompletionResponse {
 6322                        completions,
 6323                        display_options: CompletionDisplayOptions::default(),
 6324                        is_incomplete: completion_response.is_incomplete,
 6325                    })
 6326                });
 6327
 6328                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6329
 6330                Ok(responses.into_iter().flatten().collect())
 6331            })
 6332        } else {
 6333            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6334        }
 6335    }
 6336
 6337    pub fn resolve_completions(
 6338        &self,
 6339        buffer: Entity<Buffer>,
 6340        completion_indices: Vec<usize>,
 6341        completions: Rc<RefCell<Box<[Completion]>>>,
 6342        cx: &mut Context<Self>,
 6343    ) -> Task<Result<bool>> {
 6344        let client = self.upstream_client();
 6345        let buffer_id = buffer.read(cx).remote_id();
 6346        let buffer_snapshot = buffer.read(cx).snapshot();
 6347
 6348        if !self.check_if_capable_for_proto_request(
 6349            &buffer,
 6350            GetCompletions::can_resolve_completions,
 6351            cx,
 6352        ) {
 6353            return Task::ready(Ok(false));
 6354        }
 6355        cx.spawn(async move |lsp_store, cx| {
 6356            let mut did_resolve = false;
 6357            if let Some((client, project_id)) = client {
 6358                for completion_index in completion_indices {
 6359                    let server_id = {
 6360                        let completion = &completions.borrow()[completion_index];
 6361                        completion.source.server_id()
 6362                    };
 6363                    if let Some(server_id) = server_id {
 6364                        if Self::resolve_completion_remote(
 6365                            project_id,
 6366                            server_id,
 6367                            buffer_id,
 6368                            completions.clone(),
 6369                            completion_index,
 6370                            client.clone(),
 6371                        )
 6372                        .await
 6373                        .log_err()
 6374                        .is_some()
 6375                        {
 6376                            did_resolve = true;
 6377                        }
 6378                    } else {
 6379                        resolve_word_completion(
 6380                            &buffer_snapshot,
 6381                            &mut completions.borrow_mut()[completion_index],
 6382                        );
 6383                    }
 6384                }
 6385            } else {
 6386                for completion_index in completion_indices {
 6387                    let server_id = {
 6388                        let completion = &completions.borrow()[completion_index];
 6389                        completion.source.server_id()
 6390                    };
 6391                    if let Some(server_id) = server_id {
 6392                        let server_and_adapter = lsp_store
 6393                            .read_with(cx, |lsp_store, _| {
 6394                                let server = lsp_store.language_server_for_id(server_id)?;
 6395                                let adapter =
 6396                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6397                                Some((server, adapter))
 6398                            })
 6399                            .ok()
 6400                            .flatten();
 6401                        let Some((server, adapter)) = server_and_adapter else {
 6402                            continue;
 6403                        };
 6404
 6405                        let resolved = Self::resolve_completion_local(
 6406                            server,
 6407                            completions.clone(),
 6408                            completion_index,
 6409                        )
 6410                        .await
 6411                        .log_err()
 6412                        .is_some();
 6413                        if resolved {
 6414                            Self::regenerate_completion_labels(
 6415                                adapter,
 6416                                &buffer_snapshot,
 6417                                completions.clone(),
 6418                                completion_index,
 6419                            )
 6420                            .await
 6421                            .log_err();
 6422                            did_resolve = true;
 6423                        }
 6424                    } else {
 6425                        resolve_word_completion(
 6426                            &buffer_snapshot,
 6427                            &mut completions.borrow_mut()[completion_index],
 6428                        );
 6429                    }
 6430                }
 6431            }
 6432
 6433            Ok(did_resolve)
 6434        })
 6435    }
 6436
 6437    async fn resolve_completion_local(
 6438        server: Arc<lsp::LanguageServer>,
 6439        completions: Rc<RefCell<Box<[Completion]>>>,
 6440        completion_index: usize,
 6441    ) -> Result<()> {
 6442        let server_id = server.server_id();
 6443        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6444            return Ok(());
 6445        }
 6446
 6447        let request = {
 6448            let completion = &completions.borrow()[completion_index];
 6449            match &completion.source {
 6450                CompletionSource::Lsp {
 6451                    lsp_completion,
 6452                    resolved,
 6453                    server_id: completion_server_id,
 6454                    ..
 6455                } => {
 6456                    if *resolved {
 6457                        return Ok(());
 6458                    }
 6459                    anyhow::ensure!(
 6460                        server_id == *completion_server_id,
 6461                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6462                    );
 6463                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6464                }
 6465                CompletionSource::BufferWord { .. }
 6466                | CompletionSource::Dap { .. }
 6467                | CompletionSource::Custom => {
 6468                    return Ok(());
 6469                }
 6470            }
 6471        };
 6472        let resolved_completion = request
 6473            .await
 6474            .into_response()
 6475            .context("resolve completion")?;
 6476
 6477        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6478        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6479
 6480        let mut completions = completions.borrow_mut();
 6481        let completion = &mut completions[completion_index];
 6482        if let CompletionSource::Lsp {
 6483            lsp_completion,
 6484            resolved,
 6485            server_id: completion_server_id,
 6486            ..
 6487        } = &mut completion.source
 6488        {
 6489            if *resolved {
 6490                return Ok(());
 6491            }
 6492            anyhow::ensure!(
 6493                server_id == *completion_server_id,
 6494                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6495            );
 6496            **lsp_completion = resolved_completion;
 6497            *resolved = true;
 6498        }
 6499        Ok(())
 6500    }
 6501
 6502    async fn regenerate_completion_labels(
 6503        adapter: Arc<CachedLspAdapter>,
 6504        snapshot: &BufferSnapshot,
 6505        completions: Rc<RefCell<Box<[Completion]>>>,
 6506        completion_index: usize,
 6507    ) -> Result<()> {
 6508        let completion_item = completions.borrow()[completion_index]
 6509            .source
 6510            .lsp_completion(true)
 6511            .map(Cow::into_owned);
 6512        if let Some(lsp_documentation) = completion_item
 6513            .as_ref()
 6514            .and_then(|completion_item| completion_item.documentation.clone())
 6515        {
 6516            let mut completions = completions.borrow_mut();
 6517            let completion = &mut completions[completion_index];
 6518            completion.documentation = Some(lsp_documentation.into());
 6519        } else {
 6520            let mut completions = completions.borrow_mut();
 6521            let completion = &mut completions[completion_index];
 6522            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6523        }
 6524
 6525        let mut new_label = match completion_item {
 6526            Some(completion_item) => {
 6527                // NB: Zed does not have `details` inside the completion resolve capabilities, but certain language servers violate the spec and do not return `details` immediately, e.g. https://github.com/yioneko/vtsls/issues/213
 6528                // So we have to update the label here anyway...
 6529                let language = snapshot.language();
 6530                match language {
 6531                    Some(language) => {
 6532                        adapter
 6533                            .labels_for_completions(
 6534                                std::slice::from_ref(&completion_item),
 6535                                language,
 6536                            )
 6537                            .await?
 6538                    }
 6539                    None => Vec::new(),
 6540                }
 6541                .pop()
 6542                .flatten()
 6543                .unwrap_or_else(|| {
 6544                    CodeLabel::fallback_for_completion(
 6545                        &completion_item,
 6546                        language.map(|language| language.as_ref()),
 6547                    )
 6548                })
 6549            }
 6550            None => CodeLabel::plain(
 6551                completions.borrow()[completion_index].new_text.clone(),
 6552                None,
 6553            ),
 6554        };
 6555        ensure_uniform_list_compatible_label(&mut new_label);
 6556
 6557        let mut completions = completions.borrow_mut();
 6558        let completion = &mut completions[completion_index];
 6559        if completion.label.filter_text() == new_label.filter_text() {
 6560            completion.label = new_label;
 6561        } else {
 6562            log::error!(
 6563                "Resolved completion changed display label from {} to {}. \
 6564                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6565                completion.label.text(),
 6566                new_label.text(),
 6567                completion.label.filter_text(),
 6568                new_label.filter_text()
 6569            );
 6570        }
 6571
 6572        Ok(())
 6573    }
 6574
 6575    async fn resolve_completion_remote(
 6576        project_id: u64,
 6577        server_id: LanguageServerId,
 6578        buffer_id: BufferId,
 6579        completions: Rc<RefCell<Box<[Completion]>>>,
 6580        completion_index: usize,
 6581        client: AnyProtoClient,
 6582    ) -> Result<()> {
 6583        let lsp_completion = {
 6584            let completion = &completions.borrow()[completion_index];
 6585            match &completion.source {
 6586                CompletionSource::Lsp {
 6587                    lsp_completion,
 6588                    resolved,
 6589                    server_id: completion_server_id,
 6590                    ..
 6591                } => {
 6592                    anyhow::ensure!(
 6593                        server_id == *completion_server_id,
 6594                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6595                    );
 6596                    if *resolved {
 6597                        return Ok(());
 6598                    }
 6599                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6600                }
 6601                CompletionSource::Custom
 6602                | CompletionSource::Dap { .. }
 6603                | CompletionSource::BufferWord { .. } => {
 6604                    return Ok(());
 6605                }
 6606            }
 6607        };
 6608        let request = proto::ResolveCompletionDocumentation {
 6609            project_id,
 6610            language_server_id: server_id.0 as u64,
 6611            lsp_completion,
 6612            buffer_id: buffer_id.into(),
 6613        };
 6614
 6615        let response = client
 6616            .request(request)
 6617            .await
 6618            .context("completion documentation resolve proto request")?;
 6619        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6620
 6621        let documentation = if response.documentation.is_empty() {
 6622            CompletionDocumentation::Undocumented
 6623        } else if response.documentation_is_markdown {
 6624            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6625        } else if response.documentation.lines().count() <= 1 {
 6626            CompletionDocumentation::SingleLine(response.documentation.into())
 6627        } else {
 6628            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6629        };
 6630
 6631        let mut completions = completions.borrow_mut();
 6632        let completion = &mut completions[completion_index];
 6633        completion.documentation = Some(documentation);
 6634        if let CompletionSource::Lsp {
 6635            insert_range,
 6636            lsp_completion,
 6637            resolved,
 6638            server_id: completion_server_id,
 6639            lsp_defaults: _,
 6640        } = &mut completion.source
 6641        {
 6642            let completion_insert_range = response
 6643                .old_insert_start
 6644                .and_then(deserialize_anchor)
 6645                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6646            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6647
 6648            if *resolved {
 6649                return Ok(());
 6650            }
 6651            anyhow::ensure!(
 6652                server_id == *completion_server_id,
 6653                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6654            );
 6655            **lsp_completion = resolved_lsp_completion;
 6656            *resolved = true;
 6657        }
 6658
 6659        let replace_range = response
 6660            .old_replace_start
 6661            .and_then(deserialize_anchor)
 6662            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6663        if let Some((old_replace_start, old_replace_end)) = replace_range
 6664            && !response.new_text.is_empty()
 6665        {
 6666            completion.new_text = response.new_text;
 6667            completion.replace_range = old_replace_start..old_replace_end;
 6668        }
 6669
 6670        Ok(())
 6671    }
 6672
 6673    pub fn apply_additional_edits_for_completion(
 6674        &self,
 6675        buffer_handle: Entity<Buffer>,
 6676        completions: Rc<RefCell<Box<[Completion]>>>,
 6677        completion_index: usize,
 6678        push_to_history: bool,
 6679        cx: &mut Context<Self>,
 6680    ) -> Task<Result<Option<Transaction>>> {
 6681        if let Some((client, project_id)) = self.upstream_client() {
 6682            let buffer = buffer_handle.read(cx);
 6683            let buffer_id = buffer.remote_id();
 6684            cx.spawn(async move |_, cx| {
 6685                let request = {
 6686                    let completion = completions.borrow()[completion_index].clone();
 6687                    proto::ApplyCompletionAdditionalEdits {
 6688                        project_id,
 6689                        buffer_id: buffer_id.into(),
 6690                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6691                            replace_range: completion.replace_range,
 6692                            new_text: completion.new_text,
 6693                            source: completion.source,
 6694                        })),
 6695                    }
 6696                };
 6697
 6698                if let Some(transaction) = client.request(request).await?.transaction {
 6699                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6700                    buffer_handle
 6701                        .update(cx, |buffer, _| {
 6702                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6703                        })?
 6704                        .await?;
 6705                    if push_to_history {
 6706                        buffer_handle.update(cx, |buffer, _| {
 6707                            buffer.push_transaction(transaction.clone(), Instant::now());
 6708                            buffer.finalize_last_transaction();
 6709                        })?;
 6710                    }
 6711                    Ok(Some(transaction))
 6712                } else {
 6713                    Ok(None)
 6714                }
 6715            })
 6716        } else {
 6717            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6718                let completion = &completions.borrow()[completion_index];
 6719                let server_id = completion.source.server_id()?;
 6720                Some(
 6721                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6722                        .1
 6723                        .clone(),
 6724                )
 6725            }) else {
 6726                return Task::ready(Ok(None));
 6727            };
 6728
 6729            cx.spawn(async move |this, cx| {
 6730                Self::resolve_completion_local(
 6731                    server.clone(),
 6732                    completions.clone(),
 6733                    completion_index,
 6734                )
 6735                .await
 6736                .context("resolving completion")?;
 6737                let completion = completions.borrow()[completion_index].clone();
 6738                let additional_text_edits = completion
 6739                    .source
 6740                    .lsp_completion(true)
 6741                    .as_ref()
 6742                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6743                if let Some(edits) = additional_text_edits {
 6744                    let edits = this
 6745                        .update(cx, |this, cx| {
 6746                            this.as_local_mut().unwrap().edits_from_lsp(
 6747                                &buffer_handle,
 6748                                edits,
 6749                                server.server_id(),
 6750                                None,
 6751                                cx,
 6752                            )
 6753                        })?
 6754                        .await?;
 6755
 6756                    buffer_handle.update(cx, |buffer, cx| {
 6757                        buffer.finalize_last_transaction();
 6758                        buffer.start_transaction();
 6759
 6760                        for (range, text) in edits {
 6761                            let primary = &completion.replace_range;
 6762
 6763                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6764                            // and the primary completion is just an insertion (empty range), then this is likely
 6765                            // an auto-import scenario and should not be considered overlapping
 6766                            // https://github.com/zed-industries/zed/issues/26136
 6767                            let is_file_start_auto_import = {
 6768                                let snapshot = buffer.snapshot();
 6769                                let primary_start_point = primary.start.to_point(&snapshot);
 6770                                let range_start_point = range.start.to_point(&snapshot);
 6771
 6772                                let result = primary_start_point.row == 0
 6773                                    && primary_start_point.column == 0
 6774                                    && range_start_point.row == 0
 6775                                    && range_start_point.column == 0;
 6776
 6777                                result
 6778                            };
 6779
 6780                            let has_overlap = if is_file_start_auto_import {
 6781                                false
 6782                            } else {
 6783                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6784                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6785                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6786                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6787                                let result = start_within || end_within;
 6788                                result
 6789                            };
 6790
 6791                            //Skip additional edits which overlap with the primary completion edit
 6792                            //https://github.com/zed-industries/zed/pull/1871
 6793                            if !has_overlap {
 6794                                buffer.edit([(range, text)], None, cx);
 6795                            }
 6796                        }
 6797
 6798                        let transaction = if buffer.end_transaction(cx).is_some() {
 6799                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6800                            if !push_to_history {
 6801                                buffer.forget_transaction(transaction.id);
 6802                            }
 6803                            Some(transaction)
 6804                        } else {
 6805                            None
 6806                        };
 6807                        Ok(transaction)
 6808                    })?
 6809                } else {
 6810                    Ok(None)
 6811                }
 6812            })
 6813        }
 6814    }
 6815
 6816    pub fn pull_diagnostics(
 6817        &mut self,
 6818        buffer: Entity<Buffer>,
 6819        cx: &mut Context<Self>,
 6820    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6821        let buffer_id = buffer.read(cx).remote_id();
 6822
 6823        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6824            let mut suitable_capabilities = None;
 6825            // Are we capable for proto request?
 6826            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6827                &buffer,
 6828                |capabilities| {
 6829                    if let Some(caps) = &capabilities.diagnostic_provider {
 6830                        suitable_capabilities = Some(caps.clone());
 6831                        true
 6832                    } else {
 6833                        false
 6834                    }
 6835                },
 6836                cx,
 6837            );
 6838            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6839            let Some(dynamic_caps) = suitable_capabilities else {
 6840                return Task::ready(Ok(None));
 6841            };
 6842            assert!(any_server_has_diagnostics_provider);
 6843
 6844            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6845            let request = GetDocumentDiagnostics {
 6846                previous_result_id: None,
 6847                identifier,
 6848                registration_id: None,
 6849            };
 6850            let request_task = client.request_lsp(
 6851                upstream_project_id,
 6852                None,
 6853                LSP_REQUEST_TIMEOUT,
 6854                cx.background_executor().clone(),
 6855                request.to_proto(upstream_project_id, buffer.read(cx)),
 6856            );
 6857            cx.background_spawn(async move {
 6858                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6859                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6860                // Do not attempt to further process the dummy responses here.
 6861                let _response = request_task.await?;
 6862                Ok(None)
 6863            })
 6864        } else {
 6865            let servers = buffer.update(cx, |buffer, cx| {
 6866                self.running_language_servers_for_local_buffer(buffer, cx)
 6867                    .map(|(_, server)| server.clone())
 6868                    .collect::<Vec<_>>()
 6869            });
 6870
 6871            let pull_diagnostics = servers
 6872                .into_iter()
 6873                .flat_map(|server| {
 6874                    let result = maybe!({
 6875                        let local = self.as_local()?;
 6876                        let server_id = server.server_id();
 6877                        let providers_with_identifiers = local
 6878                            .language_server_dynamic_registrations
 6879                            .get(&server_id)
 6880                            .into_iter()
 6881                            .flat_map(|registrations| registrations.diagnostics.clone())
 6882                            .collect::<Vec<_>>();
 6883                        Some(
 6884                            providers_with_identifiers
 6885                                .into_iter()
 6886                                .map(|(registration_id, dynamic_caps)| {
 6887                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6888                                    let registration_id = registration_id.map(SharedString::from);
 6889                                    let result_id = self.result_id_for_buffer_pull(
 6890                                        server_id,
 6891                                        buffer_id,
 6892                                        &registration_id,
 6893                                        cx,
 6894                                    );
 6895                                    self.request_lsp(
 6896                                        buffer.clone(),
 6897                                        LanguageServerToQuery::Other(server_id),
 6898                                        GetDocumentDiagnostics {
 6899                                            previous_result_id: result_id,
 6900                                            registration_id,
 6901                                            identifier,
 6902                                        },
 6903                                        cx,
 6904                                    )
 6905                                })
 6906                                .collect::<Vec<_>>(),
 6907                        )
 6908                    });
 6909
 6910                    result.unwrap_or_default()
 6911                })
 6912                .collect::<Vec<_>>();
 6913
 6914            cx.background_spawn(async move {
 6915                let mut responses = Vec::new();
 6916                for diagnostics in join_all(pull_diagnostics).await {
 6917                    responses.extend(diagnostics?);
 6918                }
 6919                Ok(Some(responses))
 6920            })
 6921        }
 6922    }
 6923
 6924    pub fn applicable_inlay_chunks(
 6925        &mut self,
 6926        buffer: &Entity<Buffer>,
 6927        ranges: &[Range<text::Anchor>],
 6928        cx: &mut Context<Self>,
 6929    ) -> Vec<Range<BufferRow>> {
 6930        let buffer_snapshot = buffer.read(cx).snapshot();
 6931        let ranges = ranges
 6932            .iter()
 6933            .map(|range| range.to_point(&buffer_snapshot))
 6934            .collect::<Vec<_>>();
 6935
 6936        self.latest_lsp_data(buffer, cx)
 6937            .inlay_hints
 6938            .applicable_chunks(ranges.as_slice())
 6939            .map(|chunk| chunk.row_range())
 6940            .collect()
 6941    }
 6942
 6943    pub fn invalidate_inlay_hints<'a>(
 6944        &'a mut self,
 6945        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6946    ) {
 6947        for buffer_id in for_buffers {
 6948            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6949                lsp_data.inlay_hints.clear();
 6950            }
 6951        }
 6952    }
 6953
 6954    pub fn inlay_hints(
 6955        &mut self,
 6956        invalidate: InvalidationStrategy,
 6957        buffer: Entity<Buffer>,
 6958        ranges: Vec<Range<text::Anchor>>,
 6959        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6960        cx: &mut Context<Self>,
 6961    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6962        let next_hint_id = self.next_hint_id.clone();
 6963        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6964        let query_version = lsp_data.buffer_version.clone();
 6965        let mut lsp_refresh_requested = false;
 6966        let for_server = if let InvalidationStrategy::RefreshRequested {
 6967            server_id,
 6968            request_id,
 6969        } = invalidate
 6970        {
 6971            let invalidated = lsp_data
 6972                .inlay_hints
 6973                .invalidate_for_server_refresh(server_id, request_id);
 6974            lsp_refresh_requested = invalidated;
 6975            Some(server_id)
 6976        } else {
 6977            None
 6978        };
 6979        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6980        let known_chunks = known_chunks
 6981            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6982            .map(|(_, known_chunks)| known_chunks)
 6983            .unwrap_or_default();
 6984
 6985        let buffer_snapshot = buffer.read(cx).snapshot();
 6986        let ranges = ranges
 6987            .iter()
 6988            .map(|range| range.to_point(&buffer_snapshot))
 6989            .collect::<Vec<_>>();
 6990
 6991        let mut hint_fetch_tasks = Vec::new();
 6992        let mut cached_inlay_hints = None;
 6993        let mut ranges_to_query = None;
 6994        let applicable_chunks = existing_inlay_hints
 6995            .applicable_chunks(ranges.as_slice())
 6996            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 6997            .collect::<Vec<_>>();
 6998        if applicable_chunks.is_empty() {
 6999            return HashMap::default();
 7000        }
 7001
 7002        for row_chunk in applicable_chunks {
 7003            match (
 7004                existing_inlay_hints
 7005                    .cached_hints(&row_chunk)
 7006                    .filter(|_| !lsp_refresh_requested)
 7007                    .cloned(),
 7008                existing_inlay_hints
 7009                    .fetched_hints(&row_chunk)
 7010                    .as_ref()
 7011                    .filter(|_| !lsp_refresh_requested)
 7012                    .cloned(),
 7013            ) {
 7014                (None, None) => {
 7015                    let chunk_range = row_chunk.anchor_range();
 7016                    ranges_to_query
 7017                        .get_or_insert_with(Vec::new)
 7018                        .push((row_chunk, chunk_range));
 7019                }
 7020                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7021                (Some(cached_hints), None) => {
 7022                    for (server_id, cached_hints) in cached_hints {
 7023                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7024                            cached_inlay_hints
 7025                                .get_or_insert_with(HashMap::default)
 7026                                .entry(row_chunk.row_range())
 7027                                .or_insert_with(HashMap::default)
 7028                                .entry(server_id)
 7029                                .or_insert_with(Vec::new)
 7030                                .extend(cached_hints);
 7031                        }
 7032                    }
 7033                }
 7034                (Some(cached_hints), Some(fetched_hints)) => {
 7035                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 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            }
 7049        }
 7050
 7051        if hint_fetch_tasks.is_empty()
 7052            && ranges_to_query
 7053                .as_ref()
 7054                .is_none_or(|ranges| ranges.is_empty())
 7055            && let Some(cached_inlay_hints) = cached_inlay_hints
 7056        {
 7057            cached_inlay_hints
 7058                .into_iter()
 7059                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7060                .collect()
 7061        } else {
 7062            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7063                let next_hint_id = next_hint_id.clone();
 7064                let buffer = buffer.clone();
 7065                let query_version = query_version.clone();
 7066                let new_inlay_hints = cx
 7067                    .spawn(async move |lsp_store, cx| {
 7068                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7069                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7070                        })?;
 7071                        new_fetch_task
 7072                            .await
 7073                            .and_then(|new_hints_by_server| {
 7074                                lsp_store.update(cx, |lsp_store, cx| {
 7075                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7076                                    let update_cache = lsp_data.buffer_version == query_version;
 7077                                    if new_hints_by_server.is_empty() {
 7078                                        if update_cache {
 7079                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7080                                        }
 7081                                        HashMap::default()
 7082                                    } else {
 7083                                        new_hints_by_server
 7084                                            .into_iter()
 7085                                            .map(|(server_id, new_hints)| {
 7086                                                let new_hints = new_hints
 7087                                                    .into_iter()
 7088                                                    .map(|new_hint| {
 7089                                                        (
 7090                                                            InlayId::Hint(next_hint_id.fetch_add(
 7091                                                                1,
 7092                                                                atomic::Ordering::AcqRel,
 7093                                                            )),
 7094                                                            new_hint,
 7095                                                        )
 7096                                                    })
 7097                                                    .collect::<Vec<_>>();
 7098                                                if update_cache {
 7099                                                    lsp_data.inlay_hints.insert_new_hints(
 7100                                                        chunk,
 7101                                                        server_id,
 7102                                                        new_hints.clone(),
 7103                                                    );
 7104                                                }
 7105                                                (server_id, new_hints)
 7106                                            })
 7107                                            .collect()
 7108                                    }
 7109                                })
 7110                            })
 7111                            .map_err(Arc::new)
 7112                    })
 7113                    .shared();
 7114
 7115                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7116                *fetch_task = Some(new_inlay_hints.clone());
 7117                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7118            }
 7119
 7120            cached_inlay_hints
 7121                .unwrap_or_default()
 7122                .into_iter()
 7123                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7124                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7125                    (
 7126                        chunk.row_range(),
 7127                        cx.spawn(async move |_, _| {
 7128                            hints_fetch.await.map_err(|e| {
 7129                                if e.error_code() != ErrorCode::Internal {
 7130                                    anyhow!(e.error_code())
 7131                                } else {
 7132                                    anyhow!("{e:#}")
 7133                                }
 7134                            })
 7135                        }),
 7136                    )
 7137                }))
 7138                .collect()
 7139        }
 7140    }
 7141
 7142    fn fetch_inlay_hints(
 7143        &mut self,
 7144        for_server: Option<LanguageServerId>,
 7145        buffer: &Entity<Buffer>,
 7146        range: Range<Anchor>,
 7147        cx: &mut Context<Self>,
 7148    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7149        let request = InlayHints {
 7150            range: range.clone(),
 7151        };
 7152        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7153            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7154                return Task::ready(Ok(HashMap::default()));
 7155            }
 7156            let request_task = upstream_client.request_lsp(
 7157                project_id,
 7158                for_server.map(|id| id.to_proto()),
 7159                LSP_REQUEST_TIMEOUT,
 7160                cx.background_executor().clone(),
 7161                request.to_proto(project_id, buffer.read(cx)),
 7162            );
 7163            let buffer = buffer.clone();
 7164            cx.spawn(async move |weak_lsp_store, cx| {
 7165                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7166                    return Ok(HashMap::default());
 7167                };
 7168                let Some(responses) = request_task.await? else {
 7169                    return Ok(HashMap::default());
 7170                };
 7171
 7172                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7173                    let lsp_store = lsp_store.clone();
 7174                    let buffer = buffer.clone();
 7175                    let cx = cx.clone();
 7176                    let request = request.clone();
 7177                    async move {
 7178                        (
 7179                            LanguageServerId::from_proto(response.server_id),
 7180                            request
 7181                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7182                                .await,
 7183                        )
 7184                    }
 7185                }))
 7186                .await;
 7187
 7188                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot())?;
 7189                let mut has_errors = false;
 7190                let inlay_hints = inlay_hints
 7191                    .into_iter()
 7192                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7193                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7194                        Err(e) => {
 7195                            has_errors = true;
 7196                            log::error!("{e:#}");
 7197                            None
 7198                        }
 7199                    })
 7200                    .map(|(server_id, mut new_hints)| {
 7201                        new_hints.retain(|hint| {
 7202                            hint.position.is_valid(&buffer_snapshot)
 7203                                && range.start.is_valid(&buffer_snapshot)
 7204                                && range.end.is_valid(&buffer_snapshot)
 7205                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7206                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7207                        });
 7208                        (server_id, new_hints)
 7209                    })
 7210                    .collect::<HashMap<_, _>>();
 7211                anyhow::ensure!(
 7212                    !has_errors || !inlay_hints.is_empty(),
 7213                    "Failed to fetch inlay hints"
 7214                );
 7215                Ok(inlay_hints)
 7216            })
 7217        } else {
 7218            let inlay_hints_task = match for_server {
 7219                Some(server_id) => {
 7220                    let server_task = self.request_lsp(
 7221                        buffer.clone(),
 7222                        LanguageServerToQuery::Other(server_id),
 7223                        request,
 7224                        cx,
 7225                    );
 7226                    cx.background_spawn(async move {
 7227                        let mut responses = Vec::new();
 7228                        match server_task.await {
 7229                            Ok(response) => responses.push((server_id, response)),
 7230                            // rust-analyzer likes to error with this when its still loading up
 7231                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7232                            Err(e) => log::error!(
 7233                                "Error handling response for inlay hints request: {e:#}"
 7234                            ),
 7235                        }
 7236                        responses
 7237                    })
 7238                }
 7239                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7240            };
 7241            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7242            cx.background_spawn(async move {
 7243                Ok(inlay_hints_task
 7244                    .await
 7245                    .into_iter()
 7246                    .map(|(server_id, mut new_hints)| {
 7247                        new_hints.retain(|hint| {
 7248                            hint.position.is_valid(&buffer_snapshot)
 7249                                && range.start.is_valid(&buffer_snapshot)
 7250                                && range.end.is_valid(&buffer_snapshot)
 7251                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7252                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7253                        });
 7254                        (server_id, new_hints)
 7255                    })
 7256                    .collect())
 7257            })
 7258        }
 7259    }
 7260
 7261    pub fn pull_diagnostics_for_buffer(
 7262        &mut self,
 7263        buffer: Entity<Buffer>,
 7264        cx: &mut Context<Self>,
 7265    ) -> Task<anyhow::Result<()>> {
 7266        let diagnostics = self.pull_diagnostics(buffer, cx);
 7267        cx.spawn(async move |lsp_store, cx| {
 7268            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7269                return Ok(());
 7270            };
 7271            lsp_store.update(cx, |lsp_store, cx| {
 7272                if lsp_store.as_local().is_none() {
 7273                    return;
 7274                }
 7275
 7276                let mut unchanged_buffers = HashMap::default();
 7277                let server_diagnostics_updates = diagnostics
 7278                    .into_iter()
 7279                    .filter_map(|diagnostics_set| match diagnostics_set {
 7280                        LspPullDiagnostics::Response {
 7281                            server_id,
 7282                            uri,
 7283                            diagnostics,
 7284                            registration_id,
 7285                        } => Some((server_id, uri, diagnostics, registration_id)),
 7286                        LspPullDiagnostics::Default => None,
 7287                    })
 7288                    .fold(
 7289                        HashMap::default(),
 7290                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7291                            let (result_id, diagnostics) = match diagnostics {
 7292                                PulledDiagnostics::Unchanged { result_id } => {
 7293                                    unchanged_buffers
 7294                                        .entry(new_registration_id.clone())
 7295                                        .or_insert_with(HashSet::default)
 7296                                        .insert(uri.clone());
 7297                                    (Some(result_id), Vec::new())
 7298                                }
 7299                                PulledDiagnostics::Changed {
 7300                                    result_id,
 7301                                    diagnostics,
 7302                                } => (result_id, diagnostics),
 7303                            };
 7304                            let disk_based_sources = Cow::Owned(
 7305                                lsp_store
 7306                                    .language_server_adapter_for_id(server_id)
 7307                                    .as_ref()
 7308                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7309                                    .unwrap_or(&[])
 7310                                    .to_vec(),
 7311                            );
 7312                            acc.entry(server_id)
 7313                                .or_insert_with(HashMap::default)
 7314                                .entry(new_registration_id.clone())
 7315                                .or_insert_with(Vec::new)
 7316                                .push(DocumentDiagnosticsUpdate {
 7317                                    server_id,
 7318                                    diagnostics: lsp::PublishDiagnosticsParams {
 7319                                        uri,
 7320                                        diagnostics,
 7321                                        version: None,
 7322                                    },
 7323                                    result_id,
 7324                                    disk_based_sources,
 7325                                    registration_id: new_registration_id,
 7326                                });
 7327                            acc
 7328                        },
 7329                    );
 7330
 7331                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7332                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7333                        lsp_store
 7334                            .merge_lsp_diagnostics(
 7335                                DiagnosticSourceKind::Pulled,
 7336                                diagnostic_updates,
 7337                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7338                                    DiagnosticSourceKind::Pulled => {
 7339                                        old_diagnostic.registration_id != registration_id
 7340                                            || unchanged_buffers
 7341                                                .get(&old_diagnostic.registration_id)
 7342                                                .is_some_and(|unchanged_buffers| {
 7343                                                    unchanged_buffers.contains(&document_uri)
 7344                                                })
 7345                                    }
 7346                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7347                                        true
 7348                                    }
 7349                                },
 7350                                cx,
 7351                            )
 7352                            .log_err();
 7353                    }
 7354                }
 7355            })
 7356        })
 7357    }
 7358
 7359    pub fn document_colors(
 7360        &mut self,
 7361        known_cache_version: Option<usize>,
 7362        buffer: Entity<Buffer>,
 7363        cx: &mut Context<Self>,
 7364    ) -> Option<DocumentColorTask> {
 7365        let version_queried_for = buffer.read(cx).version();
 7366        let buffer_id = buffer.read(cx).remote_id();
 7367
 7368        let current_language_servers = self.as_local().map(|local| {
 7369            local
 7370                .buffers_opened_in_servers
 7371                .get(&buffer_id)
 7372                .cloned()
 7373                .unwrap_or_default()
 7374        });
 7375
 7376        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7377            if let Some(cached_colors) = &lsp_data.document_colors {
 7378                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7379                    let has_different_servers =
 7380                        current_language_servers.is_some_and(|current_language_servers| {
 7381                            current_language_servers
 7382                                != cached_colors.colors.keys().copied().collect()
 7383                        });
 7384                    if !has_different_servers {
 7385                        let cache_version = cached_colors.cache_version;
 7386                        if Some(cache_version) == known_cache_version {
 7387                            return None;
 7388                        } else {
 7389                            return Some(
 7390                                Task::ready(Ok(DocumentColors {
 7391                                    colors: cached_colors
 7392                                        .colors
 7393                                        .values()
 7394                                        .flatten()
 7395                                        .cloned()
 7396                                        .collect(),
 7397                                    cache_version: Some(cache_version),
 7398                                }))
 7399                                .shared(),
 7400                            );
 7401                        }
 7402                    }
 7403                }
 7404            }
 7405        }
 7406
 7407        let color_lsp_data = self
 7408            .latest_lsp_data(&buffer, cx)
 7409            .document_colors
 7410            .get_or_insert_default();
 7411        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7412            && !version_queried_for.changed_since(updating_for)
 7413        {
 7414            return Some(running_update.clone());
 7415        }
 7416        let buffer_version_queried_for = version_queried_for.clone();
 7417        let new_task = cx
 7418            .spawn(async move |lsp_store, cx| {
 7419                cx.background_executor()
 7420                    .timer(Duration::from_millis(30))
 7421                    .await;
 7422                let fetched_colors = lsp_store
 7423                    .update(cx, |lsp_store, cx| {
 7424                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7425                    })?
 7426                    .await
 7427                    .context("fetching document colors")
 7428                    .map_err(Arc::new);
 7429                let fetched_colors = match fetched_colors {
 7430                    Ok(fetched_colors) => {
 7431                        if Some(true)
 7432                            == buffer
 7433                                .update(cx, |buffer, _| {
 7434                                    buffer.version() != buffer_version_queried_for
 7435                                })
 7436                                .ok()
 7437                        {
 7438                            return Ok(DocumentColors::default());
 7439                        }
 7440                        fetched_colors
 7441                    }
 7442                    Err(e) => {
 7443                        lsp_store
 7444                            .update(cx, |lsp_store, _| {
 7445                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7446                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7447                                        document_colors.colors_update = None;
 7448                                    }
 7449                                }
 7450                            })
 7451                            .ok();
 7452                        return Err(e);
 7453                    }
 7454                };
 7455
 7456                lsp_store
 7457                    .update(cx, |lsp_store, cx| {
 7458                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7459                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7460
 7461                        if let Some(fetched_colors) = fetched_colors {
 7462                            if lsp_data.buffer_version == buffer_version_queried_for {
 7463                                lsp_colors.colors.extend(fetched_colors);
 7464                                lsp_colors.cache_version += 1;
 7465                            } else if !lsp_data
 7466                                .buffer_version
 7467                                .changed_since(&buffer_version_queried_for)
 7468                            {
 7469                                lsp_data.buffer_version = buffer_version_queried_for;
 7470                                lsp_colors.colors = fetched_colors;
 7471                                lsp_colors.cache_version += 1;
 7472                            }
 7473                        }
 7474                        lsp_colors.colors_update = None;
 7475                        let colors = lsp_colors
 7476                            .colors
 7477                            .values()
 7478                            .flatten()
 7479                            .cloned()
 7480                            .collect::<HashSet<_>>();
 7481                        DocumentColors {
 7482                            colors,
 7483                            cache_version: Some(lsp_colors.cache_version),
 7484                        }
 7485                    })
 7486                    .map_err(Arc::new)
 7487            })
 7488            .shared();
 7489        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7490        Some(new_task)
 7491    }
 7492
 7493    fn fetch_document_colors_for_buffer(
 7494        &mut self,
 7495        buffer: &Entity<Buffer>,
 7496        cx: &mut Context<Self>,
 7497    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7498        if let Some((client, project_id)) = self.upstream_client() {
 7499            let request = GetDocumentColor {};
 7500            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7501                return Task::ready(Ok(None));
 7502            }
 7503
 7504            let request_task = client.request_lsp(
 7505                project_id,
 7506                None,
 7507                LSP_REQUEST_TIMEOUT,
 7508                cx.background_executor().clone(),
 7509                request.to_proto(project_id, buffer.read(cx)),
 7510            );
 7511            let buffer = buffer.clone();
 7512            cx.spawn(async move |lsp_store, cx| {
 7513                let Some(lsp_store) = lsp_store.upgrade() else {
 7514                    return Ok(None);
 7515                };
 7516                let colors = join_all(
 7517                    request_task
 7518                        .await
 7519                        .log_err()
 7520                        .flatten()
 7521                        .map(|response| response.payload)
 7522                        .unwrap_or_default()
 7523                        .into_iter()
 7524                        .map(|color_response| {
 7525                            let response = request.response_from_proto(
 7526                                color_response.response,
 7527                                lsp_store.clone(),
 7528                                buffer.clone(),
 7529                                cx.clone(),
 7530                            );
 7531                            async move {
 7532                                (
 7533                                    LanguageServerId::from_proto(color_response.server_id),
 7534                                    response.await.log_err().unwrap_or_default(),
 7535                                )
 7536                            }
 7537                        }),
 7538                )
 7539                .await
 7540                .into_iter()
 7541                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7542                    acc.entry(server_id)
 7543                        .or_insert_with(HashSet::default)
 7544                        .extend(colors);
 7545                    acc
 7546                });
 7547                Ok(Some(colors))
 7548            })
 7549        } else {
 7550            let document_colors_task =
 7551                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7552            cx.background_spawn(async move {
 7553                Ok(Some(
 7554                    document_colors_task
 7555                        .await
 7556                        .into_iter()
 7557                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7558                            acc.entry(server_id)
 7559                                .or_insert_with(HashSet::default)
 7560                                .extend(colors);
 7561                            acc
 7562                        })
 7563                        .into_iter()
 7564                        .collect(),
 7565                ))
 7566            })
 7567        }
 7568    }
 7569
 7570    pub fn signature_help<T: ToPointUtf16>(
 7571        &mut self,
 7572        buffer: &Entity<Buffer>,
 7573        position: T,
 7574        cx: &mut Context<Self>,
 7575    ) -> Task<Option<Vec<SignatureHelp>>> {
 7576        let position = position.to_point_utf16(buffer.read(cx));
 7577
 7578        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7579            let request = GetSignatureHelp { position };
 7580            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7581                return Task::ready(None);
 7582            }
 7583            let request_task = client.request_lsp(
 7584                upstream_project_id,
 7585                None,
 7586                LSP_REQUEST_TIMEOUT,
 7587                cx.background_executor().clone(),
 7588                request.to_proto(upstream_project_id, buffer.read(cx)),
 7589            );
 7590            let buffer = buffer.clone();
 7591            cx.spawn(async move |weak_lsp_store, cx| {
 7592                let lsp_store = weak_lsp_store.upgrade()?;
 7593                let signatures = join_all(
 7594                    request_task
 7595                        .await
 7596                        .log_err()
 7597                        .flatten()
 7598                        .map(|response| response.payload)
 7599                        .unwrap_or_default()
 7600                        .into_iter()
 7601                        .map(|response| {
 7602                            let response = GetSignatureHelp { position }.response_from_proto(
 7603                                response.response,
 7604                                lsp_store.clone(),
 7605                                buffer.clone(),
 7606                                cx.clone(),
 7607                            );
 7608                            async move { response.await.log_err().flatten() }
 7609                        }),
 7610                )
 7611                .await
 7612                .into_iter()
 7613                .flatten()
 7614                .collect();
 7615                Some(signatures)
 7616            })
 7617        } else {
 7618            let all_actions_task = self.request_multiple_lsp_locally(
 7619                buffer,
 7620                Some(position),
 7621                GetSignatureHelp { position },
 7622                cx,
 7623            );
 7624            cx.background_spawn(async move {
 7625                Some(
 7626                    all_actions_task
 7627                        .await
 7628                        .into_iter()
 7629                        .flat_map(|(_, actions)| actions)
 7630                        .collect::<Vec<_>>(),
 7631                )
 7632            })
 7633        }
 7634    }
 7635
 7636    pub fn hover(
 7637        &mut self,
 7638        buffer: &Entity<Buffer>,
 7639        position: PointUtf16,
 7640        cx: &mut Context<Self>,
 7641    ) -> Task<Option<Vec<Hover>>> {
 7642        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7643            let request = GetHover { position };
 7644            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7645                return Task::ready(None);
 7646            }
 7647            let request_task = client.request_lsp(
 7648                upstream_project_id,
 7649                None,
 7650                LSP_REQUEST_TIMEOUT,
 7651                cx.background_executor().clone(),
 7652                request.to_proto(upstream_project_id, buffer.read(cx)),
 7653            );
 7654            let buffer = buffer.clone();
 7655            cx.spawn(async move |weak_lsp_store, cx| {
 7656                let lsp_store = weak_lsp_store.upgrade()?;
 7657                let hovers = join_all(
 7658                    request_task
 7659                        .await
 7660                        .log_err()
 7661                        .flatten()
 7662                        .map(|response| response.payload)
 7663                        .unwrap_or_default()
 7664                        .into_iter()
 7665                        .map(|response| {
 7666                            let response = GetHover { position }.response_from_proto(
 7667                                response.response,
 7668                                lsp_store.clone(),
 7669                                buffer.clone(),
 7670                                cx.clone(),
 7671                            );
 7672                            async move {
 7673                                response
 7674                                    .await
 7675                                    .log_err()
 7676                                    .flatten()
 7677                                    .and_then(remove_empty_hover_blocks)
 7678                            }
 7679                        }),
 7680                )
 7681                .await
 7682                .into_iter()
 7683                .flatten()
 7684                .collect();
 7685                Some(hovers)
 7686            })
 7687        } else {
 7688            let all_actions_task = self.request_multiple_lsp_locally(
 7689                buffer,
 7690                Some(position),
 7691                GetHover { position },
 7692                cx,
 7693            );
 7694            cx.background_spawn(async move {
 7695                Some(
 7696                    all_actions_task
 7697                        .await
 7698                        .into_iter()
 7699                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7700                        .collect::<Vec<Hover>>(),
 7701                )
 7702            })
 7703        }
 7704    }
 7705
 7706    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7707        let language_registry = self.languages.clone();
 7708
 7709        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7710            let request = upstream_client.request(proto::GetProjectSymbols {
 7711                project_id: *project_id,
 7712                query: query.to_string(),
 7713            });
 7714            cx.foreground_executor().spawn(async move {
 7715                let response = request.await?;
 7716                let mut symbols = Vec::new();
 7717                let core_symbols = response
 7718                    .symbols
 7719                    .into_iter()
 7720                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7721                    .collect::<Vec<_>>();
 7722                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7723                    .await;
 7724                Ok(symbols)
 7725            })
 7726        } else if let Some(local) = self.as_local() {
 7727            struct WorkspaceSymbolsResult {
 7728                server_id: LanguageServerId,
 7729                lsp_adapter: Arc<CachedLspAdapter>,
 7730                worktree: WeakEntity<Worktree>,
 7731                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7732            }
 7733
 7734            let mut requests = Vec::new();
 7735            let mut requested_servers = BTreeSet::new();
 7736            for (seed, state) in local.language_server_ids.iter() {
 7737                let Some(worktree_handle) = self
 7738                    .worktree_store
 7739                    .read(cx)
 7740                    .worktree_for_id(seed.worktree_id, cx)
 7741                else {
 7742                    continue;
 7743                };
 7744                let worktree = worktree_handle.read(cx);
 7745                if !worktree.is_visible() {
 7746                    continue;
 7747                }
 7748
 7749                if !requested_servers.insert(state.id) {
 7750                    continue;
 7751                }
 7752
 7753                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7754                    Some(LanguageServerState::Running {
 7755                        adapter, server, ..
 7756                    }) => (adapter.clone(), server),
 7757
 7758                    _ => continue,
 7759                };
 7760                let supports_workspace_symbol_request =
 7761                    match server.capabilities().workspace_symbol_provider {
 7762                        Some(OneOf::Left(supported)) => supported,
 7763                        Some(OneOf::Right(_)) => true,
 7764                        None => false,
 7765                    };
 7766                if !supports_workspace_symbol_request {
 7767                    continue;
 7768                }
 7769                let worktree_handle = worktree_handle.clone();
 7770                let server_id = server.server_id();
 7771                requests.push(
 7772                        server
 7773                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7774                                lsp::WorkspaceSymbolParams {
 7775                                    query: query.to_string(),
 7776                                    ..Default::default()
 7777                                },
 7778                            )
 7779                            .map(move |response| {
 7780                                let lsp_symbols = response.into_response()
 7781                                    .context("workspace symbols request")
 7782                                    .log_err()
 7783                                    .flatten()
 7784                                    .map(|symbol_response| match symbol_response {
 7785                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7786                                            flat_responses.into_iter().map(|lsp_symbol| {
 7787                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7788                                            }).collect::<Vec<_>>()
 7789                                        }
 7790                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7791                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7792                                                let location = match lsp_symbol.location {
 7793                                                    OneOf::Left(location) => location,
 7794                                                    OneOf::Right(_) => {
 7795                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7796                                                        return None
 7797                                                    }
 7798                                                };
 7799                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7800                                            }).collect::<Vec<_>>()
 7801                                        }
 7802                                    }).unwrap_or_default();
 7803
 7804                                WorkspaceSymbolsResult {
 7805                                    server_id,
 7806                                    lsp_adapter,
 7807                                    worktree: worktree_handle.downgrade(),
 7808                                    lsp_symbols,
 7809                                }
 7810                            }),
 7811                    );
 7812            }
 7813
 7814            cx.spawn(async move |this, cx| {
 7815                let responses = futures::future::join_all(requests).await;
 7816                let this = match this.upgrade() {
 7817                    Some(this) => this,
 7818                    None => return Ok(Vec::new()),
 7819                };
 7820
 7821                let mut symbols = Vec::new();
 7822                for result in responses {
 7823                    let core_symbols = this.update(cx, |this, cx| {
 7824                        result
 7825                            .lsp_symbols
 7826                            .into_iter()
 7827                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7828                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7829                                let source_worktree = result.worktree.upgrade()?;
 7830                                let source_worktree_id = source_worktree.read(cx).id();
 7831
 7832                                let path = if let Some((tree, rel_path)) =
 7833                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7834                                {
 7835                                    let worktree_id = tree.read(cx).id();
 7836                                    SymbolLocation::InProject(ProjectPath {
 7837                                        worktree_id,
 7838                                        path: rel_path,
 7839                                    })
 7840                                } else {
 7841                                    SymbolLocation::OutsideProject {
 7842                                        signature: this.symbol_signature(&abs_path),
 7843                                        abs_path: abs_path.into(),
 7844                                    }
 7845                                };
 7846
 7847                                Some(CoreSymbol {
 7848                                    source_language_server_id: result.server_id,
 7849                                    language_server_name: result.lsp_adapter.name.clone(),
 7850                                    source_worktree_id,
 7851                                    path,
 7852                                    kind: symbol_kind,
 7853                                    name: symbol_name,
 7854                                    range: range_from_lsp(symbol_location.range),
 7855                                })
 7856                            })
 7857                            .collect()
 7858                    })?;
 7859
 7860                    populate_labels_for_symbols(
 7861                        core_symbols,
 7862                        &language_registry,
 7863                        Some(result.lsp_adapter),
 7864                        &mut symbols,
 7865                    )
 7866                    .await;
 7867                }
 7868
 7869                Ok(symbols)
 7870            })
 7871        } else {
 7872            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7873        }
 7874    }
 7875
 7876    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7877        let mut summary = DiagnosticSummary::default();
 7878        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7879            summary.error_count += path_summary.error_count;
 7880            summary.warning_count += path_summary.warning_count;
 7881        }
 7882        summary
 7883    }
 7884
 7885    /// Returns the diagnostic summary for a specific project path.
 7886    pub fn diagnostic_summary_for_path(
 7887        &self,
 7888        project_path: &ProjectPath,
 7889        _: &App,
 7890    ) -> DiagnosticSummary {
 7891        if let Some(summaries) = self
 7892            .diagnostic_summaries
 7893            .get(&project_path.worktree_id)
 7894            .and_then(|map| map.get(&project_path.path))
 7895        {
 7896            let (error_count, warning_count) = summaries.iter().fold(
 7897                (0, 0),
 7898                |(error_count, warning_count), (_language_server_id, summary)| {
 7899                    (
 7900                        error_count + summary.error_count,
 7901                        warning_count + summary.warning_count,
 7902                    )
 7903                },
 7904            );
 7905
 7906            DiagnosticSummary {
 7907                error_count,
 7908                warning_count,
 7909            }
 7910        } else {
 7911            DiagnosticSummary::default()
 7912        }
 7913    }
 7914
 7915    pub fn diagnostic_summaries<'a>(
 7916        &'a self,
 7917        include_ignored: bool,
 7918        cx: &'a App,
 7919    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7920        self.worktree_store
 7921            .read(cx)
 7922            .visible_worktrees(cx)
 7923            .filter_map(|worktree| {
 7924                let worktree = worktree.read(cx);
 7925                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7926            })
 7927            .flat_map(move |(worktree, summaries)| {
 7928                let worktree_id = worktree.id();
 7929                summaries
 7930                    .iter()
 7931                    .filter(move |(path, _)| {
 7932                        include_ignored
 7933                            || worktree
 7934                                .entry_for_path(path.as_ref())
 7935                                .is_some_and(|entry| !entry.is_ignored)
 7936                    })
 7937                    .flat_map(move |(path, summaries)| {
 7938                        summaries.iter().map(move |(server_id, summary)| {
 7939                            (
 7940                                ProjectPath {
 7941                                    worktree_id,
 7942                                    path: path.clone(),
 7943                                },
 7944                                *server_id,
 7945                                *summary,
 7946                            )
 7947                        })
 7948                    })
 7949            })
 7950    }
 7951
 7952    pub fn on_buffer_edited(
 7953        &mut self,
 7954        buffer: Entity<Buffer>,
 7955        cx: &mut Context<Self>,
 7956    ) -> Option<()> {
 7957        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7958            Some(
 7959                self.as_local()?
 7960                    .language_servers_for_buffer(buffer, cx)
 7961                    .map(|i| i.1.clone())
 7962                    .collect(),
 7963            )
 7964        })?;
 7965
 7966        let buffer = buffer.read(cx);
 7967        let file = File::from_dyn(buffer.file())?;
 7968        let abs_path = file.as_local()?.abs_path(cx);
 7969        let uri = lsp::Uri::from_file_path(&abs_path)
 7970            .ok()
 7971            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7972            .log_err()?;
 7973        let next_snapshot = buffer.text_snapshot();
 7974        for language_server in language_servers {
 7975            let language_server = language_server.clone();
 7976
 7977            let buffer_snapshots = self
 7978                .as_local_mut()?
 7979                .buffer_snapshots
 7980                .get_mut(&buffer.remote_id())
 7981                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7982            let previous_snapshot = buffer_snapshots.last()?;
 7983
 7984            let build_incremental_change = || {
 7985                buffer
 7986                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7987                        previous_snapshot.snapshot.version(),
 7988                    )
 7989                    .map(|edit| {
 7990                        let edit_start = edit.new.start.0;
 7991                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7992                        let new_text = next_snapshot
 7993                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7994                            .collect();
 7995                        lsp::TextDocumentContentChangeEvent {
 7996                            range: Some(lsp::Range::new(
 7997                                point_to_lsp(edit_start),
 7998                                point_to_lsp(edit_end),
 7999                            )),
 8000                            range_length: None,
 8001                            text: new_text,
 8002                        }
 8003                    })
 8004                    .collect()
 8005            };
 8006
 8007            let document_sync_kind = language_server
 8008                .capabilities()
 8009                .text_document_sync
 8010                .as_ref()
 8011                .and_then(|sync| match sync {
 8012                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 8013                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 8014                });
 8015
 8016            let content_changes: Vec<_> = match document_sync_kind {
 8017                Some(lsp::TextDocumentSyncKind::FULL) => {
 8018                    vec![lsp::TextDocumentContentChangeEvent {
 8019                        range: None,
 8020                        range_length: None,
 8021                        text: next_snapshot.text(),
 8022                    }]
 8023                }
 8024                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8025                _ => {
 8026                    #[cfg(any(test, feature = "test-support"))]
 8027                    {
 8028                        build_incremental_change()
 8029                    }
 8030
 8031                    #[cfg(not(any(test, feature = "test-support")))]
 8032                    {
 8033                        continue;
 8034                    }
 8035                }
 8036            };
 8037
 8038            let next_version = previous_snapshot.version + 1;
 8039            buffer_snapshots.push(LspBufferSnapshot {
 8040                version: next_version,
 8041                snapshot: next_snapshot.clone(),
 8042            });
 8043
 8044            language_server
 8045                .notify::<lsp::notification::DidChangeTextDocument>(
 8046                    lsp::DidChangeTextDocumentParams {
 8047                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8048                            uri.clone(),
 8049                            next_version,
 8050                        ),
 8051                        content_changes,
 8052                    },
 8053                )
 8054                .ok();
 8055            self.pull_workspace_diagnostics(language_server.server_id());
 8056        }
 8057
 8058        None
 8059    }
 8060
 8061    pub fn on_buffer_saved(
 8062        &mut self,
 8063        buffer: Entity<Buffer>,
 8064        cx: &mut Context<Self>,
 8065    ) -> Option<()> {
 8066        let file = File::from_dyn(buffer.read(cx).file())?;
 8067        let worktree_id = file.worktree_id(cx);
 8068        let abs_path = file.as_local()?.abs_path(cx);
 8069        let text_document = lsp::TextDocumentIdentifier {
 8070            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8071        };
 8072        let local = self.as_local()?;
 8073
 8074        for server in local.language_servers_for_worktree(worktree_id) {
 8075            if let Some(include_text) = include_text(server.as_ref()) {
 8076                let text = if include_text {
 8077                    Some(buffer.read(cx).text())
 8078                } else {
 8079                    None
 8080                };
 8081                server
 8082                    .notify::<lsp::notification::DidSaveTextDocument>(
 8083                        lsp::DidSaveTextDocumentParams {
 8084                            text_document: text_document.clone(),
 8085                            text,
 8086                        },
 8087                    )
 8088                    .ok();
 8089            }
 8090        }
 8091
 8092        let language_servers = buffer.update(cx, |buffer, cx| {
 8093            local.language_server_ids_for_buffer(buffer, cx)
 8094        });
 8095        for language_server_id in language_servers {
 8096            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8097        }
 8098
 8099        None
 8100    }
 8101
 8102    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8103        maybe!(async move {
 8104            let mut refreshed_servers = HashSet::default();
 8105            let servers = lsp_store
 8106                .update(cx, |lsp_store, cx| {
 8107                    let local = lsp_store.as_local()?;
 8108
 8109                    let servers = local
 8110                        .language_server_ids
 8111                        .iter()
 8112                        .filter_map(|(seed, state)| {
 8113                            let worktree = lsp_store
 8114                                .worktree_store
 8115                                .read(cx)
 8116                                .worktree_for_id(seed.worktree_id, cx);
 8117                            let delegate: Arc<dyn LspAdapterDelegate> =
 8118                                worktree.map(|worktree| {
 8119                                    LocalLspAdapterDelegate::new(
 8120                                        local.languages.clone(),
 8121                                        &local.environment,
 8122                                        cx.weak_entity(),
 8123                                        &worktree,
 8124                                        local.http_client.clone(),
 8125                                        local.fs.clone(),
 8126                                        cx,
 8127                                    )
 8128                                })?;
 8129                            let server_id = state.id;
 8130
 8131                            let states = local.language_servers.get(&server_id)?;
 8132
 8133                            match states {
 8134                                LanguageServerState::Starting { .. } => None,
 8135                                LanguageServerState::Running {
 8136                                    adapter, server, ..
 8137                                } => {
 8138                                    let adapter = adapter.clone();
 8139                                    let server = server.clone();
 8140                                    refreshed_servers.insert(server.name());
 8141                                    let toolchain = seed.toolchain.clone();
 8142                                    Some(cx.spawn(async move |_, cx| {
 8143                                        let settings =
 8144                                            LocalLspStore::workspace_configuration_for_adapter(
 8145                                                adapter.adapter.clone(),
 8146                                                &delegate,
 8147                                                toolchain,
 8148                                                None,
 8149                                                cx,
 8150                                            )
 8151                                            .await
 8152                                            .ok()?;
 8153                                        server
 8154                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8155                                                lsp::DidChangeConfigurationParams { settings },
 8156                                            )
 8157                                            .ok()?;
 8158                                        Some(())
 8159                                    }))
 8160                                }
 8161                            }
 8162                        })
 8163                        .collect::<Vec<_>>();
 8164
 8165                    Some(servers)
 8166                })
 8167                .ok()
 8168                .flatten()?;
 8169
 8170            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8171            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8172            // to stop and unregister its language server wrapper.
 8173            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8174            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8175            let _: Vec<Option<()>> = join_all(servers).await;
 8176
 8177            Some(())
 8178        })
 8179        .await;
 8180    }
 8181
 8182    fn maintain_workspace_config(
 8183        external_refresh_requests: watch::Receiver<()>,
 8184        cx: &mut Context<Self>,
 8185    ) -> Task<Result<()>> {
 8186        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8187        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8188
 8189        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8190            *settings_changed_tx.borrow_mut() = ();
 8191        });
 8192
 8193        let mut joint_future =
 8194            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8195        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8196        // - 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).
 8197        // - 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.
 8198        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8199        // - 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,
 8200        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8201        cx.spawn(async move |this, cx| {
 8202            while let Some(()) = joint_future.next().await {
 8203                this.update(cx, |this, cx| {
 8204                    this.refresh_server_tree(cx);
 8205                })
 8206                .ok();
 8207
 8208                Self::refresh_workspace_configurations(&this, cx).await;
 8209            }
 8210
 8211            drop(settings_observation);
 8212            anyhow::Ok(())
 8213        })
 8214    }
 8215
 8216    pub fn running_language_servers_for_local_buffer<'a>(
 8217        &'a self,
 8218        buffer: &Buffer,
 8219        cx: &mut App,
 8220    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8221        let local = self.as_local();
 8222        let language_server_ids = local
 8223            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8224            .unwrap_or_default();
 8225
 8226        language_server_ids
 8227            .into_iter()
 8228            .filter_map(
 8229                move |server_id| match local?.language_servers.get(&server_id)? {
 8230                    LanguageServerState::Running {
 8231                        adapter, server, ..
 8232                    } => Some((adapter, server)),
 8233                    _ => None,
 8234                },
 8235            )
 8236    }
 8237
 8238    pub fn language_servers_for_local_buffer(
 8239        &self,
 8240        buffer: &Buffer,
 8241        cx: &mut App,
 8242    ) -> Vec<LanguageServerId> {
 8243        let local = self.as_local();
 8244        local
 8245            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8246            .unwrap_or_default()
 8247    }
 8248
 8249    pub fn language_server_for_local_buffer<'a>(
 8250        &'a self,
 8251        buffer: &'a Buffer,
 8252        server_id: LanguageServerId,
 8253        cx: &'a mut App,
 8254    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8255        self.as_local()?
 8256            .language_servers_for_buffer(buffer, cx)
 8257            .find(|(_, s)| s.server_id() == server_id)
 8258    }
 8259
 8260    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8261        self.diagnostic_summaries.remove(&id_to_remove);
 8262        if let Some(local) = self.as_local_mut() {
 8263            let to_remove = local.remove_worktree(id_to_remove, cx);
 8264            for server in to_remove {
 8265                self.language_server_statuses.remove(&server);
 8266            }
 8267        }
 8268    }
 8269
 8270    pub fn shared(
 8271        &mut self,
 8272        project_id: u64,
 8273        downstream_client: AnyProtoClient,
 8274        _: &mut Context<Self>,
 8275    ) {
 8276        self.downstream_client = Some((downstream_client.clone(), project_id));
 8277
 8278        for (server_id, status) in &self.language_server_statuses {
 8279            if let Some(server) = self.language_server_for_id(*server_id) {
 8280                downstream_client
 8281                    .send(proto::StartLanguageServer {
 8282                        project_id,
 8283                        server: Some(proto::LanguageServer {
 8284                            id: server_id.to_proto(),
 8285                            name: status.name.to_string(),
 8286                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8287                        }),
 8288                        capabilities: serde_json::to_string(&server.capabilities())
 8289                            .expect("serializing server LSP capabilities"),
 8290                    })
 8291                    .log_err();
 8292            }
 8293        }
 8294    }
 8295
 8296    pub fn disconnected_from_host(&mut self) {
 8297        self.downstream_client.take();
 8298    }
 8299
 8300    pub fn disconnected_from_ssh_remote(&mut self) {
 8301        if let LspStoreMode::Remote(RemoteLspStore {
 8302            upstream_client, ..
 8303        }) = &mut self.mode
 8304        {
 8305            upstream_client.take();
 8306        }
 8307    }
 8308
 8309    pub(crate) fn set_language_server_statuses_from_proto(
 8310        &mut self,
 8311        project: WeakEntity<Project>,
 8312        language_servers: Vec<proto::LanguageServer>,
 8313        server_capabilities: Vec<String>,
 8314        cx: &mut Context<Self>,
 8315    ) {
 8316        let lsp_logs = cx
 8317            .try_global::<GlobalLogStore>()
 8318            .map(|lsp_store| lsp_store.0.clone());
 8319
 8320        self.language_server_statuses = language_servers
 8321            .into_iter()
 8322            .zip(server_capabilities)
 8323            .map(|(server, server_capabilities)| {
 8324                let server_id = LanguageServerId(server.id as usize);
 8325                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8326                    self.lsp_server_capabilities
 8327                        .insert(server_id, server_capabilities);
 8328                }
 8329
 8330                let name = LanguageServerName::from_proto(server.name);
 8331                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8332
 8333                if let Some(lsp_logs) = &lsp_logs {
 8334                    lsp_logs.update(cx, |lsp_logs, cx| {
 8335                        lsp_logs.add_language_server(
 8336                            // Only remote clients get their language servers set from proto
 8337                            LanguageServerKind::Remote {
 8338                                project: project.clone(),
 8339                            },
 8340                            server_id,
 8341                            Some(name.clone()),
 8342                            worktree,
 8343                            None,
 8344                            cx,
 8345                        );
 8346                    });
 8347                }
 8348
 8349                (
 8350                    server_id,
 8351                    LanguageServerStatus {
 8352                        name,
 8353                        pending_work: Default::default(),
 8354                        has_pending_diagnostic_updates: false,
 8355                        progress_tokens: Default::default(),
 8356                        worktree,
 8357                        binary: None,
 8358                        configuration: None,
 8359                        workspace_folders: BTreeSet::new(),
 8360                    },
 8361                )
 8362            })
 8363            .collect();
 8364    }
 8365
 8366    #[cfg(test)]
 8367    pub fn update_diagnostic_entries(
 8368        &mut self,
 8369        server_id: LanguageServerId,
 8370        abs_path: PathBuf,
 8371        result_id: Option<SharedString>,
 8372        version: Option<i32>,
 8373        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8374        cx: &mut Context<Self>,
 8375    ) -> anyhow::Result<()> {
 8376        self.merge_diagnostic_entries(
 8377            vec![DocumentDiagnosticsUpdate {
 8378                diagnostics: DocumentDiagnostics {
 8379                    diagnostics,
 8380                    document_abs_path: abs_path,
 8381                    version,
 8382                },
 8383                result_id,
 8384                server_id,
 8385                disk_based_sources: Cow::Borrowed(&[]),
 8386                registration_id: None,
 8387            }],
 8388            |_, _, _| false,
 8389            cx,
 8390        )?;
 8391        Ok(())
 8392    }
 8393
 8394    pub fn merge_diagnostic_entries<'a>(
 8395        &mut self,
 8396        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8397        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8398        cx: &mut Context<Self>,
 8399    ) -> anyhow::Result<()> {
 8400        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8401        let mut updated_diagnostics_paths = HashMap::default();
 8402        for mut update in diagnostic_updates {
 8403            let abs_path = &update.diagnostics.document_abs_path;
 8404            let server_id = update.server_id;
 8405            let Some((worktree, relative_path)) =
 8406                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8407            else {
 8408                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8409                return Ok(());
 8410            };
 8411
 8412            let worktree_id = worktree.read(cx).id();
 8413            let project_path = ProjectPath {
 8414                worktree_id,
 8415                path: relative_path,
 8416            };
 8417
 8418            let document_uri = lsp::Uri::from_file_path(abs_path)
 8419                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8420            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8421                let snapshot = buffer_handle.read(cx).snapshot();
 8422                let buffer = buffer_handle.read(cx);
 8423                let reused_diagnostics = buffer
 8424                    .buffer_diagnostics(Some(server_id))
 8425                    .iter()
 8426                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8427                    .map(|v| {
 8428                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8429                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8430                        DiagnosticEntry {
 8431                            range: start..end,
 8432                            diagnostic: v.diagnostic.clone(),
 8433                        }
 8434                    })
 8435                    .collect::<Vec<_>>();
 8436
 8437                self.as_local_mut()
 8438                    .context("cannot merge diagnostics on a remote LspStore")?
 8439                    .update_buffer_diagnostics(
 8440                        &buffer_handle,
 8441                        server_id,
 8442                        Some(update.registration_id),
 8443                        update.result_id,
 8444                        update.diagnostics.version,
 8445                        update.diagnostics.diagnostics.clone(),
 8446                        reused_diagnostics.clone(),
 8447                        cx,
 8448                    )?;
 8449
 8450                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8451            } else if let Some(local) = self.as_local() {
 8452                let reused_diagnostics = local
 8453                    .diagnostics
 8454                    .get(&worktree_id)
 8455                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8456                    .and_then(|diagnostics_by_server_id| {
 8457                        diagnostics_by_server_id
 8458                            .binary_search_by_key(&server_id, |e| e.0)
 8459                            .ok()
 8460                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8461                    })
 8462                    .into_iter()
 8463                    .flatten()
 8464                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8465
 8466                update
 8467                    .diagnostics
 8468                    .diagnostics
 8469                    .extend(reused_diagnostics.cloned());
 8470            }
 8471
 8472            let updated = worktree.update(cx, |worktree, cx| {
 8473                self.update_worktree_diagnostics(
 8474                    worktree.id(),
 8475                    server_id,
 8476                    project_path.path.clone(),
 8477                    update.diagnostics.diagnostics,
 8478                    cx,
 8479                )
 8480            })?;
 8481            match updated {
 8482                ControlFlow::Continue(new_summary) => {
 8483                    if let Some((project_id, new_summary)) = new_summary {
 8484                        match &mut diagnostics_summary {
 8485                            Some(diagnostics_summary) => {
 8486                                diagnostics_summary
 8487                                    .more_summaries
 8488                                    .push(proto::DiagnosticSummary {
 8489                                        path: project_path.path.as_ref().to_proto(),
 8490                                        language_server_id: server_id.0 as u64,
 8491                                        error_count: new_summary.error_count,
 8492                                        warning_count: new_summary.warning_count,
 8493                                    })
 8494                            }
 8495                            None => {
 8496                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8497                                    project_id,
 8498                                    worktree_id: worktree_id.to_proto(),
 8499                                    summary: Some(proto::DiagnosticSummary {
 8500                                        path: project_path.path.as_ref().to_proto(),
 8501                                        language_server_id: server_id.0 as u64,
 8502                                        error_count: new_summary.error_count,
 8503                                        warning_count: new_summary.warning_count,
 8504                                    }),
 8505                                    more_summaries: Vec::new(),
 8506                                })
 8507                            }
 8508                        }
 8509                    }
 8510                    updated_diagnostics_paths
 8511                        .entry(server_id)
 8512                        .or_insert_with(Vec::new)
 8513                        .push(project_path);
 8514                }
 8515                ControlFlow::Break(()) => {}
 8516            }
 8517        }
 8518
 8519        if let Some((diagnostics_summary, (downstream_client, _))) =
 8520            diagnostics_summary.zip(self.downstream_client.as_ref())
 8521        {
 8522            downstream_client.send(diagnostics_summary).log_err();
 8523        }
 8524        for (server_id, paths) in updated_diagnostics_paths {
 8525            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8526        }
 8527        Ok(())
 8528    }
 8529
 8530    fn update_worktree_diagnostics(
 8531        &mut self,
 8532        worktree_id: WorktreeId,
 8533        server_id: LanguageServerId,
 8534        path_in_worktree: Arc<RelPath>,
 8535        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8536        _: &mut Context<Worktree>,
 8537    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8538        let local = match &mut self.mode {
 8539            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8540            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8541        };
 8542
 8543        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8544        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8545        let summaries_by_server_id = summaries_for_tree
 8546            .entry(path_in_worktree.clone())
 8547            .or_default();
 8548
 8549        let old_summary = summaries_by_server_id
 8550            .remove(&server_id)
 8551            .unwrap_or_default();
 8552
 8553        let new_summary = DiagnosticSummary::new(&diagnostics);
 8554        if diagnostics.is_empty() {
 8555            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8556            {
 8557                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8558                    diagnostics_by_server_id.remove(ix);
 8559                }
 8560                if diagnostics_by_server_id.is_empty() {
 8561                    diagnostics_for_tree.remove(&path_in_worktree);
 8562                }
 8563            }
 8564        } else {
 8565            summaries_by_server_id.insert(server_id, new_summary);
 8566            let diagnostics_by_server_id = diagnostics_for_tree
 8567                .entry(path_in_worktree.clone())
 8568                .or_default();
 8569            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8570                Ok(ix) => {
 8571                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8572                }
 8573                Err(ix) => {
 8574                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8575                }
 8576            }
 8577        }
 8578
 8579        if !old_summary.is_empty() || !new_summary.is_empty() {
 8580            if let Some((_, project_id)) = &self.downstream_client {
 8581                Ok(ControlFlow::Continue(Some((
 8582                    *project_id,
 8583                    proto::DiagnosticSummary {
 8584                        path: path_in_worktree.to_proto(),
 8585                        language_server_id: server_id.0 as u64,
 8586                        error_count: new_summary.error_count as u32,
 8587                        warning_count: new_summary.warning_count as u32,
 8588                    },
 8589                ))))
 8590            } else {
 8591                Ok(ControlFlow::Continue(None))
 8592            }
 8593        } else {
 8594            Ok(ControlFlow::Break(()))
 8595        }
 8596    }
 8597
 8598    pub fn open_buffer_for_symbol(
 8599        &mut self,
 8600        symbol: &Symbol,
 8601        cx: &mut Context<Self>,
 8602    ) -> Task<Result<Entity<Buffer>>> {
 8603        if let Some((client, project_id)) = self.upstream_client() {
 8604            let request = client.request(proto::OpenBufferForSymbol {
 8605                project_id,
 8606                symbol: Some(Self::serialize_symbol(symbol)),
 8607            });
 8608            cx.spawn(async move |this, cx| {
 8609                let response = request.await?;
 8610                let buffer_id = BufferId::new(response.buffer_id)?;
 8611                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8612                    .await
 8613            })
 8614        } else if let Some(local) = self.as_local() {
 8615            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8616                seed.worktree_id == symbol.source_worktree_id
 8617                    && state.id == symbol.source_language_server_id
 8618                    && symbol.language_server_name == seed.name
 8619            });
 8620            if !is_valid {
 8621                return Task::ready(Err(anyhow!(
 8622                    "language server for worktree and language not found"
 8623                )));
 8624            };
 8625
 8626            let symbol_abs_path = match &symbol.path {
 8627                SymbolLocation::InProject(project_path) => self
 8628                    .worktree_store
 8629                    .read(cx)
 8630                    .absolutize(&project_path, cx)
 8631                    .context("no such worktree"),
 8632                SymbolLocation::OutsideProject {
 8633                    abs_path,
 8634                    signature: _,
 8635                } => Ok(abs_path.to_path_buf()),
 8636            };
 8637            let symbol_abs_path = match symbol_abs_path {
 8638                Ok(abs_path) => abs_path,
 8639                Err(err) => return Task::ready(Err(err)),
 8640            };
 8641            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8642                uri
 8643            } else {
 8644                return Task::ready(Err(anyhow!("invalid symbol path")));
 8645            };
 8646
 8647            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8648        } else {
 8649            Task::ready(Err(anyhow!("no upstream client or local store")))
 8650        }
 8651    }
 8652
 8653    pub(crate) fn open_local_buffer_via_lsp(
 8654        &mut self,
 8655        abs_path: lsp::Uri,
 8656        language_server_id: LanguageServerId,
 8657        cx: &mut Context<Self>,
 8658    ) -> Task<Result<Entity<Buffer>>> {
 8659        cx.spawn(async move |lsp_store, cx| {
 8660            // Escape percent-encoded string.
 8661            let current_scheme = abs_path.scheme().to_owned();
 8662            // Uri is immutable, so we can't modify the scheme
 8663
 8664            let abs_path = abs_path
 8665                .to_file_path()
 8666                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8667            let p = abs_path.clone();
 8668            let yarn_worktree = lsp_store
 8669                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8670                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8671                        cx.spawn(async move |this, cx| {
 8672                            let t = this
 8673                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8674                                .ok()?;
 8675                            t.await
 8676                        })
 8677                    }),
 8678                    None => Task::ready(None),
 8679                })?
 8680                .await;
 8681            let (worktree_root_target, known_relative_path) =
 8682                if let Some((zip_root, relative_path)) = yarn_worktree {
 8683                    (zip_root, Some(relative_path))
 8684                } else {
 8685                    (Arc::<Path>::from(abs_path.as_path()), None)
 8686                };
 8687            let (worktree, relative_path) = if let Some(result) =
 8688                lsp_store.update(cx, |lsp_store, cx| {
 8689                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8690                        worktree_store.find_worktree(&worktree_root_target, cx)
 8691                    })
 8692                })? {
 8693                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8694                (result.0, relative_path)
 8695            } else {
 8696                let worktree = lsp_store
 8697                    .update(cx, |lsp_store, cx| {
 8698                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8699                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8700                        })
 8701                    })?
 8702                    .await?;
 8703                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8704                    lsp_store
 8705                        .update(cx, |lsp_store, cx| {
 8706                            if let Some(local) = lsp_store.as_local_mut() {
 8707                                local.register_language_server_for_invisible_worktree(
 8708                                    &worktree,
 8709                                    language_server_id,
 8710                                    cx,
 8711                                )
 8712                            }
 8713                        })
 8714                        .ok();
 8715                }
 8716                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8717                let relative_path = if let Some(known_path) = known_relative_path {
 8718                    known_path
 8719                } else {
 8720                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8721                        .into_arc()
 8722                };
 8723                (worktree, relative_path)
 8724            };
 8725            let project_path = ProjectPath {
 8726                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8727                path: relative_path,
 8728            };
 8729            lsp_store
 8730                .update(cx, |lsp_store, cx| {
 8731                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8732                        buffer_store.open_buffer(project_path, cx)
 8733                    })
 8734                })?
 8735                .await
 8736        })
 8737    }
 8738
 8739    fn request_multiple_lsp_locally<P, R>(
 8740        &mut self,
 8741        buffer: &Entity<Buffer>,
 8742        position: Option<P>,
 8743        request: R,
 8744        cx: &mut Context<Self>,
 8745    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8746    where
 8747        P: ToOffset,
 8748        R: LspCommand + Clone,
 8749        <R::LspRequest as lsp::request::Request>::Result: Send,
 8750        <R::LspRequest as lsp::request::Request>::Params: Send,
 8751    {
 8752        let Some(local) = self.as_local() else {
 8753            return Task::ready(Vec::new());
 8754        };
 8755
 8756        let snapshot = buffer.read(cx).snapshot();
 8757        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8758
 8759        let server_ids = buffer.update(cx, |buffer, cx| {
 8760            local
 8761                .language_servers_for_buffer(buffer, cx)
 8762                .filter(|(adapter, _)| {
 8763                    scope
 8764                        .as_ref()
 8765                        .map(|scope| scope.language_allowed(&adapter.name))
 8766                        .unwrap_or(true)
 8767                })
 8768                .map(|(_, server)| server.server_id())
 8769                .filter(|server_id| {
 8770                    self.as_local().is_none_or(|local| {
 8771                        local
 8772                            .buffers_opened_in_servers
 8773                            .get(&snapshot.remote_id())
 8774                            .is_some_and(|servers| servers.contains(server_id))
 8775                    })
 8776                })
 8777                .collect::<Vec<_>>()
 8778        });
 8779
 8780        let mut response_results = server_ids
 8781            .into_iter()
 8782            .map(|server_id| {
 8783                let task = self.request_lsp(
 8784                    buffer.clone(),
 8785                    LanguageServerToQuery::Other(server_id),
 8786                    request.clone(),
 8787                    cx,
 8788                );
 8789                async move { (server_id, task.await) }
 8790            })
 8791            .collect::<FuturesUnordered<_>>();
 8792
 8793        cx.background_spawn(async move {
 8794            let mut responses = Vec::with_capacity(response_results.len());
 8795            while let Some((server_id, response_result)) = response_results.next().await {
 8796                match response_result {
 8797                    Ok(response) => responses.push((server_id, response)),
 8798                    // rust-analyzer likes to error with this when its still loading up
 8799                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8800                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8801                }
 8802            }
 8803            responses
 8804        })
 8805    }
 8806
 8807    async fn handle_lsp_get_completions(
 8808        this: Entity<Self>,
 8809        envelope: TypedEnvelope<proto::GetCompletions>,
 8810        mut cx: AsyncApp,
 8811    ) -> Result<proto::GetCompletionsResponse> {
 8812        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8813
 8814        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8815        let buffer_handle = this.update(&mut cx, |this, cx| {
 8816            this.buffer_store.read(cx).get_existing(buffer_id)
 8817        })??;
 8818        let request = GetCompletions::from_proto(
 8819            envelope.payload,
 8820            this.clone(),
 8821            buffer_handle.clone(),
 8822            cx.clone(),
 8823        )
 8824        .await?;
 8825
 8826        let server_to_query = match request.server_id {
 8827            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8828            None => LanguageServerToQuery::FirstCapable,
 8829        };
 8830
 8831        let response = this
 8832            .update(&mut cx, |this, cx| {
 8833                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8834            })?
 8835            .await?;
 8836        this.update(&mut cx, |this, cx| {
 8837            Ok(GetCompletions::response_to_proto(
 8838                response,
 8839                this,
 8840                sender_id,
 8841                &buffer_handle.read(cx).version(),
 8842                cx,
 8843            ))
 8844        })?
 8845    }
 8846
 8847    async fn handle_lsp_command<T: LspCommand>(
 8848        this: Entity<Self>,
 8849        envelope: TypedEnvelope<T::ProtoRequest>,
 8850        mut cx: AsyncApp,
 8851    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8852    where
 8853        <T::LspRequest as lsp::request::Request>::Params: Send,
 8854        <T::LspRequest as lsp::request::Request>::Result: Send,
 8855    {
 8856        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8857        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8858        let buffer_handle = this.update(&mut cx, |this, cx| {
 8859            this.buffer_store.read(cx).get_existing(buffer_id)
 8860        })??;
 8861        let request = T::from_proto(
 8862            envelope.payload,
 8863            this.clone(),
 8864            buffer_handle.clone(),
 8865            cx.clone(),
 8866        )
 8867        .await?;
 8868        let response = this
 8869            .update(&mut cx, |this, cx| {
 8870                this.request_lsp(
 8871                    buffer_handle.clone(),
 8872                    LanguageServerToQuery::FirstCapable,
 8873                    request,
 8874                    cx,
 8875                )
 8876            })?
 8877            .await?;
 8878        this.update(&mut cx, |this, cx| {
 8879            Ok(T::response_to_proto(
 8880                response,
 8881                this,
 8882                sender_id,
 8883                &buffer_handle.read(cx).version(),
 8884                cx,
 8885            ))
 8886        })?
 8887    }
 8888
 8889    async fn handle_lsp_query(
 8890        lsp_store: Entity<Self>,
 8891        envelope: TypedEnvelope<proto::LspQuery>,
 8892        mut cx: AsyncApp,
 8893    ) -> Result<proto::Ack> {
 8894        use proto::lsp_query::Request;
 8895        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8896        let lsp_query = envelope.payload;
 8897        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8898        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8899        match lsp_query.request.context("invalid LSP query request")? {
 8900            Request::GetReferences(get_references) => {
 8901                let position = get_references.position.clone().and_then(deserialize_anchor);
 8902                Self::query_lsp_locally::<GetReferences>(
 8903                    lsp_store,
 8904                    server_id,
 8905                    sender_id,
 8906                    lsp_request_id,
 8907                    get_references,
 8908                    position,
 8909                    &mut cx,
 8910                )
 8911                .await?;
 8912            }
 8913            Request::GetDocumentColor(get_document_color) => {
 8914                Self::query_lsp_locally::<GetDocumentColor>(
 8915                    lsp_store,
 8916                    server_id,
 8917                    sender_id,
 8918                    lsp_request_id,
 8919                    get_document_color,
 8920                    None,
 8921                    &mut cx,
 8922                )
 8923                .await?;
 8924            }
 8925            Request::GetHover(get_hover) => {
 8926                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8927                Self::query_lsp_locally::<GetHover>(
 8928                    lsp_store,
 8929                    server_id,
 8930                    sender_id,
 8931                    lsp_request_id,
 8932                    get_hover,
 8933                    position,
 8934                    &mut cx,
 8935                )
 8936                .await?;
 8937            }
 8938            Request::GetCodeActions(get_code_actions) => {
 8939                Self::query_lsp_locally::<GetCodeActions>(
 8940                    lsp_store,
 8941                    server_id,
 8942                    sender_id,
 8943                    lsp_request_id,
 8944                    get_code_actions,
 8945                    None,
 8946                    &mut cx,
 8947                )
 8948                .await?;
 8949            }
 8950            Request::GetSignatureHelp(get_signature_help) => {
 8951                let position = get_signature_help
 8952                    .position
 8953                    .clone()
 8954                    .and_then(deserialize_anchor);
 8955                Self::query_lsp_locally::<GetSignatureHelp>(
 8956                    lsp_store,
 8957                    server_id,
 8958                    sender_id,
 8959                    lsp_request_id,
 8960                    get_signature_help,
 8961                    position,
 8962                    &mut cx,
 8963                )
 8964                .await?;
 8965            }
 8966            Request::GetCodeLens(get_code_lens) => {
 8967                Self::query_lsp_locally::<GetCodeLens>(
 8968                    lsp_store,
 8969                    server_id,
 8970                    sender_id,
 8971                    lsp_request_id,
 8972                    get_code_lens,
 8973                    None,
 8974                    &mut cx,
 8975                )
 8976                .await?;
 8977            }
 8978            Request::GetDefinition(get_definition) => {
 8979                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8980                Self::query_lsp_locally::<GetDefinitions>(
 8981                    lsp_store,
 8982                    server_id,
 8983                    sender_id,
 8984                    lsp_request_id,
 8985                    get_definition,
 8986                    position,
 8987                    &mut cx,
 8988                )
 8989                .await?;
 8990            }
 8991            Request::GetDeclaration(get_declaration) => {
 8992                let position = get_declaration
 8993                    .position
 8994                    .clone()
 8995                    .and_then(deserialize_anchor);
 8996                Self::query_lsp_locally::<GetDeclarations>(
 8997                    lsp_store,
 8998                    server_id,
 8999                    sender_id,
 9000                    lsp_request_id,
 9001                    get_declaration,
 9002                    position,
 9003                    &mut cx,
 9004                )
 9005                .await?;
 9006            }
 9007            Request::GetTypeDefinition(get_type_definition) => {
 9008                let position = get_type_definition
 9009                    .position
 9010                    .clone()
 9011                    .and_then(deserialize_anchor);
 9012                Self::query_lsp_locally::<GetTypeDefinitions>(
 9013                    lsp_store,
 9014                    server_id,
 9015                    sender_id,
 9016                    lsp_request_id,
 9017                    get_type_definition,
 9018                    position,
 9019                    &mut cx,
 9020                )
 9021                .await?;
 9022            }
 9023            Request::GetImplementation(get_implementation) => {
 9024                let position = get_implementation
 9025                    .position
 9026                    .clone()
 9027                    .and_then(deserialize_anchor);
 9028                Self::query_lsp_locally::<GetImplementations>(
 9029                    lsp_store,
 9030                    server_id,
 9031                    sender_id,
 9032                    lsp_request_id,
 9033                    get_implementation,
 9034                    position,
 9035                    &mut cx,
 9036                )
 9037                .await?;
 9038            }
 9039            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9040                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 9041                let version = deserialize_version(get_document_diagnostics.buffer_version());
 9042                let buffer = lsp_store.update(&mut cx, |this, cx| {
 9043                    this.buffer_store.read(cx).get_existing(buffer_id)
 9044                })??;
 9045                buffer
 9046                    .update(&mut cx, |buffer, _| {
 9047                        buffer.wait_for_version(version.clone())
 9048                    })?
 9049                    .await?;
 9050                lsp_store.update(&mut cx, |lsp_store, cx| {
 9051                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9052                    let key = LspKey {
 9053                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9054                        server_queried: server_id,
 9055                    };
 9056                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9057                    ) {
 9058                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9059                            lsp_requests.clear();
 9060                        };
 9061                    }
 9062
 9063                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 9064                    existing_queries.insert(
 9065                        lsp_request_id,
 9066                        cx.spawn(async move |lsp_store, cx| {
 9067                            let diagnostics_pull = lsp_store
 9068                                .update(cx, |lsp_store, cx| {
 9069                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9070                                })
 9071                                .ok();
 9072                            if let Some(diagnostics_pull) = diagnostics_pull {
 9073                                match diagnostics_pull.await {
 9074                                    Ok(()) => {}
 9075                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9076                                };
 9077                            }
 9078                        }),
 9079                    );
 9080                })?;
 9081            }
 9082            Request::InlayHints(inlay_hints) => {
 9083                let query_start = inlay_hints
 9084                    .start
 9085                    .clone()
 9086                    .and_then(deserialize_anchor)
 9087                    .context("invalid inlay hints range start")?;
 9088                let query_end = inlay_hints
 9089                    .end
 9090                    .clone()
 9091                    .and_then(deserialize_anchor)
 9092                    .context("invalid inlay hints range end")?;
 9093                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9094                    &lsp_store,
 9095                    server_id,
 9096                    lsp_request_id,
 9097                    &inlay_hints,
 9098                    query_start..query_end,
 9099                    &mut cx,
 9100                )
 9101                .await
 9102                .context("preparing inlay hints request")?;
 9103                Self::query_lsp_locally::<InlayHints>(
 9104                    lsp_store,
 9105                    server_id,
 9106                    sender_id,
 9107                    lsp_request_id,
 9108                    inlay_hints,
 9109                    None,
 9110                    &mut cx,
 9111                )
 9112                .await
 9113                .context("querying for inlay hints")?
 9114            }
 9115        }
 9116        Ok(proto::Ack {})
 9117    }
 9118
 9119    async fn handle_lsp_query_response(
 9120        lsp_store: Entity<Self>,
 9121        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9122        cx: AsyncApp,
 9123    ) -> Result<()> {
 9124        lsp_store.read_with(&cx, |lsp_store, _| {
 9125            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9126                upstream_client.handle_lsp_response(envelope.clone());
 9127            }
 9128        })?;
 9129        Ok(())
 9130    }
 9131
 9132    async fn handle_apply_code_action(
 9133        this: Entity<Self>,
 9134        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9135        mut cx: AsyncApp,
 9136    ) -> Result<proto::ApplyCodeActionResponse> {
 9137        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9138        let action =
 9139            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9140        let apply_code_action = this.update(&mut cx, |this, cx| {
 9141            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9142            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9143            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9144        })??;
 9145
 9146        let project_transaction = apply_code_action.await?;
 9147        let project_transaction = this.update(&mut cx, |this, cx| {
 9148            this.buffer_store.update(cx, |buffer_store, cx| {
 9149                buffer_store.serialize_project_transaction_for_peer(
 9150                    project_transaction,
 9151                    sender_id,
 9152                    cx,
 9153                )
 9154            })
 9155        })?;
 9156        Ok(proto::ApplyCodeActionResponse {
 9157            transaction: Some(project_transaction),
 9158        })
 9159    }
 9160
 9161    async fn handle_register_buffer_with_language_servers(
 9162        this: Entity<Self>,
 9163        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9164        mut cx: AsyncApp,
 9165    ) -> Result<proto::Ack> {
 9166        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9167        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9168        this.update(&mut cx, |this, cx| {
 9169            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9170                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9171                    project_id: upstream_project_id,
 9172                    buffer_id: buffer_id.to_proto(),
 9173                    only_servers: envelope.payload.only_servers,
 9174                });
 9175            }
 9176
 9177            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9178                anyhow::bail!("buffer is not open");
 9179            };
 9180
 9181            let handle = this.register_buffer_with_language_servers(
 9182                &buffer,
 9183                envelope
 9184                    .payload
 9185                    .only_servers
 9186                    .into_iter()
 9187                    .filter_map(|selector| {
 9188                        Some(match selector.selector? {
 9189                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9190                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9191                            }
 9192                            proto::language_server_selector::Selector::Name(name) => {
 9193                                LanguageServerSelector::Name(LanguageServerName(
 9194                                    SharedString::from(name),
 9195                                ))
 9196                            }
 9197                        })
 9198                    })
 9199                    .collect(),
 9200                false,
 9201                cx,
 9202            );
 9203            this.buffer_store().update(cx, |buffer_store, _| {
 9204                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9205            });
 9206
 9207            Ok(())
 9208        })??;
 9209        Ok(proto::Ack {})
 9210    }
 9211
 9212    async fn handle_rename_project_entry(
 9213        this: Entity<Self>,
 9214        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9215        mut cx: AsyncApp,
 9216    ) -> Result<proto::ProjectEntryResponse> {
 9217        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9218        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9219        let new_path =
 9220            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9221
 9222        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9223            .update(&mut cx, |this, cx| {
 9224                let (worktree, entry) = this
 9225                    .worktree_store
 9226                    .read(cx)
 9227                    .worktree_and_entry_for_id(entry_id, cx)?;
 9228                let new_worktree = this
 9229                    .worktree_store
 9230                    .read(cx)
 9231                    .worktree_for_id(new_worktree_id, cx)?;
 9232                Some((
 9233                    this.worktree_store.clone(),
 9234                    worktree,
 9235                    new_worktree,
 9236                    entry.clone(),
 9237                ))
 9238            })?
 9239            .context("worktree not found")?;
 9240        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9241            (worktree.absolutize(&old_entry.path), worktree.id())
 9242        })?;
 9243        let new_abs_path =
 9244            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 9245
 9246        let _transaction = Self::will_rename_entry(
 9247            this.downgrade(),
 9248            old_worktree_id,
 9249            &old_abs_path,
 9250            &new_abs_path,
 9251            old_entry.is_dir(),
 9252            cx.clone(),
 9253        )
 9254        .await;
 9255        let response = WorktreeStore::handle_rename_project_entry(
 9256            worktree_store,
 9257            envelope.payload,
 9258            cx.clone(),
 9259        )
 9260        .await;
 9261        this.read_with(&cx, |this, _| {
 9262            this.did_rename_entry(
 9263                old_worktree_id,
 9264                &old_abs_path,
 9265                &new_abs_path,
 9266                old_entry.is_dir(),
 9267            );
 9268        })
 9269        .ok();
 9270        response
 9271    }
 9272
 9273    async fn handle_update_diagnostic_summary(
 9274        this: Entity<Self>,
 9275        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9276        mut cx: AsyncApp,
 9277    ) -> Result<()> {
 9278        this.update(&mut cx, |lsp_store, cx| {
 9279            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9280            let mut updated_diagnostics_paths = HashMap::default();
 9281            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9282            for message_summary in envelope
 9283                .payload
 9284                .summary
 9285                .into_iter()
 9286                .chain(envelope.payload.more_summaries)
 9287            {
 9288                let project_path = ProjectPath {
 9289                    worktree_id,
 9290                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9291                };
 9292                let path = project_path.path.clone();
 9293                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9294                let summary = DiagnosticSummary {
 9295                    error_count: message_summary.error_count as usize,
 9296                    warning_count: message_summary.warning_count as usize,
 9297                };
 9298
 9299                if summary.is_empty() {
 9300                    if let Some(worktree_summaries) =
 9301                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9302                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9303                    {
 9304                        summaries.remove(&server_id);
 9305                        if summaries.is_empty() {
 9306                            worktree_summaries.remove(&path);
 9307                        }
 9308                    }
 9309                } else {
 9310                    lsp_store
 9311                        .diagnostic_summaries
 9312                        .entry(worktree_id)
 9313                        .or_default()
 9314                        .entry(path)
 9315                        .or_default()
 9316                        .insert(server_id, summary);
 9317                }
 9318
 9319                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9320                    match &mut diagnostics_summary {
 9321                        Some(diagnostics_summary) => {
 9322                            diagnostics_summary
 9323                                .more_summaries
 9324                                .push(proto::DiagnosticSummary {
 9325                                    path: project_path.path.as_ref().to_proto(),
 9326                                    language_server_id: server_id.0 as u64,
 9327                                    error_count: summary.error_count as u32,
 9328                                    warning_count: summary.warning_count as u32,
 9329                                })
 9330                        }
 9331                        None => {
 9332                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9333                                project_id: *project_id,
 9334                                worktree_id: worktree_id.to_proto(),
 9335                                summary: Some(proto::DiagnosticSummary {
 9336                                    path: project_path.path.as_ref().to_proto(),
 9337                                    language_server_id: server_id.0 as u64,
 9338                                    error_count: summary.error_count as u32,
 9339                                    warning_count: summary.warning_count as u32,
 9340                                }),
 9341                                more_summaries: Vec::new(),
 9342                            })
 9343                        }
 9344                    }
 9345                }
 9346                updated_diagnostics_paths
 9347                    .entry(server_id)
 9348                    .or_insert_with(Vec::new)
 9349                    .push(project_path);
 9350            }
 9351
 9352            if let Some((diagnostics_summary, (downstream_client, _))) =
 9353                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9354            {
 9355                downstream_client.send(diagnostics_summary).log_err();
 9356            }
 9357            for (server_id, paths) in updated_diagnostics_paths {
 9358                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9359            }
 9360            Ok(())
 9361        })?
 9362    }
 9363
 9364    async fn handle_start_language_server(
 9365        lsp_store: Entity<Self>,
 9366        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9367        mut cx: AsyncApp,
 9368    ) -> Result<()> {
 9369        let server = envelope.payload.server.context("invalid server")?;
 9370        let server_capabilities =
 9371            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9372                .with_context(|| {
 9373                    format!(
 9374                        "incorrect server capabilities {}",
 9375                        envelope.payload.capabilities
 9376                    )
 9377                })?;
 9378        lsp_store.update(&mut cx, |lsp_store, cx| {
 9379            let server_id = LanguageServerId(server.id as usize);
 9380            let server_name = LanguageServerName::from_proto(server.name.clone());
 9381            lsp_store
 9382                .lsp_server_capabilities
 9383                .insert(server_id, server_capabilities);
 9384            lsp_store.language_server_statuses.insert(
 9385                server_id,
 9386                LanguageServerStatus {
 9387                    name: server_name.clone(),
 9388                    pending_work: Default::default(),
 9389                    has_pending_diagnostic_updates: false,
 9390                    progress_tokens: Default::default(),
 9391                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9392                    binary: None,
 9393                    configuration: None,
 9394                    workspace_folders: BTreeSet::new(),
 9395                },
 9396            );
 9397            cx.emit(LspStoreEvent::LanguageServerAdded(
 9398                server_id,
 9399                server_name,
 9400                server.worktree_id.map(WorktreeId::from_proto),
 9401            ));
 9402            cx.notify();
 9403        })?;
 9404        Ok(())
 9405    }
 9406
 9407    async fn handle_update_language_server(
 9408        lsp_store: Entity<Self>,
 9409        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9410        mut cx: AsyncApp,
 9411    ) -> Result<()> {
 9412        lsp_store.update(&mut cx, |lsp_store, cx| {
 9413            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9414
 9415            match envelope.payload.variant.context("invalid variant")? {
 9416                proto::update_language_server::Variant::WorkStart(payload) => {
 9417                    lsp_store.on_lsp_work_start(
 9418                        language_server_id,
 9419                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9420                            .context("invalid progress token value")?,
 9421                        LanguageServerProgress {
 9422                            title: payload.title,
 9423                            is_disk_based_diagnostics_progress: false,
 9424                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9425                            message: payload.message,
 9426                            percentage: payload.percentage.map(|p| p as usize),
 9427                            last_update_at: cx.background_executor().now(),
 9428                        },
 9429                        cx,
 9430                    );
 9431                }
 9432                proto::update_language_server::Variant::WorkProgress(payload) => {
 9433                    lsp_store.on_lsp_work_progress(
 9434                        language_server_id,
 9435                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9436                            .context("invalid progress token value")?,
 9437                        LanguageServerProgress {
 9438                            title: None,
 9439                            is_disk_based_diagnostics_progress: false,
 9440                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9441                            message: payload.message,
 9442                            percentage: payload.percentage.map(|p| p as usize),
 9443                            last_update_at: cx.background_executor().now(),
 9444                        },
 9445                        cx,
 9446                    );
 9447                }
 9448
 9449                proto::update_language_server::Variant::WorkEnd(payload) => {
 9450                    lsp_store.on_lsp_work_end(
 9451                        language_server_id,
 9452                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9453                            .context("invalid progress token value")?,
 9454                        cx,
 9455                    );
 9456                }
 9457
 9458                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9459                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9460                }
 9461
 9462                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9463                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9464                }
 9465
 9466                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9467                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9468                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9469                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9470                        language_server_id,
 9471                        name: envelope
 9472                            .payload
 9473                            .server_name
 9474                            .map(SharedString::new)
 9475                            .map(LanguageServerName),
 9476                        message: non_lsp,
 9477                    });
 9478                }
 9479            }
 9480
 9481            Ok(())
 9482        })?
 9483    }
 9484
 9485    async fn handle_language_server_log(
 9486        this: Entity<Self>,
 9487        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9488        mut cx: AsyncApp,
 9489    ) -> Result<()> {
 9490        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9491        let log_type = envelope
 9492            .payload
 9493            .log_type
 9494            .map(LanguageServerLogType::from_proto)
 9495            .context("invalid language server log type")?;
 9496
 9497        let message = envelope.payload.message;
 9498
 9499        this.update(&mut cx, |_, cx| {
 9500            cx.emit(LspStoreEvent::LanguageServerLog(
 9501                language_server_id,
 9502                log_type,
 9503                message,
 9504            ));
 9505        })
 9506    }
 9507
 9508    async fn handle_lsp_ext_cancel_flycheck(
 9509        lsp_store: Entity<Self>,
 9510        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9511        cx: AsyncApp,
 9512    ) -> Result<proto::Ack> {
 9513        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9514        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9515            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9516                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9517            } else {
 9518                None
 9519            }
 9520        })?;
 9521        if let Some(task) = task {
 9522            task.context("handling lsp ext cancel flycheck")?;
 9523        }
 9524
 9525        Ok(proto::Ack {})
 9526    }
 9527
 9528    async fn handle_lsp_ext_run_flycheck(
 9529        lsp_store: Entity<Self>,
 9530        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9531        mut cx: AsyncApp,
 9532    ) -> Result<proto::Ack> {
 9533        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9534        lsp_store.update(&mut cx, |lsp_store, cx| {
 9535            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9536                let text_document = if envelope.payload.current_file_only {
 9537                    let buffer_id = envelope
 9538                        .payload
 9539                        .buffer_id
 9540                        .map(|id| BufferId::new(id))
 9541                        .transpose()?;
 9542                    buffer_id
 9543                        .and_then(|buffer_id| {
 9544                            lsp_store
 9545                                .buffer_store()
 9546                                .read(cx)
 9547                                .get(buffer_id)
 9548                                .and_then(|buffer| {
 9549                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9550                                })
 9551                                .map(|path| make_text_document_identifier(&path))
 9552                        })
 9553                        .transpose()?
 9554                } else {
 9555                    None
 9556                };
 9557                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9558                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9559                )?;
 9560            }
 9561            anyhow::Ok(())
 9562        })??;
 9563
 9564        Ok(proto::Ack {})
 9565    }
 9566
 9567    async fn handle_lsp_ext_clear_flycheck(
 9568        lsp_store: Entity<Self>,
 9569        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9570        cx: AsyncApp,
 9571    ) -> Result<proto::Ack> {
 9572        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9573        lsp_store
 9574            .read_with(&cx, |lsp_store, _| {
 9575                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9576                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9577                } else {
 9578                    None
 9579                }
 9580            })
 9581            .context("handling lsp ext clear flycheck")?;
 9582
 9583        Ok(proto::Ack {})
 9584    }
 9585
 9586    pub fn disk_based_diagnostics_started(
 9587        &mut self,
 9588        language_server_id: LanguageServerId,
 9589        cx: &mut Context<Self>,
 9590    ) {
 9591        if let Some(language_server_status) =
 9592            self.language_server_statuses.get_mut(&language_server_id)
 9593        {
 9594            language_server_status.has_pending_diagnostic_updates = true;
 9595        }
 9596
 9597        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9598        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9599            language_server_id,
 9600            name: self
 9601                .language_server_adapter_for_id(language_server_id)
 9602                .map(|adapter| adapter.name()),
 9603            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9604                Default::default(),
 9605            ),
 9606        })
 9607    }
 9608
 9609    pub fn disk_based_diagnostics_finished(
 9610        &mut self,
 9611        language_server_id: LanguageServerId,
 9612        cx: &mut Context<Self>,
 9613    ) {
 9614        if let Some(language_server_status) =
 9615            self.language_server_statuses.get_mut(&language_server_id)
 9616        {
 9617            language_server_status.has_pending_diagnostic_updates = false;
 9618        }
 9619
 9620        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9621        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9622            language_server_id,
 9623            name: self
 9624                .language_server_adapter_for_id(language_server_id)
 9625                .map(|adapter| adapter.name()),
 9626            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9627                Default::default(),
 9628            ),
 9629        })
 9630    }
 9631
 9632    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9633    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9634    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9635    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9636    // the language server might take some time to publish diagnostics.
 9637    fn simulate_disk_based_diagnostics_events_if_needed(
 9638        &mut self,
 9639        language_server_id: LanguageServerId,
 9640        cx: &mut Context<Self>,
 9641    ) {
 9642        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9643
 9644        let Some(LanguageServerState::Running {
 9645            simulate_disk_based_diagnostics_completion,
 9646            adapter,
 9647            ..
 9648        }) = self
 9649            .as_local_mut()
 9650            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9651        else {
 9652            return;
 9653        };
 9654
 9655        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9656            return;
 9657        }
 9658
 9659        let prev_task =
 9660            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9661                cx.background_executor()
 9662                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9663                    .await;
 9664
 9665                this.update(cx, |this, cx| {
 9666                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9667
 9668                    if let Some(LanguageServerState::Running {
 9669                        simulate_disk_based_diagnostics_completion,
 9670                        ..
 9671                    }) = this.as_local_mut().and_then(|local_store| {
 9672                        local_store.language_servers.get_mut(&language_server_id)
 9673                    }) {
 9674                        *simulate_disk_based_diagnostics_completion = None;
 9675                    }
 9676                })
 9677                .ok();
 9678            }));
 9679
 9680        if prev_task.is_none() {
 9681            self.disk_based_diagnostics_started(language_server_id, cx);
 9682        }
 9683    }
 9684
 9685    pub fn language_server_statuses(
 9686        &self,
 9687    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9688        self.language_server_statuses
 9689            .iter()
 9690            .map(|(key, value)| (*key, value))
 9691    }
 9692
 9693    pub(super) fn did_rename_entry(
 9694        &self,
 9695        worktree_id: WorktreeId,
 9696        old_path: &Path,
 9697        new_path: &Path,
 9698        is_dir: bool,
 9699    ) {
 9700        maybe!({
 9701            let local_store = self.as_local()?;
 9702
 9703            let old_uri = lsp::Uri::from_file_path(old_path)
 9704                .ok()
 9705                .map(|uri| uri.to_string())?;
 9706            let new_uri = lsp::Uri::from_file_path(new_path)
 9707                .ok()
 9708                .map(|uri| uri.to_string())?;
 9709
 9710            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9711                let Some(filter) = local_store
 9712                    .language_server_paths_watched_for_rename
 9713                    .get(&language_server.server_id())
 9714                else {
 9715                    continue;
 9716                };
 9717
 9718                if filter.should_send_did_rename(&old_uri, is_dir) {
 9719                    language_server
 9720                        .notify::<DidRenameFiles>(RenameFilesParams {
 9721                            files: vec![FileRename {
 9722                                old_uri: old_uri.clone(),
 9723                                new_uri: new_uri.clone(),
 9724                            }],
 9725                        })
 9726                        .ok();
 9727                }
 9728            }
 9729            Some(())
 9730        });
 9731    }
 9732
 9733    pub(super) fn will_rename_entry(
 9734        this: WeakEntity<Self>,
 9735        worktree_id: WorktreeId,
 9736        old_path: &Path,
 9737        new_path: &Path,
 9738        is_dir: bool,
 9739        cx: AsyncApp,
 9740    ) -> Task<ProjectTransaction> {
 9741        let old_uri = lsp::Uri::from_file_path(old_path)
 9742            .ok()
 9743            .map(|uri| uri.to_string());
 9744        let new_uri = lsp::Uri::from_file_path(new_path)
 9745            .ok()
 9746            .map(|uri| uri.to_string());
 9747        cx.spawn(async move |cx| {
 9748            let mut tasks = vec![];
 9749            this.update(cx, |this, cx| {
 9750                let local_store = this.as_local()?;
 9751                let old_uri = old_uri?;
 9752                let new_uri = new_uri?;
 9753                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9754                    let Some(filter) = local_store
 9755                        .language_server_paths_watched_for_rename
 9756                        .get(&language_server.server_id())
 9757                    else {
 9758                        continue;
 9759                    };
 9760
 9761                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9762                        let apply_edit = cx.spawn({
 9763                            let old_uri = old_uri.clone();
 9764                            let new_uri = new_uri.clone();
 9765                            let language_server = language_server.clone();
 9766                            async move |this, cx| {
 9767                                let edit = language_server
 9768                                    .request::<WillRenameFiles>(RenameFilesParams {
 9769                                        files: vec![FileRename { old_uri, new_uri }],
 9770                                    })
 9771                                    .await
 9772                                    .into_response()
 9773                                    .context("will rename files")
 9774                                    .log_err()
 9775                                    .flatten()?;
 9776
 9777                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9778                                    this.upgrade()?,
 9779                                    edit,
 9780                                    false,
 9781                                    language_server.clone(),
 9782                                    cx,
 9783                                )
 9784                                .await
 9785                                .ok()?;
 9786                                Some(transaction)
 9787                            }
 9788                        });
 9789                        tasks.push(apply_edit);
 9790                    }
 9791                }
 9792                Some(())
 9793            })
 9794            .ok()
 9795            .flatten();
 9796            let mut merged_transaction = ProjectTransaction::default();
 9797            for task in tasks {
 9798                // Await on tasks sequentially so that the order of application of edits is deterministic
 9799                // (at least with regards to the order of registration of language servers)
 9800                if let Some(transaction) = task.await {
 9801                    for (buffer, buffer_transaction) in transaction.0 {
 9802                        merged_transaction.0.insert(buffer, buffer_transaction);
 9803                    }
 9804                }
 9805            }
 9806            merged_transaction
 9807        })
 9808    }
 9809
 9810    fn lsp_notify_abs_paths_changed(
 9811        &mut self,
 9812        server_id: LanguageServerId,
 9813        changes: Vec<PathEvent>,
 9814    ) {
 9815        maybe!({
 9816            let server = self.language_server_for_id(server_id)?;
 9817            let changes = changes
 9818                .into_iter()
 9819                .filter_map(|event| {
 9820                    let typ = match event.kind? {
 9821                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9822                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9823                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9824                    };
 9825                    Some(lsp::FileEvent {
 9826                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9827                        typ,
 9828                    })
 9829                })
 9830                .collect::<Vec<_>>();
 9831            if !changes.is_empty() {
 9832                server
 9833                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9834                        lsp::DidChangeWatchedFilesParams { changes },
 9835                    )
 9836                    .ok();
 9837            }
 9838            Some(())
 9839        });
 9840    }
 9841
 9842    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9843        self.as_local()?.language_server_for_id(id)
 9844    }
 9845
 9846    fn on_lsp_progress(
 9847        &mut self,
 9848        progress_params: lsp::ProgressParams,
 9849        language_server_id: LanguageServerId,
 9850        disk_based_diagnostics_progress_token: Option<String>,
 9851        cx: &mut Context<Self>,
 9852    ) {
 9853        match progress_params.value {
 9854            lsp::ProgressParamsValue::WorkDone(progress) => {
 9855                self.handle_work_done_progress(
 9856                    progress,
 9857                    language_server_id,
 9858                    disk_based_diagnostics_progress_token,
 9859                    ProgressToken::from_lsp(progress_params.token),
 9860                    cx,
 9861                );
 9862            }
 9863            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9864                let registration_id = match progress_params.token {
 9865                    lsp::NumberOrString::Number(_) => None,
 9866                    lsp::NumberOrString::String(token) => token
 9867                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9868                        .map(|(_, id)| id.to_owned()),
 9869                };
 9870                if let Some(LanguageServerState::Running {
 9871                    workspace_diagnostics_refresh_tasks,
 9872                    ..
 9873                }) = self
 9874                    .as_local_mut()
 9875                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9876                    && let Some(workspace_diagnostics) =
 9877                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9878                {
 9879                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9880                    self.apply_workspace_diagnostic_report(
 9881                        language_server_id,
 9882                        report,
 9883                        registration_id.map(SharedString::from),
 9884                        cx,
 9885                    )
 9886                }
 9887            }
 9888        }
 9889    }
 9890
 9891    fn handle_work_done_progress(
 9892        &mut self,
 9893        progress: lsp::WorkDoneProgress,
 9894        language_server_id: LanguageServerId,
 9895        disk_based_diagnostics_progress_token: Option<String>,
 9896        token: ProgressToken,
 9897        cx: &mut Context<Self>,
 9898    ) {
 9899        let language_server_status =
 9900            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9901                status
 9902            } else {
 9903                return;
 9904            };
 9905
 9906        if !language_server_status.progress_tokens.contains(&token) {
 9907            return;
 9908        }
 9909
 9910        let is_disk_based_diagnostics_progress =
 9911            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9912                (&disk_based_diagnostics_progress_token, &token)
 9913            {
 9914                token.starts_with(disk_based_token)
 9915            } else {
 9916                false
 9917            };
 9918
 9919        match progress {
 9920            lsp::WorkDoneProgress::Begin(report) => {
 9921                if is_disk_based_diagnostics_progress {
 9922                    self.disk_based_diagnostics_started(language_server_id, cx);
 9923                }
 9924                self.on_lsp_work_start(
 9925                    language_server_id,
 9926                    token.clone(),
 9927                    LanguageServerProgress {
 9928                        title: Some(report.title),
 9929                        is_disk_based_diagnostics_progress,
 9930                        is_cancellable: report.cancellable.unwrap_or(false),
 9931                        message: report.message.clone(),
 9932                        percentage: report.percentage.map(|p| p as usize),
 9933                        last_update_at: cx.background_executor().now(),
 9934                    },
 9935                    cx,
 9936                );
 9937            }
 9938            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9939                language_server_id,
 9940                token,
 9941                LanguageServerProgress {
 9942                    title: None,
 9943                    is_disk_based_diagnostics_progress,
 9944                    is_cancellable: report.cancellable.unwrap_or(false),
 9945                    message: report.message,
 9946                    percentage: report.percentage.map(|p| p as usize),
 9947                    last_update_at: cx.background_executor().now(),
 9948                },
 9949                cx,
 9950            ),
 9951            lsp::WorkDoneProgress::End(_) => {
 9952                language_server_status.progress_tokens.remove(&token);
 9953                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9954                if is_disk_based_diagnostics_progress {
 9955                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9956                }
 9957            }
 9958        }
 9959    }
 9960
 9961    fn on_lsp_work_start(
 9962        &mut self,
 9963        language_server_id: LanguageServerId,
 9964        token: ProgressToken,
 9965        progress: LanguageServerProgress,
 9966        cx: &mut Context<Self>,
 9967    ) {
 9968        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9969            status.pending_work.insert(token.clone(), progress.clone());
 9970            cx.notify();
 9971        }
 9972        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9973            language_server_id,
 9974            name: self
 9975                .language_server_adapter_for_id(language_server_id)
 9976                .map(|adapter| adapter.name()),
 9977            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9978                token: Some(token.to_proto()),
 9979                title: progress.title,
 9980                message: progress.message,
 9981                percentage: progress.percentage.map(|p| p as u32),
 9982                is_cancellable: Some(progress.is_cancellable),
 9983            }),
 9984        })
 9985    }
 9986
 9987    fn on_lsp_work_progress(
 9988        &mut self,
 9989        language_server_id: LanguageServerId,
 9990        token: ProgressToken,
 9991        progress: LanguageServerProgress,
 9992        cx: &mut Context<Self>,
 9993    ) {
 9994        let mut did_update = false;
 9995        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9996            match status.pending_work.entry(token.clone()) {
 9997                btree_map::Entry::Vacant(entry) => {
 9998                    entry.insert(progress.clone());
 9999                    did_update = true;
10000                }
10001                btree_map::Entry::Occupied(mut entry) => {
10002                    let entry = entry.get_mut();
10003                    if (progress.last_update_at - entry.last_update_at)
10004                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10005                    {
10006                        entry.last_update_at = progress.last_update_at;
10007                        if progress.message.is_some() {
10008                            entry.message = progress.message.clone();
10009                        }
10010                        if progress.percentage.is_some() {
10011                            entry.percentage = progress.percentage;
10012                        }
10013                        if progress.is_cancellable != entry.is_cancellable {
10014                            entry.is_cancellable = progress.is_cancellable;
10015                        }
10016                        did_update = true;
10017                    }
10018                }
10019            }
10020        }
10021
10022        if did_update {
10023            cx.emit(LspStoreEvent::LanguageServerUpdate {
10024                language_server_id,
10025                name: self
10026                    .language_server_adapter_for_id(language_server_id)
10027                    .map(|adapter| adapter.name()),
10028                message: proto::update_language_server::Variant::WorkProgress(
10029                    proto::LspWorkProgress {
10030                        token: Some(token.to_proto()),
10031                        message: progress.message,
10032                        percentage: progress.percentage.map(|p| p as u32),
10033                        is_cancellable: Some(progress.is_cancellable),
10034                    },
10035                ),
10036            })
10037        }
10038    }
10039
10040    fn on_lsp_work_end(
10041        &mut self,
10042        language_server_id: LanguageServerId,
10043        token: ProgressToken,
10044        cx: &mut Context<Self>,
10045    ) {
10046        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10047            if let Some(work) = status.pending_work.remove(&token)
10048                && !work.is_disk_based_diagnostics_progress
10049            {
10050                cx.emit(LspStoreEvent::RefreshInlayHints {
10051                    server_id: language_server_id,
10052                    request_id: None,
10053                });
10054            }
10055            cx.notify();
10056        }
10057
10058        cx.emit(LspStoreEvent::LanguageServerUpdate {
10059            language_server_id,
10060            name: self
10061                .language_server_adapter_for_id(language_server_id)
10062                .map(|adapter| adapter.name()),
10063            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10064                token: Some(token.to_proto()),
10065            }),
10066        })
10067    }
10068
10069    pub async fn handle_resolve_completion_documentation(
10070        this: Entity<Self>,
10071        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10072        mut cx: AsyncApp,
10073    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10074        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10075
10076        let completion = this
10077            .read_with(&cx, |this, cx| {
10078                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10079                let server = this
10080                    .language_server_for_id(id)
10081                    .with_context(|| format!("No language server {id}"))?;
10082
10083                anyhow::Ok(cx.background_spawn(async move {
10084                    let can_resolve = server
10085                        .capabilities()
10086                        .completion_provider
10087                        .as_ref()
10088                        .and_then(|options| options.resolve_provider)
10089                        .unwrap_or(false);
10090                    if can_resolve {
10091                        server
10092                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
10093                            .await
10094                            .into_response()
10095                            .context("resolve completion item")
10096                    } else {
10097                        anyhow::Ok(lsp_completion)
10098                    }
10099                }))
10100            })??
10101            .await?;
10102
10103        let mut documentation_is_markdown = false;
10104        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10105        let documentation = match completion.documentation {
10106            Some(lsp::Documentation::String(text)) => text,
10107
10108            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10109                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10110                value
10111            }
10112
10113            _ => String::new(),
10114        };
10115
10116        // If we have a new buffer_id, that means we're talking to a new client
10117        // and want to check for new text_edits in the completion too.
10118        let mut old_replace_start = None;
10119        let mut old_replace_end = None;
10120        let mut old_insert_start = None;
10121        let mut old_insert_end = None;
10122        let mut new_text = String::default();
10123        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10124            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10125                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10126                anyhow::Ok(buffer.read(cx).snapshot())
10127            })??;
10128
10129            if let Some(text_edit) = completion.text_edit.as_ref() {
10130                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10131
10132                if let Some(mut edit) = edit {
10133                    LineEnding::normalize(&mut edit.new_text);
10134
10135                    new_text = edit.new_text;
10136                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10137                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10138                    if let Some(insert_range) = edit.insert_range {
10139                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10140                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10141                    }
10142                }
10143            }
10144        }
10145
10146        Ok(proto::ResolveCompletionDocumentationResponse {
10147            documentation,
10148            documentation_is_markdown,
10149            old_replace_start,
10150            old_replace_end,
10151            new_text,
10152            lsp_completion,
10153            old_insert_start,
10154            old_insert_end,
10155        })
10156    }
10157
10158    async fn handle_on_type_formatting(
10159        this: Entity<Self>,
10160        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10161        mut cx: AsyncApp,
10162    ) -> Result<proto::OnTypeFormattingResponse> {
10163        let on_type_formatting = this.update(&mut cx, |this, cx| {
10164            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10165            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10166            let position = envelope
10167                .payload
10168                .position
10169                .and_then(deserialize_anchor)
10170                .context("invalid position")?;
10171            anyhow::Ok(this.apply_on_type_formatting(
10172                buffer,
10173                position,
10174                envelope.payload.trigger.clone(),
10175                cx,
10176            ))
10177        })??;
10178
10179        let transaction = on_type_formatting
10180            .await?
10181            .as_ref()
10182            .map(language::proto::serialize_transaction);
10183        Ok(proto::OnTypeFormattingResponse { transaction })
10184    }
10185
10186    async fn handle_refresh_inlay_hints(
10187        lsp_store: Entity<Self>,
10188        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10189        mut cx: AsyncApp,
10190    ) -> Result<proto::Ack> {
10191        lsp_store.update(&mut cx, |_, cx| {
10192            cx.emit(LspStoreEvent::RefreshInlayHints {
10193                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10194                request_id: envelope.payload.request_id.map(|id| id as usize),
10195            });
10196        })?;
10197        Ok(proto::Ack {})
10198    }
10199
10200    async fn handle_pull_workspace_diagnostics(
10201        lsp_store: Entity<Self>,
10202        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10203        mut cx: AsyncApp,
10204    ) -> Result<proto::Ack> {
10205        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10206        lsp_store.update(&mut cx, |lsp_store, _| {
10207            lsp_store.pull_workspace_diagnostics(server_id);
10208        })?;
10209        Ok(proto::Ack {})
10210    }
10211
10212    async fn handle_get_color_presentation(
10213        lsp_store: Entity<Self>,
10214        envelope: TypedEnvelope<proto::GetColorPresentation>,
10215        mut cx: AsyncApp,
10216    ) -> Result<proto::GetColorPresentationResponse> {
10217        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10218        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10219            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10220        })??;
10221
10222        let color = envelope
10223            .payload
10224            .color
10225            .context("invalid color resolve request")?;
10226        let start = color
10227            .lsp_range_start
10228            .context("invalid color resolve request")?;
10229        let end = color
10230            .lsp_range_end
10231            .context("invalid color resolve request")?;
10232
10233        let color = DocumentColor {
10234            lsp_range: lsp::Range {
10235                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10236                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10237            },
10238            color: lsp::Color {
10239                red: color.red,
10240                green: color.green,
10241                blue: color.blue,
10242                alpha: color.alpha,
10243            },
10244            resolved: false,
10245            color_presentations: Vec::new(),
10246        };
10247        let resolved_color = lsp_store
10248            .update(&mut cx, |lsp_store, cx| {
10249                lsp_store.resolve_color_presentation(
10250                    color,
10251                    buffer.clone(),
10252                    LanguageServerId(envelope.payload.server_id as usize),
10253                    cx,
10254                )
10255            })?
10256            .await
10257            .context("resolving color presentation")?;
10258
10259        Ok(proto::GetColorPresentationResponse {
10260            presentations: resolved_color
10261                .color_presentations
10262                .into_iter()
10263                .map(|presentation| proto::ColorPresentation {
10264                    label: presentation.label.to_string(),
10265                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10266                    additional_text_edits: presentation
10267                        .additional_text_edits
10268                        .into_iter()
10269                        .map(serialize_lsp_edit)
10270                        .collect(),
10271                })
10272                .collect(),
10273        })
10274    }
10275
10276    async fn handle_resolve_inlay_hint(
10277        lsp_store: Entity<Self>,
10278        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10279        mut cx: AsyncApp,
10280    ) -> Result<proto::ResolveInlayHintResponse> {
10281        let proto_hint = envelope
10282            .payload
10283            .hint
10284            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10285        let hint = InlayHints::proto_to_project_hint(proto_hint)
10286            .context("resolved proto inlay hint conversion")?;
10287        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10288            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10289            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10290        })??;
10291        let response_hint = lsp_store
10292            .update(&mut cx, |lsp_store, cx| {
10293                lsp_store.resolve_inlay_hint(
10294                    hint,
10295                    buffer,
10296                    LanguageServerId(envelope.payload.language_server_id as usize),
10297                    cx,
10298                )
10299            })?
10300            .await
10301            .context("inlay hints fetch")?;
10302        Ok(proto::ResolveInlayHintResponse {
10303            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10304        })
10305    }
10306
10307    async fn handle_refresh_code_lens(
10308        this: Entity<Self>,
10309        _: TypedEnvelope<proto::RefreshCodeLens>,
10310        mut cx: AsyncApp,
10311    ) -> Result<proto::Ack> {
10312        this.update(&mut cx, |_, cx| {
10313            cx.emit(LspStoreEvent::RefreshCodeLens);
10314        })?;
10315        Ok(proto::Ack {})
10316    }
10317
10318    async fn handle_open_buffer_for_symbol(
10319        this: Entity<Self>,
10320        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10321        mut cx: AsyncApp,
10322    ) -> Result<proto::OpenBufferForSymbolResponse> {
10323        let peer_id = envelope.original_sender_id().unwrap_or_default();
10324        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10325        let symbol = Self::deserialize_symbol(symbol)?;
10326        this.read_with(&cx, |this, _| {
10327            if let SymbolLocation::OutsideProject {
10328                abs_path,
10329                signature,
10330            } = &symbol.path
10331            {
10332                let new_signature = this.symbol_signature(&abs_path);
10333                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10334            }
10335            Ok(())
10336        })??;
10337        let buffer = this
10338            .update(&mut cx, |this, cx| {
10339                this.open_buffer_for_symbol(
10340                    &Symbol {
10341                        language_server_name: symbol.language_server_name,
10342                        source_worktree_id: symbol.source_worktree_id,
10343                        source_language_server_id: symbol.source_language_server_id,
10344                        path: symbol.path,
10345                        name: symbol.name,
10346                        kind: symbol.kind,
10347                        range: symbol.range,
10348                        label: CodeLabel::default(),
10349                    },
10350                    cx,
10351                )
10352            })?
10353            .await?;
10354
10355        this.update(&mut cx, |this, cx| {
10356            let is_private = buffer
10357                .read(cx)
10358                .file()
10359                .map(|f| f.is_private())
10360                .unwrap_or_default();
10361            if is_private {
10362                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10363            } else {
10364                this.buffer_store
10365                    .update(cx, |buffer_store, cx| {
10366                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10367                    })
10368                    .detach_and_log_err(cx);
10369                let buffer_id = buffer.read(cx).remote_id().to_proto();
10370                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10371            }
10372        })?
10373    }
10374
10375    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10376        let mut hasher = Sha256::new();
10377        hasher.update(abs_path.to_string_lossy().as_bytes());
10378        hasher.update(self.nonce.to_be_bytes());
10379        hasher.finalize().as_slice().try_into().unwrap()
10380    }
10381
10382    pub async fn handle_get_project_symbols(
10383        this: Entity<Self>,
10384        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10385        mut cx: AsyncApp,
10386    ) -> Result<proto::GetProjectSymbolsResponse> {
10387        let symbols = this
10388            .update(&mut cx, |this, cx| {
10389                this.symbols(&envelope.payload.query, cx)
10390            })?
10391            .await?;
10392
10393        Ok(proto::GetProjectSymbolsResponse {
10394            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10395        })
10396    }
10397
10398    pub async fn handle_restart_language_servers(
10399        this: Entity<Self>,
10400        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10401        mut cx: AsyncApp,
10402    ) -> Result<proto::Ack> {
10403        this.update(&mut cx, |lsp_store, cx| {
10404            let buffers =
10405                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10406            lsp_store.restart_language_servers_for_buffers(
10407                buffers,
10408                envelope
10409                    .payload
10410                    .only_servers
10411                    .into_iter()
10412                    .filter_map(|selector| {
10413                        Some(match selector.selector? {
10414                            proto::language_server_selector::Selector::ServerId(server_id) => {
10415                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10416                            }
10417                            proto::language_server_selector::Selector::Name(name) => {
10418                                LanguageServerSelector::Name(LanguageServerName(
10419                                    SharedString::from(name),
10420                                ))
10421                            }
10422                        })
10423                    })
10424                    .collect(),
10425                cx,
10426            );
10427        })?;
10428
10429        Ok(proto::Ack {})
10430    }
10431
10432    pub async fn handle_stop_language_servers(
10433        lsp_store: Entity<Self>,
10434        envelope: TypedEnvelope<proto::StopLanguageServers>,
10435        mut cx: AsyncApp,
10436    ) -> Result<proto::Ack> {
10437        lsp_store.update(&mut cx, |lsp_store, cx| {
10438            if envelope.payload.all
10439                && envelope.payload.also_servers.is_empty()
10440                && envelope.payload.buffer_ids.is_empty()
10441            {
10442                lsp_store.stop_all_language_servers(cx);
10443            } else {
10444                let buffers =
10445                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10446                lsp_store
10447                    .stop_language_servers_for_buffers(
10448                        buffers,
10449                        envelope
10450                            .payload
10451                            .also_servers
10452                            .into_iter()
10453                            .filter_map(|selector| {
10454                                Some(match selector.selector? {
10455                                    proto::language_server_selector::Selector::ServerId(
10456                                        server_id,
10457                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10458                                        server_id,
10459                                    )),
10460                                    proto::language_server_selector::Selector::Name(name) => {
10461                                        LanguageServerSelector::Name(LanguageServerName(
10462                                            SharedString::from(name),
10463                                        ))
10464                                    }
10465                                })
10466                            })
10467                            .collect(),
10468                        cx,
10469                    )
10470                    .detach_and_log_err(cx);
10471            }
10472        })?;
10473
10474        Ok(proto::Ack {})
10475    }
10476
10477    pub async fn handle_cancel_language_server_work(
10478        lsp_store: Entity<Self>,
10479        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10480        mut cx: AsyncApp,
10481    ) -> Result<proto::Ack> {
10482        lsp_store.update(&mut cx, |lsp_store, cx| {
10483            if let Some(work) = envelope.payload.work {
10484                match work {
10485                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10486                        let buffers =
10487                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10488                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10489                    }
10490                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10491                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10492                        let token = work
10493                            .token
10494                            .map(|token| {
10495                                ProgressToken::from_proto(token)
10496                                    .context("invalid work progress token")
10497                            })
10498                            .transpose()?;
10499                        lsp_store.cancel_language_server_work(server_id, token, cx);
10500                    }
10501                }
10502            }
10503            anyhow::Ok(())
10504        })??;
10505
10506        Ok(proto::Ack {})
10507    }
10508
10509    fn buffer_ids_to_buffers(
10510        &mut self,
10511        buffer_ids: impl Iterator<Item = u64>,
10512        cx: &mut Context<Self>,
10513    ) -> Vec<Entity<Buffer>> {
10514        buffer_ids
10515            .into_iter()
10516            .flat_map(|buffer_id| {
10517                self.buffer_store
10518                    .read(cx)
10519                    .get(BufferId::new(buffer_id).log_err()?)
10520            })
10521            .collect::<Vec<_>>()
10522    }
10523
10524    async fn handle_apply_additional_edits_for_completion(
10525        this: Entity<Self>,
10526        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10527        mut cx: AsyncApp,
10528    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10529        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10530            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10531            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10532            let completion = Self::deserialize_completion(
10533                envelope.payload.completion.context("invalid completion")?,
10534            )?;
10535            anyhow::Ok((buffer, completion))
10536        })??;
10537
10538        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10539            this.apply_additional_edits_for_completion(
10540                buffer,
10541                Rc::new(RefCell::new(Box::new([Completion {
10542                    replace_range: completion.replace_range,
10543                    new_text: completion.new_text,
10544                    source: completion.source,
10545                    documentation: None,
10546                    label: CodeLabel::default(),
10547                    match_start: None,
10548                    snippet_deduplication_key: None,
10549                    insert_text_mode: None,
10550                    icon_path: None,
10551                    confirm: None,
10552                }]))),
10553                0,
10554                false,
10555                cx,
10556            )
10557        })?;
10558
10559        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10560            transaction: apply_additional_edits
10561                .await?
10562                .as_ref()
10563                .map(language::proto::serialize_transaction),
10564        })
10565    }
10566
10567    pub fn last_formatting_failure(&self) -> Option<&str> {
10568        self.last_formatting_failure.as_deref()
10569    }
10570
10571    pub fn reset_last_formatting_failure(&mut self) {
10572        self.last_formatting_failure = None;
10573    }
10574
10575    pub fn environment_for_buffer(
10576        &self,
10577        buffer: &Entity<Buffer>,
10578        cx: &mut Context<Self>,
10579    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10580        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10581            environment.update(cx, |env, cx| {
10582                env.buffer_environment(buffer, &self.worktree_store, cx)
10583            })
10584        } else {
10585            Task::ready(None).shared()
10586        }
10587    }
10588
10589    pub fn format(
10590        &mut self,
10591        buffers: HashSet<Entity<Buffer>>,
10592        target: LspFormatTarget,
10593        push_to_history: bool,
10594        trigger: FormatTrigger,
10595        cx: &mut Context<Self>,
10596    ) -> Task<anyhow::Result<ProjectTransaction>> {
10597        let logger = zlog::scoped!("format");
10598        if self.as_local().is_some() {
10599            zlog::trace!(logger => "Formatting locally");
10600            let logger = zlog::scoped!(logger => "local");
10601            let buffers = buffers
10602                .into_iter()
10603                .map(|buffer_handle| {
10604                    let buffer = buffer_handle.read(cx);
10605                    let buffer_abs_path = File::from_dyn(buffer.file())
10606                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10607
10608                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10609                })
10610                .collect::<Vec<_>>();
10611
10612            cx.spawn(async move |lsp_store, cx| {
10613                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10614
10615                for (handle, abs_path, id) in buffers {
10616                    let env = lsp_store
10617                        .update(cx, |lsp_store, cx| {
10618                            lsp_store.environment_for_buffer(&handle, cx)
10619                        })?
10620                        .await;
10621
10622                    let ranges = match &target {
10623                        LspFormatTarget::Buffers => None,
10624                        LspFormatTarget::Ranges(ranges) => {
10625                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10626                        }
10627                    };
10628
10629                    formattable_buffers.push(FormattableBuffer {
10630                        handle,
10631                        abs_path,
10632                        env,
10633                        ranges,
10634                    });
10635                }
10636                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10637
10638                let format_timer = zlog::time!(logger => "Formatting buffers");
10639                let result = LocalLspStore::format_locally(
10640                    lsp_store.clone(),
10641                    formattable_buffers,
10642                    push_to_history,
10643                    trigger,
10644                    logger,
10645                    cx,
10646                )
10647                .await;
10648                format_timer.end();
10649
10650                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10651
10652                lsp_store.update(cx, |lsp_store, _| {
10653                    lsp_store.update_last_formatting_failure(&result);
10654                })?;
10655
10656                result
10657            })
10658        } else if let Some((client, project_id)) = self.upstream_client() {
10659            zlog::trace!(logger => "Formatting remotely");
10660            let logger = zlog::scoped!(logger => "remote");
10661            // Don't support formatting ranges via remote
10662            match target {
10663                LspFormatTarget::Buffers => {}
10664                LspFormatTarget::Ranges(_) => {
10665                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10666                    return Task::ready(Ok(ProjectTransaction::default()));
10667                }
10668            }
10669
10670            let buffer_store = self.buffer_store();
10671            cx.spawn(async move |lsp_store, cx| {
10672                zlog::trace!(logger => "Sending remote format request");
10673                let request_timer = zlog::time!(logger => "remote format request");
10674                let result = client
10675                    .request(proto::FormatBuffers {
10676                        project_id,
10677                        trigger: trigger as i32,
10678                        buffer_ids: buffers
10679                            .iter()
10680                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10681                            .collect::<Result<_>>()?,
10682                    })
10683                    .await
10684                    .and_then(|result| result.transaction.context("missing transaction"));
10685                request_timer.end();
10686
10687                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10688
10689                lsp_store.update(cx, |lsp_store, _| {
10690                    lsp_store.update_last_formatting_failure(&result);
10691                })?;
10692
10693                let transaction_response = result?;
10694                let _timer = zlog::time!(logger => "deserializing project transaction");
10695                buffer_store
10696                    .update(cx, |buffer_store, cx| {
10697                        buffer_store.deserialize_project_transaction(
10698                            transaction_response,
10699                            push_to_history,
10700                            cx,
10701                        )
10702                    })?
10703                    .await
10704            })
10705        } else {
10706            zlog::trace!(logger => "Not formatting");
10707            Task::ready(Ok(ProjectTransaction::default()))
10708        }
10709    }
10710
10711    async fn handle_format_buffers(
10712        this: Entity<Self>,
10713        envelope: TypedEnvelope<proto::FormatBuffers>,
10714        mut cx: AsyncApp,
10715    ) -> Result<proto::FormatBuffersResponse> {
10716        let sender_id = envelope.original_sender_id().unwrap_or_default();
10717        let format = this.update(&mut cx, |this, cx| {
10718            let mut buffers = HashSet::default();
10719            for buffer_id in &envelope.payload.buffer_ids {
10720                let buffer_id = BufferId::new(*buffer_id)?;
10721                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10722            }
10723            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10724            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10725        })??;
10726
10727        let project_transaction = format.await?;
10728        let project_transaction = this.update(&mut cx, |this, cx| {
10729            this.buffer_store.update(cx, |buffer_store, cx| {
10730                buffer_store.serialize_project_transaction_for_peer(
10731                    project_transaction,
10732                    sender_id,
10733                    cx,
10734                )
10735            })
10736        })?;
10737        Ok(proto::FormatBuffersResponse {
10738            transaction: Some(project_transaction),
10739        })
10740    }
10741
10742    async fn handle_apply_code_action_kind(
10743        this: Entity<Self>,
10744        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10745        mut cx: AsyncApp,
10746    ) -> Result<proto::ApplyCodeActionKindResponse> {
10747        let sender_id = envelope.original_sender_id().unwrap_or_default();
10748        let format = this.update(&mut cx, |this, cx| {
10749            let mut buffers = HashSet::default();
10750            for buffer_id in &envelope.payload.buffer_ids {
10751                let buffer_id = BufferId::new(*buffer_id)?;
10752                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10753            }
10754            let kind = match envelope.payload.kind.as_str() {
10755                "" => CodeActionKind::EMPTY,
10756                "quickfix" => CodeActionKind::QUICKFIX,
10757                "refactor" => CodeActionKind::REFACTOR,
10758                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10759                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10760                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10761                "source" => CodeActionKind::SOURCE,
10762                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10763                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10764                _ => anyhow::bail!(
10765                    "Invalid code action kind {}",
10766                    envelope.payload.kind.as_str()
10767                ),
10768            };
10769            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10770        })??;
10771
10772        let project_transaction = format.await?;
10773        let project_transaction = this.update(&mut cx, |this, cx| {
10774            this.buffer_store.update(cx, |buffer_store, cx| {
10775                buffer_store.serialize_project_transaction_for_peer(
10776                    project_transaction,
10777                    sender_id,
10778                    cx,
10779                )
10780            })
10781        })?;
10782        Ok(proto::ApplyCodeActionKindResponse {
10783            transaction: Some(project_transaction),
10784        })
10785    }
10786
10787    async fn shutdown_language_server(
10788        server_state: Option<LanguageServerState>,
10789        name: LanguageServerName,
10790        cx: &mut AsyncApp,
10791    ) {
10792        let server = match server_state {
10793            Some(LanguageServerState::Starting { startup, .. }) => {
10794                let mut timer = cx
10795                    .background_executor()
10796                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10797                    .fuse();
10798
10799                select! {
10800                    server = startup.fuse() => server,
10801                    () = timer => {
10802                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10803                        None
10804                    },
10805                }
10806            }
10807
10808            Some(LanguageServerState::Running { server, .. }) => Some(server),
10809
10810            None => None,
10811        };
10812
10813        if let Some(server) = server
10814            && let Some(shutdown) = server.shutdown()
10815        {
10816            shutdown.await;
10817        }
10818    }
10819
10820    // Returns a list of all of the worktrees which no longer have a language server and the root path
10821    // for the stopped server
10822    fn stop_local_language_server(
10823        &mut self,
10824        server_id: LanguageServerId,
10825        cx: &mut Context<Self>,
10826    ) -> Task<()> {
10827        let local = match &mut self.mode {
10828            LspStoreMode::Local(local) => local,
10829            _ => {
10830                return Task::ready(());
10831            }
10832        };
10833
10834        // Remove this server ID from all entries in the given worktree.
10835        local
10836            .language_server_ids
10837            .retain(|_, state| state.id != server_id);
10838        self.buffer_store.update(cx, |buffer_store, cx| {
10839            for buffer in buffer_store.buffers() {
10840                buffer.update(cx, |buffer, cx| {
10841                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10842                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10843                });
10844            }
10845        });
10846
10847        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10848            summaries.retain(|path, summaries_by_server_id| {
10849                if summaries_by_server_id.remove(&server_id).is_some() {
10850                    if let Some((client, project_id)) = self.downstream_client.clone() {
10851                        client
10852                            .send(proto::UpdateDiagnosticSummary {
10853                                project_id,
10854                                worktree_id: worktree_id.to_proto(),
10855                                summary: Some(proto::DiagnosticSummary {
10856                                    path: path.as_ref().to_proto(),
10857                                    language_server_id: server_id.0 as u64,
10858                                    error_count: 0,
10859                                    warning_count: 0,
10860                                }),
10861                                more_summaries: Vec::new(),
10862                            })
10863                            .log_err();
10864                    }
10865                    !summaries_by_server_id.is_empty()
10866                } else {
10867                    true
10868                }
10869            });
10870        }
10871
10872        let local = self.as_local_mut().unwrap();
10873        for diagnostics in local.diagnostics.values_mut() {
10874            diagnostics.retain(|_, diagnostics_by_server_id| {
10875                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10876                    diagnostics_by_server_id.remove(ix);
10877                    !diagnostics_by_server_id.is_empty()
10878                } else {
10879                    true
10880                }
10881            });
10882        }
10883        local.language_server_watched_paths.remove(&server_id);
10884
10885        let server_state = local.language_servers.remove(&server_id);
10886        self.cleanup_lsp_data(server_id);
10887        let name = self
10888            .language_server_statuses
10889            .remove(&server_id)
10890            .map(|status| status.name)
10891            .or_else(|| {
10892                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10893                    Some(adapter.name())
10894                } else {
10895                    None
10896                }
10897            });
10898
10899        if let Some(name) = name {
10900            log::info!("stopping language server {name}");
10901            self.languages
10902                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10903            cx.notify();
10904
10905            return cx.spawn(async move |lsp_store, cx| {
10906                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10907                lsp_store
10908                    .update(cx, |lsp_store, cx| {
10909                        lsp_store
10910                            .languages
10911                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10912                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10913                        cx.notify();
10914                    })
10915                    .ok();
10916            });
10917        }
10918
10919        if server_state.is_some() {
10920            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10921        }
10922        Task::ready(())
10923    }
10924
10925    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10926        if let Some((client, project_id)) = self.upstream_client() {
10927            let request = client.request(proto::StopLanguageServers {
10928                project_id,
10929                buffer_ids: Vec::new(),
10930                also_servers: Vec::new(),
10931                all: true,
10932            });
10933            cx.background_spawn(request).detach_and_log_err(cx);
10934        } else {
10935            let Some(local) = self.as_local_mut() else {
10936                return;
10937            };
10938            let language_servers_to_stop = local
10939                .language_server_ids
10940                .values()
10941                .map(|state| state.id)
10942                .collect();
10943            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10944            let tasks = language_servers_to_stop
10945                .into_iter()
10946                .map(|server| self.stop_local_language_server(server, cx))
10947                .collect::<Vec<_>>();
10948            cx.background_spawn(async move {
10949                futures::future::join_all(tasks).await;
10950            })
10951            .detach();
10952        }
10953    }
10954
10955    pub fn restart_language_servers_for_buffers(
10956        &mut self,
10957        buffers: Vec<Entity<Buffer>>,
10958        only_restart_servers: HashSet<LanguageServerSelector>,
10959        cx: &mut Context<Self>,
10960    ) {
10961        if let Some((client, project_id)) = self.upstream_client() {
10962            let request = client.request(proto::RestartLanguageServers {
10963                project_id,
10964                buffer_ids: buffers
10965                    .into_iter()
10966                    .map(|b| b.read(cx).remote_id().to_proto())
10967                    .collect(),
10968                only_servers: only_restart_servers
10969                    .into_iter()
10970                    .map(|selector| {
10971                        let selector = match selector {
10972                            LanguageServerSelector::Id(language_server_id) => {
10973                                proto::language_server_selector::Selector::ServerId(
10974                                    language_server_id.to_proto(),
10975                                )
10976                            }
10977                            LanguageServerSelector::Name(language_server_name) => {
10978                                proto::language_server_selector::Selector::Name(
10979                                    language_server_name.to_string(),
10980                                )
10981                            }
10982                        };
10983                        proto::LanguageServerSelector {
10984                            selector: Some(selector),
10985                        }
10986                    })
10987                    .collect(),
10988                all: false,
10989            });
10990            cx.background_spawn(request).detach_and_log_err(cx);
10991        } else {
10992            let stop_task = if only_restart_servers.is_empty() {
10993                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10994            } else {
10995                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10996            };
10997            cx.spawn(async move |lsp_store, cx| {
10998                stop_task.await;
10999                lsp_store
11000                    .update(cx, |lsp_store, cx| {
11001                        for buffer in buffers {
11002                            lsp_store.register_buffer_with_language_servers(
11003                                &buffer,
11004                                only_restart_servers.clone(),
11005                                true,
11006                                cx,
11007                            );
11008                        }
11009                    })
11010                    .ok()
11011            })
11012            .detach();
11013        }
11014    }
11015
11016    pub fn stop_language_servers_for_buffers(
11017        &mut self,
11018        buffers: Vec<Entity<Buffer>>,
11019        also_stop_servers: HashSet<LanguageServerSelector>,
11020        cx: &mut Context<Self>,
11021    ) -> Task<Result<()>> {
11022        if let Some((client, project_id)) = self.upstream_client() {
11023            let request = client.request(proto::StopLanguageServers {
11024                project_id,
11025                buffer_ids: buffers
11026                    .into_iter()
11027                    .map(|b| b.read(cx).remote_id().to_proto())
11028                    .collect(),
11029                also_servers: also_stop_servers
11030                    .into_iter()
11031                    .map(|selector| {
11032                        let selector = match selector {
11033                            LanguageServerSelector::Id(language_server_id) => {
11034                                proto::language_server_selector::Selector::ServerId(
11035                                    language_server_id.to_proto(),
11036                                )
11037                            }
11038                            LanguageServerSelector::Name(language_server_name) => {
11039                                proto::language_server_selector::Selector::Name(
11040                                    language_server_name.to_string(),
11041                                )
11042                            }
11043                        };
11044                        proto::LanguageServerSelector {
11045                            selector: Some(selector),
11046                        }
11047                    })
11048                    .collect(),
11049                all: false,
11050            });
11051            cx.background_spawn(async move {
11052                let _ = request.await?;
11053                Ok(())
11054            })
11055        } else {
11056            let task =
11057                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11058            cx.background_spawn(async move {
11059                task.await;
11060                Ok(())
11061            })
11062        }
11063    }
11064
11065    fn stop_local_language_servers_for_buffers(
11066        &mut self,
11067        buffers: &[Entity<Buffer>],
11068        also_stop_servers: HashSet<LanguageServerSelector>,
11069        cx: &mut Context<Self>,
11070    ) -> Task<()> {
11071        let Some(local) = self.as_local_mut() else {
11072            return Task::ready(());
11073        };
11074        let mut language_server_names_to_stop = BTreeSet::default();
11075        let mut language_servers_to_stop = also_stop_servers
11076            .into_iter()
11077            .flat_map(|selector| match selector {
11078                LanguageServerSelector::Id(id) => Some(id),
11079                LanguageServerSelector::Name(name) => {
11080                    language_server_names_to_stop.insert(name);
11081                    None
11082                }
11083            })
11084            .collect::<BTreeSet<_>>();
11085
11086        let mut covered_worktrees = HashSet::default();
11087        for buffer in buffers {
11088            buffer.update(cx, |buffer, cx| {
11089                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11090                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11091                    && covered_worktrees.insert(worktree_id)
11092                {
11093                    language_server_names_to_stop.retain(|name| {
11094                        let old_ids_count = language_servers_to_stop.len();
11095                        let all_language_servers_with_this_name = local
11096                            .language_server_ids
11097                            .iter()
11098                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11099                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11100                        old_ids_count == language_servers_to_stop.len()
11101                    });
11102                }
11103            });
11104        }
11105        for name in language_server_names_to_stop {
11106            language_servers_to_stop.extend(
11107                local
11108                    .language_server_ids
11109                    .iter()
11110                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11111            );
11112        }
11113
11114        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11115        let tasks = language_servers_to_stop
11116            .into_iter()
11117            .map(|server| self.stop_local_language_server(server, cx))
11118            .collect::<Vec<_>>();
11119
11120        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11121    }
11122
11123    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11124        let (worktree, relative_path) =
11125            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11126
11127        let project_path = ProjectPath {
11128            worktree_id: worktree.read(cx).id(),
11129            path: relative_path,
11130        };
11131
11132        Some(
11133            self.buffer_store()
11134                .read(cx)
11135                .get_by_path(&project_path)?
11136                .read(cx),
11137        )
11138    }
11139
11140    #[cfg(any(test, feature = "test-support"))]
11141    pub fn update_diagnostics(
11142        &mut self,
11143        server_id: LanguageServerId,
11144        diagnostics: lsp::PublishDiagnosticsParams,
11145        result_id: Option<SharedString>,
11146        source_kind: DiagnosticSourceKind,
11147        disk_based_sources: &[String],
11148        cx: &mut Context<Self>,
11149    ) -> Result<()> {
11150        self.merge_lsp_diagnostics(
11151            source_kind,
11152            vec![DocumentDiagnosticsUpdate {
11153                diagnostics,
11154                result_id,
11155                server_id,
11156                disk_based_sources: Cow::Borrowed(disk_based_sources),
11157                registration_id: None,
11158            }],
11159            |_, _, _| false,
11160            cx,
11161        )
11162    }
11163
11164    pub fn merge_lsp_diagnostics(
11165        &mut self,
11166        source_kind: DiagnosticSourceKind,
11167        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11168        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11169        cx: &mut Context<Self>,
11170    ) -> Result<()> {
11171        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11172        let updates = lsp_diagnostics
11173            .into_iter()
11174            .filter_map(|update| {
11175                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11176                Some(DocumentDiagnosticsUpdate {
11177                    diagnostics: self.lsp_to_document_diagnostics(
11178                        abs_path,
11179                        source_kind,
11180                        update.server_id,
11181                        update.diagnostics,
11182                        &update.disk_based_sources,
11183                        update.registration_id.clone(),
11184                    ),
11185                    result_id: update.result_id,
11186                    server_id: update.server_id,
11187                    disk_based_sources: update.disk_based_sources,
11188                    registration_id: update.registration_id,
11189                })
11190            })
11191            .collect();
11192        self.merge_diagnostic_entries(updates, merge, cx)?;
11193        Ok(())
11194    }
11195
11196    fn lsp_to_document_diagnostics(
11197        &mut self,
11198        document_abs_path: PathBuf,
11199        source_kind: DiagnosticSourceKind,
11200        server_id: LanguageServerId,
11201        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11202        disk_based_sources: &[String],
11203        registration_id: Option<SharedString>,
11204    ) -> DocumentDiagnostics {
11205        let mut diagnostics = Vec::default();
11206        let mut primary_diagnostic_group_ids = HashMap::default();
11207        let mut sources_by_group_id = HashMap::default();
11208        let mut supporting_diagnostics = HashMap::default();
11209
11210        let adapter = self.language_server_adapter_for_id(server_id);
11211
11212        // Ensure that primary diagnostics are always the most severe
11213        lsp_diagnostics
11214            .diagnostics
11215            .sort_by_key(|item| item.severity);
11216
11217        for diagnostic in &lsp_diagnostics.diagnostics {
11218            let source = diagnostic.source.as_ref();
11219            let range = range_from_lsp(diagnostic.range);
11220            let is_supporting = diagnostic
11221                .related_information
11222                .as_ref()
11223                .is_some_and(|infos| {
11224                    infos.iter().any(|info| {
11225                        primary_diagnostic_group_ids.contains_key(&(
11226                            source,
11227                            diagnostic.code.clone(),
11228                            range_from_lsp(info.location.range),
11229                        ))
11230                    })
11231                });
11232
11233            let is_unnecessary = diagnostic
11234                .tags
11235                .as_ref()
11236                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11237
11238            let underline = self
11239                .language_server_adapter_for_id(server_id)
11240                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11241
11242            if is_supporting {
11243                supporting_diagnostics.insert(
11244                    (source, diagnostic.code.clone(), range),
11245                    (diagnostic.severity, is_unnecessary),
11246                );
11247            } else {
11248                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11249                let is_disk_based =
11250                    source.is_some_and(|source| disk_based_sources.contains(source));
11251
11252                sources_by_group_id.insert(group_id, source);
11253                primary_diagnostic_group_ids
11254                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11255
11256                diagnostics.push(DiagnosticEntry {
11257                    range,
11258                    diagnostic: Diagnostic {
11259                        source: diagnostic.source.clone(),
11260                        source_kind,
11261                        code: diagnostic.code.clone(),
11262                        code_description: diagnostic
11263                            .code_description
11264                            .as_ref()
11265                            .and_then(|d| d.href.clone()),
11266                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11267                        markdown: adapter.as_ref().and_then(|adapter| {
11268                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11269                        }),
11270                        message: diagnostic.message.trim().to_string(),
11271                        group_id,
11272                        is_primary: true,
11273                        is_disk_based,
11274                        is_unnecessary,
11275                        underline,
11276                        data: diagnostic.data.clone(),
11277                        registration_id: registration_id.clone(),
11278                    },
11279                });
11280                if let Some(infos) = &diagnostic.related_information {
11281                    for info in infos {
11282                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11283                            let range = range_from_lsp(info.location.range);
11284                            diagnostics.push(DiagnosticEntry {
11285                                range,
11286                                diagnostic: Diagnostic {
11287                                    source: diagnostic.source.clone(),
11288                                    source_kind,
11289                                    code: diagnostic.code.clone(),
11290                                    code_description: diagnostic
11291                                        .code_description
11292                                        .as_ref()
11293                                        .and_then(|d| d.href.clone()),
11294                                    severity: DiagnosticSeverity::INFORMATION,
11295                                    markdown: adapter.as_ref().and_then(|adapter| {
11296                                        adapter.diagnostic_message_to_markdown(&info.message)
11297                                    }),
11298                                    message: info.message.trim().to_string(),
11299                                    group_id,
11300                                    is_primary: false,
11301                                    is_disk_based,
11302                                    is_unnecessary: false,
11303                                    underline,
11304                                    data: diagnostic.data.clone(),
11305                                    registration_id: registration_id.clone(),
11306                                },
11307                            });
11308                        }
11309                    }
11310                }
11311            }
11312        }
11313
11314        for entry in &mut diagnostics {
11315            let diagnostic = &mut entry.diagnostic;
11316            if !diagnostic.is_primary {
11317                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11318                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11319                    source,
11320                    diagnostic.code.clone(),
11321                    entry.range.clone(),
11322                )) {
11323                    if let Some(severity) = severity {
11324                        diagnostic.severity = severity;
11325                    }
11326                    diagnostic.is_unnecessary = is_unnecessary;
11327                }
11328            }
11329        }
11330
11331        DocumentDiagnostics {
11332            diagnostics,
11333            document_abs_path,
11334            version: lsp_diagnostics.version,
11335        }
11336    }
11337
11338    fn insert_newly_running_language_server(
11339        &mut self,
11340        adapter: Arc<CachedLspAdapter>,
11341        language_server: Arc<LanguageServer>,
11342        server_id: LanguageServerId,
11343        key: LanguageServerSeed,
11344        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11345        cx: &mut Context<Self>,
11346    ) {
11347        let Some(local) = self.as_local_mut() else {
11348            return;
11349        };
11350        // If the language server for this key doesn't match the server id, don't store the
11351        // server. Which will cause it to be dropped, killing the process
11352        if local
11353            .language_server_ids
11354            .get(&key)
11355            .map(|state| state.id != server_id)
11356            .unwrap_or(false)
11357        {
11358            return;
11359        }
11360
11361        // Update language_servers collection with Running variant of LanguageServerState
11362        // indicating that the server is up and running and ready
11363        let workspace_folders = workspace_folders.lock().clone();
11364        language_server.set_workspace_folders(workspace_folders);
11365
11366        let workspace_diagnostics_refresh_tasks = language_server
11367            .capabilities()
11368            .diagnostic_provider
11369            .and_then(|provider| {
11370                local
11371                    .language_server_dynamic_registrations
11372                    .entry(server_id)
11373                    .or_default()
11374                    .diagnostics
11375                    .entry(None)
11376                    .or_insert(provider.clone());
11377                let workspace_refresher =
11378                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11379
11380                Some((None, workspace_refresher))
11381            })
11382            .into_iter()
11383            .collect();
11384        local.language_servers.insert(
11385            server_id,
11386            LanguageServerState::Running {
11387                workspace_diagnostics_refresh_tasks,
11388                adapter: adapter.clone(),
11389                server: language_server.clone(),
11390                simulate_disk_based_diagnostics_completion: None,
11391            },
11392        );
11393        local
11394            .languages
11395            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11396        if let Some(file_ops_caps) = language_server
11397            .capabilities()
11398            .workspace
11399            .as_ref()
11400            .and_then(|ws| ws.file_operations.as_ref())
11401        {
11402            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11403            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11404            if did_rename_caps.or(will_rename_caps).is_some() {
11405                let watcher = RenamePathsWatchedForServer::default()
11406                    .with_did_rename_patterns(did_rename_caps)
11407                    .with_will_rename_patterns(will_rename_caps);
11408                local
11409                    .language_server_paths_watched_for_rename
11410                    .insert(server_id, watcher);
11411            }
11412        }
11413
11414        self.language_server_statuses.insert(
11415            server_id,
11416            LanguageServerStatus {
11417                name: language_server.name(),
11418                pending_work: Default::default(),
11419                has_pending_diagnostic_updates: false,
11420                progress_tokens: Default::default(),
11421                worktree: Some(key.worktree_id),
11422                binary: Some(language_server.binary().clone()),
11423                configuration: Some(language_server.configuration().clone()),
11424                workspace_folders: language_server.workspace_folders(),
11425            },
11426        );
11427
11428        cx.emit(LspStoreEvent::LanguageServerAdded(
11429            server_id,
11430            language_server.name(),
11431            Some(key.worktree_id),
11432        ));
11433
11434        let server_capabilities = language_server.capabilities();
11435        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11436            downstream_client
11437                .send(proto::StartLanguageServer {
11438                    project_id: *project_id,
11439                    server: Some(proto::LanguageServer {
11440                        id: server_id.to_proto(),
11441                        name: language_server.name().to_string(),
11442                        worktree_id: Some(key.worktree_id.to_proto()),
11443                    }),
11444                    capabilities: serde_json::to_string(&server_capabilities)
11445                        .expect("serializing server LSP capabilities"),
11446                })
11447                .log_err();
11448        }
11449        self.lsp_server_capabilities
11450            .insert(server_id, server_capabilities);
11451
11452        // Tell the language server about every open buffer in the worktree that matches the language.
11453        // Also check for buffers in worktrees that reused this server
11454        let mut worktrees_using_server = vec![key.worktree_id];
11455        if let Some(local) = self.as_local() {
11456            // Find all worktrees that have this server in their language server tree
11457            for (worktree_id, servers) in &local.lsp_tree.instances {
11458                if *worktree_id != key.worktree_id {
11459                    for server_map in servers.roots.values() {
11460                        if server_map
11461                            .values()
11462                            .any(|(node, _)| node.id() == Some(server_id))
11463                        {
11464                            worktrees_using_server.push(*worktree_id);
11465                        }
11466                    }
11467                }
11468            }
11469        }
11470
11471        let mut buffer_paths_registered = Vec::new();
11472        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11473            let mut lsp_adapters = HashMap::default();
11474            for buffer_handle in buffer_store.buffers() {
11475                let buffer = buffer_handle.read(cx);
11476                let file = match File::from_dyn(buffer.file()) {
11477                    Some(file) => file,
11478                    None => continue,
11479                };
11480                let language = match buffer.language() {
11481                    Some(language) => language,
11482                    None => continue,
11483                };
11484
11485                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11486                    || !lsp_adapters
11487                        .entry(language.name())
11488                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11489                        .iter()
11490                        .any(|a| a.name == key.name)
11491                {
11492                    continue;
11493                }
11494                // didOpen
11495                let file = match file.as_local() {
11496                    Some(file) => file,
11497                    None => continue,
11498                };
11499
11500                let local = self.as_local_mut().unwrap();
11501
11502                let buffer_id = buffer.remote_id();
11503                if local.registered_buffers.contains_key(&buffer_id) {
11504                    let versions = local
11505                        .buffer_snapshots
11506                        .entry(buffer_id)
11507                        .or_default()
11508                        .entry(server_id)
11509                        .and_modify(|_| {
11510                            assert!(
11511                            false,
11512                            "There should not be an existing snapshot for a newly inserted buffer"
11513                        )
11514                        })
11515                        .or_insert_with(|| {
11516                            vec![LspBufferSnapshot {
11517                                version: 0,
11518                                snapshot: buffer.text_snapshot(),
11519                            }]
11520                        });
11521
11522                    let snapshot = versions.last().unwrap();
11523                    let version = snapshot.version;
11524                    let initial_snapshot = &snapshot.snapshot;
11525                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11526                    language_server.register_buffer(
11527                        uri,
11528                        adapter.language_id(&language.name()),
11529                        version,
11530                        initial_snapshot.text(),
11531                    );
11532                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11533                    local
11534                        .buffers_opened_in_servers
11535                        .entry(buffer_id)
11536                        .or_default()
11537                        .insert(server_id);
11538                }
11539                buffer_handle.update(cx, |buffer, cx| {
11540                    buffer.set_completion_triggers(
11541                        server_id,
11542                        language_server
11543                            .capabilities()
11544                            .completion_provider
11545                            .as_ref()
11546                            .and_then(|provider| {
11547                                provider
11548                                    .trigger_characters
11549                                    .as_ref()
11550                                    .map(|characters| characters.iter().cloned().collect())
11551                            })
11552                            .unwrap_or_default(),
11553                        cx,
11554                    )
11555                });
11556            }
11557        });
11558
11559        for (buffer_id, abs_path) in buffer_paths_registered {
11560            cx.emit(LspStoreEvent::LanguageServerUpdate {
11561                language_server_id: server_id,
11562                name: Some(adapter.name()),
11563                message: proto::update_language_server::Variant::RegisteredForBuffer(
11564                    proto::RegisteredForBuffer {
11565                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11566                        buffer_id: buffer_id.to_proto(),
11567                    },
11568                ),
11569            });
11570        }
11571
11572        cx.notify();
11573    }
11574
11575    pub fn language_servers_running_disk_based_diagnostics(
11576        &self,
11577    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11578        self.language_server_statuses
11579            .iter()
11580            .filter_map(|(id, status)| {
11581                if status.has_pending_diagnostic_updates {
11582                    Some(*id)
11583                } else {
11584                    None
11585                }
11586            })
11587    }
11588
11589    pub(crate) fn cancel_language_server_work_for_buffers(
11590        &mut self,
11591        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11592        cx: &mut Context<Self>,
11593    ) {
11594        if let Some((client, project_id)) = self.upstream_client() {
11595            let request = client.request(proto::CancelLanguageServerWork {
11596                project_id,
11597                work: Some(proto::cancel_language_server_work::Work::Buffers(
11598                    proto::cancel_language_server_work::Buffers {
11599                        buffer_ids: buffers
11600                            .into_iter()
11601                            .map(|b| b.read(cx).remote_id().to_proto())
11602                            .collect(),
11603                    },
11604                )),
11605            });
11606            cx.background_spawn(request).detach_and_log_err(cx);
11607        } else if let Some(local) = self.as_local() {
11608            let servers = buffers
11609                .into_iter()
11610                .flat_map(|buffer| {
11611                    buffer.update(cx, |buffer, cx| {
11612                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11613                    })
11614                })
11615                .collect::<HashSet<_>>();
11616            for server_id in servers {
11617                self.cancel_language_server_work(server_id, None, cx);
11618            }
11619        }
11620    }
11621
11622    pub(crate) fn cancel_language_server_work(
11623        &mut self,
11624        server_id: LanguageServerId,
11625        token_to_cancel: Option<ProgressToken>,
11626        cx: &mut Context<Self>,
11627    ) {
11628        if let Some(local) = self.as_local() {
11629            let status = self.language_server_statuses.get(&server_id);
11630            let server = local.language_servers.get(&server_id);
11631            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11632            {
11633                for (token, progress) in &status.pending_work {
11634                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11635                        && token != token_to_cancel
11636                    {
11637                        continue;
11638                    }
11639                    if progress.is_cancellable {
11640                        server
11641                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11642                                WorkDoneProgressCancelParams {
11643                                    token: token.to_lsp(),
11644                                },
11645                            )
11646                            .ok();
11647                    }
11648                }
11649            }
11650        } else if let Some((client, project_id)) = self.upstream_client() {
11651            let request = client.request(proto::CancelLanguageServerWork {
11652                project_id,
11653                work: Some(
11654                    proto::cancel_language_server_work::Work::LanguageServerWork(
11655                        proto::cancel_language_server_work::LanguageServerWork {
11656                            language_server_id: server_id.to_proto(),
11657                            token: token_to_cancel.map(|token| token.to_proto()),
11658                        },
11659                    ),
11660                ),
11661            });
11662            cx.background_spawn(request).detach_and_log_err(cx);
11663        }
11664    }
11665
11666    fn register_supplementary_language_server(
11667        &mut self,
11668        id: LanguageServerId,
11669        name: LanguageServerName,
11670        server: Arc<LanguageServer>,
11671        cx: &mut Context<Self>,
11672    ) {
11673        if let Some(local) = self.as_local_mut() {
11674            local
11675                .supplementary_language_servers
11676                .insert(id, (name.clone(), server));
11677            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11678        }
11679    }
11680
11681    fn unregister_supplementary_language_server(
11682        &mut self,
11683        id: LanguageServerId,
11684        cx: &mut Context<Self>,
11685    ) {
11686        if let Some(local) = self.as_local_mut() {
11687            local.supplementary_language_servers.remove(&id);
11688            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11689        }
11690    }
11691
11692    pub(crate) fn supplementary_language_servers(
11693        &self,
11694    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11695        self.as_local().into_iter().flat_map(|local| {
11696            local
11697                .supplementary_language_servers
11698                .iter()
11699                .map(|(id, (name, _))| (*id, name.clone()))
11700        })
11701    }
11702
11703    pub fn language_server_adapter_for_id(
11704        &self,
11705        id: LanguageServerId,
11706    ) -> Option<Arc<CachedLspAdapter>> {
11707        self.as_local()
11708            .and_then(|local| local.language_servers.get(&id))
11709            .and_then(|language_server_state| match language_server_state {
11710                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11711                _ => None,
11712            })
11713    }
11714
11715    pub(super) fn update_local_worktree_language_servers(
11716        &mut self,
11717        worktree_handle: &Entity<Worktree>,
11718        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11719        cx: &mut Context<Self>,
11720    ) {
11721        if changes.is_empty() {
11722            return;
11723        }
11724
11725        let Some(local) = self.as_local() else { return };
11726
11727        local.prettier_store.update(cx, |prettier_store, cx| {
11728            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11729        });
11730
11731        let worktree_id = worktree_handle.read(cx).id();
11732        let mut language_server_ids = local
11733            .language_server_ids
11734            .iter()
11735            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11736            .collect::<Vec<_>>();
11737        language_server_ids.sort();
11738        language_server_ids.dedup();
11739
11740        // let abs_path = worktree_handle.read(cx).abs_path();
11741        for server_id in &language_server_ids {
11742            if let Some(LanguageServerState::Running { server, .. }) =
11743                local.language_servers.get(server_id)
11744                && let Some(watched_paths) = local
11745                    .language_server_watched_paths
11746                    .get(server_id)
11747                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11748            {
11749                let params = lsp::DidChangeWatchedFilesParams {
11750                    changes: changes
11751                        .iter()
11752                        .filter_map(|(path, _, change)| {
11753                            if !watched_paths.is_match(path.as_std_path()) {
11754                                return None;
11755                            }
11756                            let typ = match change {
11757                                PathChange::Loaded => return None,
11758                                PathChange::Added => lsp::FileChangeType::CREATED,
11759                                PathChange::Removed => lsp::FileChangeType::DELETED,
11760                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11761                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11762                            };
11763                            let uri = lsp::Uri::from_file_path(
11764                                worktree_handle.read(cx).absolutize(&path),
11765                            )
11766                            .ok()?;
11767                            Some(lsp::FileEvent { uri, typ })
11768                        })
11769                        .collect(),
11770                };
11771                if !params.changes.is_empty() {
11772                    server
11773                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11774                        .ok();
11775                }
11776            }
11777        }
11778        for (path, _, _) in changes {
11779            if let Some(file_name) = path.file_name()
11780                && local.watched_manifest_filenames.contains(file_name)
11781            {
11782                self.request_workspace_config_refresh();
11783                break;
11784            }
11785        }
11786    }
11787
11788    pub fn wait_for_remote_buffer(
11789        &mut self,
11790        id: BufferId,
11791        cx: &mut Context<Self>,
11792    ) -> Task<Result<Entity<Buffer>>> {
11793        self.buffer_store.update(cx, |buffer_store, cx| {
11794            buffer_store.wait_for_remote_buffer(id, cx)
11795        })
11796    }
11797
11798    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11799        let mut result = proto::Symbol {
11800            language_server_name: symbol.language_server_name.0.to_string(),
11801            source_worktree_id: symbol.source_worktree_id.to_proto(),
11802            language_server_id: symbol.source_language_server_id.to_proto(),
11803            name: symbol.name.clone(),
11804            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11805            start: Some(proto::PointUtf16 {
11806                row: symbol.range.start.0.row,
11807                column: symbol.range.start.0.column,
11808            }),
11809            end: Some(proto::PointUtf16 {
11810                row: symbol.range.end.0.row,
11811                column: symbol.range.end.0.column,
11812            }),
11813            worktree_id: Default::default(),
11814            path: Default::default(),
11815            signature: Default::default(),
11816        };
11817        match &symbol.path {
11818            SymbolLocation::InProject(path) => {
11819                result.worktree_id = path.worktree_id.to_proto();
11820                result.path = path.path.to_proto();
11821            }
11822            SymbolLocation::OutsideProject {
11823                abs_path,
11824                signature,
11825            } => {
11826                result.path = abs_path.to_string_lossy().into_owned();
11827                result.signature = signature.to_vec();
11828            }
11829        }
11830        result
11831    }
11832
11833    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11834        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11835        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11836        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11837
11838        let path = if serialized_symbol.signature.is_empty() {
11839            SymbolLocation::InProject(ProjectPath {
11840                worktree_id,
11841                path: RelPath::from_proto(&serialized_symbol.path)
11842                    .context("invalid symbol path")?,
11843            })
11844        } else {
11845            SymbolLocation::OutsideProject {
11846                abs_path: Path::new(&serialized_symbol.path).into(),
11847                signature: serialized_symbol
11848                    .signature
11849                    .try_into()
11850                    .map_err(|_| anyhow!("invalid signature"))?,
11851            }
11852        };
11853
11854        let start = serialized_symbol.start.context("invalid start")?;
11855        let end = serialized_symbol.end.context("invalid end")?;
11856        Ok(CoreSymbol {
11857            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11858            source_worktree_id,
11859            source_language_server_id: LanguageServerId::from_proto(
11860                serialized_symbol.language_server_id,
11861            ),
11862            path,
11863            name: serialized_symbol.name,
11864            range: Unclipped(PointUtf16::new(start.row, start.column))
11865                ..Unclipped(PointUtf16::new(end.row, end.column)),
11866            kind,
11867        })
11868    }
11869
11870    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11871        let mut serialized_completion = proto::Completion {
11872            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11873            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11874            new_text: completion.new_text.clone(),
11875            ..proto::Completion::default()
11876        };
11877        match &completion.source {
11878            CompletionSource::Lsp {
11879                insert_range,
11880                server_id,
11881                lsp_completion,
11882                lsp_defaults,
11883                resolved,
11884            } => {
11885                let (old_insert_start, old_insert_end) = insert_range
11886                    .as_ref()
11887                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11888                    .unzip();
11889
11890                serialized_completion.old_insert_start = old_insert_start;
11891                serialized_completion.old_insert_end = old_insert_end;
11892                serialized_completion.source = proto::completion::Source::Lsp as i32;
11893                serialized_completion.server_id = server_id.0 as u64;
11894                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11895                serialized_completion.lsp_defaults = lsp_defaults
11896                    .as_deref()
11897                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11898                serialized_completion.resolved = *resolved;
11899            }
11900            CompletionSource::BufferWord {
11901                word_range,
11902                resolved,
11903            } => {
11904                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11905                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11906                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11907                serialized_completion.resolved = *resolved;
11908            }
11909            CompletionSource::Custom => {
11910                serialized_completion.source = proto::completion::Source::Custom as i32;
11911                serialized_completion.resolved = true;
11912            }
11913            CompletionSource::Dap { sort_text } => {
11914                serialized_completion.source = proto::completion::Source::Dap as i32;
11915                serialized_completion.sort_text = Some(sort_text.clone());
11916            }
11917        }
11918
11919        serialized_completion
11920    }
11921
11922    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11923        let old_replace_start = completion
11924            .old_replace_start
11925            .and_then(deserialize_anchor)
11926            .context("invalid old start")?;
11927        let old_replace_end = completion
11928            .old_replace_end
11929            .and_then(deserialize_anchor)
11930            .context("invalid old end")?;
11931        let insert_range = {
11932            match completion.old_insert_start.zip(completion.old_insert_end) {
11933                Some((start, end)) => {
11934                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11935                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11936                    Some(start..end)
11937                }
11938                None => None,
11939            }
11940        };
11941        Ok(CoreCompletion {
11942            replace_range: old_replace_start..old_replace_end,
11943            new_text: completion.new_text,
11944            source: match proto::completion::Source::from_i32(completion.source) {
11945                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11946                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11947                    insert_range,
11948                    server_id: LanguageServerId::from_proto(completion.server_id),
11949                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11950                    lsp_defaults: completion
11951                        .lsp_defaults
11952                        .as_deref()
11953                        .map(serde_json::from_slice)
11954                        .transpose()?,
11955                    resolved: completion.resolved,
11956                },
11957                Some(proto::completion::Source::BufferWord) => {
11958                    let word_range = completion
11959                        .buffer_word_start
11960                        .and_then(deserialize_anchor)
11961                        .context("invalid buffer word start")?
11962                        ..completion
11963                            .buffer_word_end
11964                            .and_then(deserialize_anchor)
11965                            .context("invalid buffer word end")?;
11966                    CompletionSource::BufferWord {
11967                        word_range,
11968                        resolved: completion.resolved,
11969                    }
11970                }
11971                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11972                    sort_text: completion
11973                        .sort_text
11974                        .context("expected sort text to exist")?,
11975                },
11976                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11977            },
11978        })
11979    }
11980
11981    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11982        let (kind, lsp_action) = match &action.lsp_action {
11983            LspAction::Action(code_action) => (
11984                proto::code_action::Kind::Action as i32,
11985                serde_json::to_vec(code_action).unwrap(),
11986            ),
11987            LspAction::Command(command) => (
11988                proto::code_action::Kind::Command as i32,
11989                serde_json::to_vec(command).unwrap(),
11990            ),
11991            LspAction::CodeLens(code_lens) => (
11992                proto::code_action::Kind::CodeLens as i32,
11993                serde_json::to_vec(code_lens).unwrap(),
11994            ),
11995        };
11996
11997        proto::CodeAction {
11998            server_id: action.server_id.0 as u64,
11999            start: Some(serialize_anchor(&action.range.start)),
12000            end: Some(serialize_anchor(&action.range.end)),
12001            lsp_action,
12002            kind,
12003            resolved: action.resolved,
12004        }
12005    }
12006
12007    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12008        let start = action
12009            .start
12010            .and_then(deserialize_anchor)
12011            .context("invalid start")?;
12012        let end = action
12013            .end
12014            .and_then(deserialize_anchor)
12015            .context("invalid end")?;
12016        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12017            Some(proto::code_action::Kind::Action) => {
12018                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12019            }
12020            Some(proto::code_action::Kind::Command) => {
12021                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12022            }
12023            Some(proto::code_action::Kind::CodeLens) => {
12024                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12025            }
12026            None => anyhow::bail!("Unknown action kind {}", action.kind),
12027        };
12028        Ok(CodeAction {
12029            server_id: LanguageServerId(action.server_id as usize),
12030            range: start..end,
12031            resolved: action.resolved,
12032            lsp_action,
12033        })
12034    }
12035
12036    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12037        match &formatting_result {
12038            Ok(_) => self.last_formatting_failure = None,
12039            Err(error) => {
12040                let error_string = format!("{error:#}");
12041                log::error!("Formatting failed: {error_string}");
12042                self.last_formatting_failure
12043                    .replace(error_string.lines().join(" "));
12044            }
12045        }
12046    }
12047
12048    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12049        self.lsp_server_capabilities.remove(&for_server);
12050        for lsp_data in self.lsp_data.values_mut() {
12051            lsp_data.remove_server_data(for_server);
12052        }
12053        if let Some(local) = self.as_local_mut() {
12054            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12055            local
12056                .workspace_pull_diagnostics_result_ids
12057                .remove(&for_server);
12058            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12059                buffer_servers.remove(&for_server);
12060            }
12061        }
12062    }
12063
12064    pub fn result_id_for_buffer_pull(
12065        &self,
12066        server_id: LanguageServerId,
12067        buffer_id: BufferId,
12068        registration_id: &Option<SharedString>,
12069        cx: &App,
12070    ) -> Option<SharedString> {
12071        let abs_path = self
12072            .buffer_store
12073            .read(cx)
12074            .get(buffer_id)
12075            .and_then(|b| File::from_dyn(b.read(cx).file()))
12076            .map(|f| f.abs_path(cx))?;
12077        self.as_local()?
12078            .buffer_pull_diagnostics_result_ids
12079            .get(&server_id)?
12080            .get(registration_id)?
12081            .get(&abs_path)?
12082            .clone()
12083    }
12084
12085    /// Gets all result_ids for a workspace diagnostics pull request.
12086    /// 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.
12087    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12088    pub fn result_ids_for_workspace_refresh(
12089        &self,
12090        server_id: LanguageServerId,
12091        registration_id: &Option<SharedString>,
12092    ) -> HashMap<PathBuf, SharedString> {
12093        let Some(local) = self.as_local() else {
12094            return HashMap::default();
12095        };
12096        local
12097            .workspace_pull_diagnostics_result_ids
12098            .get(&server_id)
12099            .into_iter()
12100            .filter_map(|diagnostics| diagnostics.get(registration_id))
12101            .flatten()
12102            .filter_map(|(abs_path, result_id)| {
12103                let result_id = local
12104                    .buffer_pull_diagnostics_result_ids
12105                    .get(&server_id)
12106                    .and_then(|buffer_ids_result_ids| {
12107                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12108                    })
12109                    .cloned()
12110                    .flatten()
12111                    .or_else(|| result_id.clone())?;
12112                Some((abs_path.clone(), result_id))
12113            })
12114            .collect()
12115    }
12116
12117    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12118        if let Some(LanguageServerState::Running {
12119            workspace_diagnostics_refresh_tasks,
12120            ..
12121        }) = self
12122            .as_local_mut()
12123            .and_then(|local| local.language_servers.get_mut(&server_id))
12124        {
12125            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12126                diagnostics.refresh_tx.try_send(()).ok();
12127            }
12128        }
12129    }
12130
12131    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
12132        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
12133            return;
12134        };
12135        let Some(local) = self.as_local_mut() else {
12136            return;
12137        };
12138
12139        for server_id in buffer.update(cx, |buffer, cx| {
12140            local.language_server_ids_for_buffer(buffer, cx)
12141        }) {
12142            if let Some(LanguageServerState::Running {
12143                workspace_diagnostics_refresh_tasks,
12144                ..
12145            }) = local.language_servers.get_mut(&server_id)
12146            {
12147                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12148                    diagnostics.refresh_tx.try_send(()).ok();
12149                }
12150            }
12151        }
12152    }
12153
12154    fn apply_workspace_diagnostic_report(
12155        &mut self,
12156        server_id: LanguageServerId,
12157        report: lsp::WorkspaceDiagnosticReportResult,
12158        registration_id: Option<SharedString>,
12159        cx: &mut Context<Self>,
12160    ) {
12161        let workspace_diagnostics =
12162            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12163                report,
12164                server_id,
12165                registration_id,
12166            );
12167        let mut unchanged_buffers = HashMap::default();
12168        let workspace_diagnostics_updates = workspace_diagnostics
12169            .into_iter()
12170            .filter_map(
12171                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12172                    LspPullDiagnostics::Response {
12173                        server_id,
12174                        uri,
12175                        diagnostics,
12176                        registration_id,
12177                    } => Some((
12178                        server_id,
12179                        uri,
12180                        diagnostics,
12181                        workspace_diagnostics.version,
12182                        registration_id,
12183                    )),
12184                    LspPullDiagnostics::Default => None,
12185                },
12186            )
12187            .fold(
12188                HashMap::default(),
12189                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12190                    let (result_id, diagnostics) = match diagnostics {
12191                        PulledDiagnostics::Unchanged { result_id } => {
12192                            unchanged_buffers
12193                                .entry(new_registration_id.clone())
12194                                .or_insert_with(HashSet::default)
12195                                .insert(uri.clone());
12196                            (Some(result_id), Vec::new())
12197                        }
12198                        PulledDiagnostics::Changed {
12199                            result_id,
12200                            diagnostics,
12201                        } => (result_id, diagnostics),
12202                    };
12203                    let disk_based_sources = Cow::Owned(
12204                        self.language_server_adapter_for_id(server_id)
12205                            .as_ref()
12206                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12207                            .unwrap_or(&[])
12208                            .to_vec(),
12209                    );
12210
12211                    let Some(abs_path) = uri.to_file_path().ok() else {
12212                        return acc;
12213                    };
12214                    let Some((worktree, relative_path)) =
12215                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12216                    else {
12217                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12218                        return acc;
12219                    };
12220                    let worktree_id = worktree.read(cx).id();
12221                    let project_path = ProjectPath {
12222                        worktree_id,
12223                        path: relative_path,
12224                    };
12225                    if let Some(local_lsp_store) = self.as_local_mut() {
12226                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12227                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12228                    }
12229                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12230                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12231                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12232                        acc.entry(server_id)
12233                            .or_insert_with(HashMap::default)
12234                            .entry(new_registration_id.clone())
12235                            .or_insert_with(Vec::new)
12236                            .push(DocumentDiagnosticsUpdate {
12237                                server_id,
12238                                diagnostics: lsp::PublishDiagnosticsParams {
12239                                    uri,
12240                                    diagnostics,
12241                                    version,
12242                                },
12243                                result_id,
12244                                disk_based_sources,
12245                                registration_id: new_registration_id,
12246                            });
12247                    }
12248                    acc
12249                },
12250            );
12251
12252        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12253            for (registration_id, diagnostic_updates) in diagnostic_updates {
12254                self.merge_lsp_diagnostics(
12255                    DiagnosticSourceKind::Pulled,
12256                    diagnostic_updates,
12257                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12258                        DiagnosticSourceKind::Pulled => {
12259                            old_diagnostic.registration_id != registration_id
12260                                || unchanged_buffers
12261                                    .get(&old_diagnostic.registration_id)
12262                                    .is_some_and(|unchanged_buffers| {
12263                                        unchanged_buffers.contains(&document_uri)
12264                                    })
12265                        }
12266                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12267                    },
12268                    cx,
12269                )
12270                .log_err();
12271            }
12272        }
12273    }
12274
12275    fn register_server_capabilities(
12276        &mut self,
12277        server_id: LanguageServerId,
12278        params: lsp::RegistrationParams,
12279        cx: &mut Context<Self>,
12280    ) -> anyhow::Result<()> {
12281        let server = self
12282            .language_server_for_id(server_id)
12283            .with_context(|| format!("no server {server_id} found"))?;
12284        for reg in params.registrations {
12285            match reg.method.as_str() {
12286                "workspace/didChangeWatchedFiles" => {
12287                    if let Some(options) = reg.register_options {
12288                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12289                            let caps = serde_json::from_value(options)?;
12290                            local_lsp_store
12291                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12292                            true
12293                        } else {
12294                            false
12295                        };
12296                        if notify {
12297                            notify_server_capabilities_updated(&server, cx);
12298                        }
12299                    }
12300                }
12301                "workspace/didChangeConfiguration" => {
12302                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12303                }
12304                "workspace/didChangeWorkspaceFolders" => {
12305                    // In this case register options is an empty object, we can ignore it
12306                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12307                        supported: Some(true),
12308                        change_notifications: Some(OneOf::Right(reg.id)),
12309                    };
12310                    server.update_capabilities(|capabilities| {
12311                        capabilities
12312                            .workspace
12313                            .get_or_insert_default()
12314                            .workspace_folders = Some(caps);
12315                    });
12316                    notify_server_capabilities_updated(&server, cx);
12317                }
12318                "workspace/symbol" => {
12319                    let options = parse_register_capabilities(reg)?;
12320                    server.update_capabilities(|capabilities| {
12321                        capabilities.workspace_symbol_provider = Some(options);
12322                    });
12323                    notify_server_capabilities_updated(&server, cx);
12324                }
12325                "workspace/fileOperations" => {
12326                    if let Some(options) = reg.register_options {
12327                        let caps = serde_json::from_value(options)?;
12328                        server.update_capabilities(|capabilities| {
12329                            capabilities
12330                                .workspace
12331                                .get_or_insert_default()
12332                                .file_operations = Some(caps);
12333                        });
12334                        notify_server_capabilities_updated(&server, cx);
12335                    }
12336                }
12337                "workspace/executeCommand" => {
12338                    if let Some(options) = reg.register_options {
12339                        let options = serde_json::from_value(options)?;
12340                        server.update_capabilities(|capabilities| {
12341                            capabilities.execute_command_provider = Some(options);
12342                        });
12343                        notify_server_capabilities_updated(&server, cx);
12344                    }
12345                }
12346                "textDocument/rangeFormatting" => {
12347                    let options = parse_register_capabilities(reg)?;
12348                    server.update_capabilities(|capabilities| {
12349                        capabilities.document_range_formatting_provider = Some(options);
12350                    });
12351                    notify_server_capabilities_updated(&server, cx);
12352                }
12353                "textDocument/onTypeFormatting" => {
12354                    if let Some(options) = reg
12355                        .register_options
12356                        .map(serde_json::from_value)
12357                        .transpose()?
12358                    {
12359                        server.update_capabilities(|capabilities| {
12360                            capabilities.document_on_type_formatting_provider = Some(options);
12361                        });
12362                        notify_server_capabilities_updated(&server, cx);
12363                    }
12364                }
12365                "textDocument/formatting" => {
12366                    let options = parse_register_capabilities(reg)?;
12367                    server.update_capabilities(|capabilities| {
12368                        capabilities.document_formatting_provider = Some(options);
12369                    });
12370                    notify_server_capabilities_updated(&server, cx);
12371                }
12372                "textDocument/rename" => {
12373                    let options = parse_register_capabilities(reg)?;
12374                    server.update_capabilities(|capabilities| {
12375                        capabilities.rename_provider = Some(options);
12376                    });
12377                    notify_server_capabilities_updated(&server, cx);
12378                }
12379                "textDocument/inlayHint" => {
12380                    let options = parse_register_capabilities(reg)?;
12381                    server.update_capabilities(|capabilities| {
12382                        capabilities.inlay_hint_provider = Some(options);
12383                    });
12384                    notify_server_capabilities_updated(&server, cx);
12385                }
12386                "textDocument/documentSymbol" => {
12387                    let options = parse_register_capabilities(reg)?;
12388                    server.update_capabilities(|capabilities| {
12389                        capabilities.document_symbol_provider = Some(options);
12390                    });
12391                    notify_server_capabilities_updated(&server, cx);
12392                }
12393                "textDocument/codeAction" => {
12394                    let options = parse_register_capabilities(reg)?;
12395                    let provider = match options {
12396                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12397                        OneOf::Right(caps) => caps,
12398                    };
12399                    server.update_capabilities(|capabilities| {
12400                        capabilities.code_action_provider = Some(provider);
12401                    });
12402                    notify_server_capabilities_updated(&server, cx);
12403                }
12404                "textDocument/definition" => {
12405                    let options = parse_register_capabilities(reg)?;
12406                    server.update_capabilities(|capabilities| {
12407                        capabilities.definition_provider = Some(options);
12408                    });
12409                    notify_server_capabilities_updated(&server, cx);
12410                }
12411                "textDocument/completion" => {
12412                    if let Some(caps) = reg
12413                        .register_options
12414                        .map(serde_json::from_value::<CompletionOptions>)
12415                        .transpose()?
12416                    {
12417                        server.update_capabilities(|capabilities| {
12418                            capabilities.completion_provider = Some(caps.clone());
12419                        });
12420
12421                        if let Some(local) = self.as_local() {
12422                            let mut buffers_with_language_server = Vec::new();
12423                            for handle in self.buffer_store.read(cx).buffers() {
12424                                let buffer_id = handle.read(cx).remote_id();
12425                                if local
12426                                    .buffers_opened_in_servers
12427                                    .get(&buffer_id)
12428                                    .filter(|s| s.contains(&server_id))
12429                                    .is_some()
12430                                {
12431                                    buffers_with_language_server.push(handle);
12432                                }
12433                            }
12434                            let triggers = caps
12435                                .trigger_characters
12436                                .unwrap_or_default()
12437                                .into_iter()
12438                                .collect::<BTreeSet<_>>();
12439                            for handle in buffers_with_language_server {
12440                                let triggers = triggers.clone();
12441                                let _ = handle.update(cx, move |buffer, cx| {
12442                                    buffer.set_completion_triggers(server_id, triggers, cx);
12443                                });
12444                            }
12445                        }
12446                        notify_server_capabilities_updated(&server, cx);
12447                    }
12448                }
12449                "textDocument/hover" => {
12450                    let options = parse_register_capabilities(reg)?;
12451                    let provider = match options {
12452                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12453                        OneOf::Right(caps) => caps,
12454                    };
12455                    server.update_capabilities(|capabilities| {
12456                        capabilities.hover_provider = Some(provider);
12457                    });
12458                    notify_server_capabilities_updated(&server, cx);
12459                }
12460                "textDocument/signatureHelp" => {
12461                    if let Some(caps) = reg
12462                        .register_options
12463                        .map(serde_json::from_value)
12464                        .transpose()?
12465                    {
12466                        server.update_capabilities(|capabilities| {
12467                            capabilities.signature_help_provider = Some(caps);
12468                        });
12469                        notify_server_capabilities_updated(&server, cx);
12470                    }
12471                }
12472                "textDocument/didChange" => {
12473                    if let Some(sync_kind) = reg
12474                        .register_options
12475                        .and_then(|opts| opts.get("syncKind").cloned())
12476                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12477                        .transpose()?
12478                    {
12479                        server.update_capabilities(|capabilities| {
12480                            let mut sync_options =
12481                                Self::take_text_document_sync_options(capabilities);
12482                            sync_options.change = Some(sync_kind);
12483                            capabilities.text_document_sync =
12484                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12485                        });
12486                        notify_server_capabilities_updated(&server, cx);
12487                    }
12488                }
12489                "textDocument/didSave" => {
12490                    if let Some(include_text) = reg
12491                        .register_options
12492                        .map(|opts| {
12493                            let transpose = opts
12494                                .get("includeText")
12495                                .cloned()
12496                                .map(serde_json::from_value::<Option<bool>>)
12497                                .transpose();
12498                            match transpose {
12499                                Ok(value) => Ok(value.flatten()),
12500                                Err(e) => Err(e),
12501                            }
12502                        })
12503                        .transpose()?
12504                    {
12505                        server.update_capabilities(|capabilities| {
12506                            let mut sync_options =
12507                                Self::take_text_document_sync_options(capabilities);
12508                            sync_options.save =
12509                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12510                                    include_text,
12511                                }));
12512                            capabilities.text_document_sync =
12513                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12514                        });
12515                        notify_server_capabilities_updated(&server, cx);
12516                    }
12517                }
12518                "textDocument/codeLens" => {
12519                    if let Some(caps) = reg
12520                        .register_options
12521                        .map(serde_json::from_value)
12522                        .transpose()?
12523                    {
12524                        server.update_capabilities(|capabilities| {
12525                            capabilities.code_lens_provider = Some(caps);
12526                        });
12527                        notify_server_capabilities_updated(&server, cx);
12528                    }
12529                }
12530                "textDocument/diagnostic" => {
12531                    if let Some(caps) = reg
12532                        .register_options
12533                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12534                        .transpose()?
12535                    {
12536                        let local = self
12537                            .as_local_mut()
12538                            .context("Expected LSP Store to be local")?;
12539                        let state = local
12540                            .language_servers
12541                            .get_mut(&server_id)
12542                            .context("Could not obtain Language Servers state")?;
12543                        local
12544                            .language_server_dynamic_registrations
12545                            .entry(server_id)
12546                            .or_default()
12547                            .diagnostics
12548                            .insert(Some(reg.id.clone()), caps.clone());
12549
12550                        let supports_workspace_diagnostics =
12551                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12552                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12553                                    diagnostic_options.workspace_diagnostics
12554                                }
12555                                DiagnosticServerCapabilities::RegistrationOptions(
12556                                    diagnostic_registration_options,
12557                                ) => {
12558                                    diagnostic_registration_options
12559                                        .diagnostic_options
12560                                        .workspace_diagnostics
12561                                }
12562                            };
12563
12564                        if supports_workspace_diagnostics(&caps) {
12565                            if let LanguageServerState::Running {
12566                                workspace_diagnostics_refresh_tasks,
12567                                ..
12568                            } = state
12569                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12570                                    Some(reg.id.clone()),
12571                                    caps.clone(),
12572                                    server.clone(),
12573                                    cx,
12574                                )
12575                            {
12576                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12577                            }
12578                        }
12579
12580                        server.update_capabilities(|capabilities| {
12581                            capabilities.diagnostic_provider = Some(caps);
12582                        });
12583
12584                        notify_server_capabilities_updated(&server, cx);
12585                    }
12586                }
12587                "textDocument/documentColor" => {
12588                    let options = parse_register_capabilities(reg)?;
12589                    let provider = match options {
12590                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12591                        OneOf::Right(caps) => caps,
12592                    };
12593                    server.update_capabilities(|capabilities| {
12594                        capabilities.color_provider = Some(provider);
12595                    });
12596                    notify_server_capabilities_updated(&server, cx);
12597                }
12598                _ => log::warn!("unhandled capability registration: {reg:?}"),
12599            }
12600        }
12601
12602        Ok(())
12603    }
12604
12605    fn unregister_server_capabilities(
12606        &mut self,
12607        server_id: LanguageServerId,
12608        params: lsp::UnregistrationParams,
12609        cx: &mut Context<Self>,
12610    ) -> anyhow::Result<()> {
12611        let server = self
12612            .language_server_for_id(server_id)
12613            .with_context(|| format!("no server {server_id} found"))?;
12614        for unreg in params.unregisterations.iter() {
12615            match unreg.method.as_str() {
12616                "workspace/didChangeWatchedFiles" => {
12617                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12618                        local_lsp_store
12619                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12620                        true
12621                    } else {
12622                        false
12623                    };
12624                    if notify {
12625                        notify_server_capabilities_updated(&server, cx);
12626                    }
12627                }
12628                "workspace/didChangeConfiguration" => {
12629                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12630                }
12631                "workspace/didChangeWorkspaceFolders" => {
12632                    server.update_capabilities(|capabilities| {
12633                        capabilities
12634                            .workspace
12635                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12636                                workspace_folders: None,
12637                                file_operations: None,
12638                            })
12639                            .workspace_folders = None;
12640                    });
12641                    notify_server_capabilities_updated(&server, cx);
12642                }
12643                "workspace/symbol" => {
12644                    server.update_capabilities(|capabilities| {
12645                        capabilities.workspace_symbol_provider = None
12646                    });
12647                    notify_server_capabilities_updated(&server, cx);
12648                }
12649                "workspace/fileOperations" => {
12650                    server.update_capabilities(|capabilities| {
12651                        capabilities
12652                            .workspace
12653                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12654                                workspace_folders: None,
12655                                file_operations: None,
12656                            })
12657                            .file_operations = None;
12658                    });
12659                    notify_server_capabilities_updated(&server, cx);
12660                }
12661                "workspace/executeCommand" => {
12662                    server.update_capabilities(|capabilities| {
12663                        capabilities.execute_command_provider = None;
12664                    });
12665                    notify_server_capabilities_updated(&server, cx);
12666                }
12667                "textDocument/rangeFormatting" => {
12668                    server.update_capabilities(|capabilities| {
12669                        capabilities.document_range_formatting_provider = None
12670                    });
12671                    notify_server_capabilities_updated(&server, cx);
12672                }
12673                "textDocument/onTypeFormatting" => {
12674                    server.update_capabilities(|capabilities| {
12675                        capabilities.document_on_type_formatting_provider = None;
12676                    });
12677                    notify_server_capabilities_updated(&server, cx);
12678                }
12679                "textDocument/formatting" => {
12680                    server.update_capabilities(|capabilities| {
12681                        capabilities.document_formatting_provider = None;
12682                    });
12683                    notify_server_capabilities_updated(&server, cx);
12684                }
12685                "textDocument/rename" => {
12686                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12687                    notify_server_capabilities_updated(&server, cx);
12688                }
12689                "textDocument/codeAction" => {
12690                    server.update_capabilities(|capabilities| {
12691                        capabilities.code_action_provider = None;
12692                    });
12693                    notify_server_capabilities_updated(&server, cx);
12694                }
12695                "textDocument/definition" => {
12696                    server.update_capabilities(|capabilities| {
12697                        capabilities.definition_provider = None;
12698                    });
12699                    notify_server_capabilities_updated(&server, cx);
12700                }
12701                "textDocument/completion" => {
12702                    server.update_capabilities(|capabilities| {
12703                        capabilities.completion_provider = None;
12704                    });
12705                    notify_server_capabilities_updated(&server, cx);
12706                }
12707                "textDocument/hover" => {
12708                    server.update_capabilities(|capabilities| {
12709                        capabilities.hover_provider = None;
12710                    });
12711                    notify_server_capabilities_updated(&server, cx);
12712                }
12713                "textDocument/signatureHelp" => {
12714                    server.update_capabilities(|capabilities| {
12715                        capabilities.signature_help_provider = None;
12716                    });
12717                    notify_server_capabilities_updated(&server, cx);
12718                }
12719                "textDocument/didChange" => {
12720                    server.update_capabilities(|capabilities| {
12721                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12722                        sync_options.change = None;
12723                        capabilities.text_document_sync =
12724                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12725                    });
12726                    notify_server_capabilities_updated(&server, cx);
12727                }
12728                "textDocument/didSave" => {
12729                    server.update_capabilities(|capabilities| {
12730                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12731                        sync_options.save = None;
12732                        capabilities.text_document_sync =
12733                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12734                    });
12735                    notify_server_capabilities_updated(&server, cx);
12736                }
12737                "textDocument/codeLens" => {
12738                    server.update_capabilities(|capabilities| {
12739                        capabilities.code_lens_provider = None;
12740                    });
12741                    notify_server_capabilities_updated(&server, cx);
12742                }
12743                "textDocument/diagnostic" => {
12744                    let local = self
12745                        .as_local_mut()
12746                        .context("Expected LSP Store to be local")?;
12747
12748                    let state = local
12749                        .language_servers
12750                        .get_mut(&server_id)
12751                        .context("Could not obtain Language Servers state")?;
12752                    let registrations = local
12753                        .language_server_dynamic_registrations
12754                        .get_mut(&server_id)
12755                        .with_context(|| {
12756                            format!("Expected dynamic registration to exist for server {server_id}")
12757                        })?;
12758                    registrations.diagnostics
12759                        .remove(&Some(unreg.id.clone()))
12760                        .with_context(|| format!(
12761                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12762                            unreg.id)
12763                        )?;
12764                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12765
12766                    if let LanguageServerState::Running {
12767                        workspace_diagnostics_refresh_tasks,
12768                        ..
12769                    } = state
12770                    {
12771                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12772                    }
12773
12774                    if removed_last_diagnostic_provider {
12775                        server.update_capabilities(|capabilities| {
12776                            debug_assert!(capabilities.diagnostic_provider.is_some());
12777                            capabilities.diagnostic_provider = None;
12778                        });
12779                    }
12780
12781                    notify_server_capabilities_updated(&server, cx);
12782                }
12783                "textDocument/documentColor" => {
12784                    server.update_capabilities(|capabilities| {
12785                        capabilities.color_provider = None;
12786                    });
12787                    notify_server_capabilities_updated(&server, cx);
12788                }
12789                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12790            }
12791        }
12792
12793        Ok(())
12794    }
12795
12796    async fn deduplicate_range_based_lsp_requests<T>(
12797        lsp_store: &Entity<Self>,
12798        server_id: Option<LanguageServerId>,
12799        lsp_request_id: LspRequestId,
12800        proto_request: &T::ProtoRequest,
12801        range: Range<Anchor>,
12802        cx: &mut AsyncApp,
12803    ) -> Result<()>
12804    where
12805        T: LspCommand,
12806        T::ProtoRequest: proto::LspRequestMessage,
12807    {
12808        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12809        let version = deserialize_version(proto_request.buffer_version());
12810        let buffer = lsp_store.update(cx, |this, cx| {
12811            this.buffer_store.read(cx).get_existing(buffer_id)
12812        })??;
12813        buffer
12814            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12815            .await?;
12816        lsp_store.update(cx, |lsp_store, cx| {
12817            let buffer_snapshot = buffer.read(cx).snapshot();
12818            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12819            let chunks_queried_for = lsp_data
12820                .inlay_hints
12821                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12822                .collect::<Vec<_>>();
12823            match chunks_queried_for.as_slice() {
12824                &[chunk] => {
12825                    let key = LspKey {
12826                        request_type: TypeId::of::<T>(),
12827                        server_queried: server_id,
12828                    };
12829                    let previous_request = lsp_data
12830                        .chunk_lsp_requests
12831                        .entry(key)
12832                        .or_default()
12833                        .insert(chunk, lsp_request_id);
12834                    if let Some((previous_request, running_requests)) =
12835                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12836                    {
12837                        running_requests.remove(&previous_request);
12838                    }
12839                }
12840                _ambiguous_chunks => {
12841                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12842                    // there, a buffer version-based check will be performed and outdated requests discarded.
12843                }
12844            }
12845            anyhow::Ok(())
12846        })??;
12847
12848        Ok(())
12849    }
12850
12851    async fn query_lsp_locally<T>(
12852        lsp_store: Entity<Self>,
12853        for_server_id: Option<LanguageServerId>,
12854        sender_id: proto::PeerId,
12855        lsp_request_id: LspRequestId,
12856        proto_request: T::ProtoRequest,
12857        position: Option<Anchor>,
12858        cx: &mut AsyncApp,
12859    ) -> Result<()>
12860    where
12861        T: LspCommand + Clone,
12862        T::ProtoRequest: proto::LspRequestMessage,
12863        <T::ProtoRequest as proto::RequestMessage>::Response:
12864            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12865    {
12866        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12867        let version = deserialize_version(proto_request.buffer_version());
12868        let buffer = lsp_store.update(cx, |this, cx| {
12869            this.buffer_store.read(cx).get_existing(buffer_id)
12870        })??;
12871        buffer
12872            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12873            .await?;
12874        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12875        let request =
12876            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12877        let key = LspKey {
12878            request_type: TypeId::of::<T>(),
12879            server_queried: for_server_id,
12880        };
12881        lsp_store.update(cx, |lsp_store, cx| {
12882            let request_task = match for_server_id {
12883                Some(server_id) => {
12884                    let server_task = lsp_store.request_lsp(
12885                        buffer.clone(),
12886                        LanguageServerToQuery::Other(server_id),
12887                        request.clone(),
12888                        cx,
12889                    );
12890                    cx.background_spawn(async move {
12891                        let mut responses = Vec::new();
12892                        match server_task.await {
12893                            Ok(response) => responses.push((server_id, response)),
12894                            // rust-analyzer likes to error with this when its still loading up
12895                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12896                            Err(e) => log::error!(
12897                                "Error handling response for request {request:?}: {e:#}"
12898                            ),
12899                        }
12900                        responses
12901                    })
12902                }
12903                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12904            };
12905            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12906            if T::ProtoRequest::stop_previous_requests() {
12907                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12908                    lsp_requests.clear();
12909                }
12910            }
12911            lsp_data.lsp_requests.entry(key).or_default().insert(
12912                lsp_request_id,
12913                cx.spawn(async move |lsp_store, cx| {
12914                    let response = request_task.await;
12915                    lsp_store
12916                        .update(cx, |lsp_store, cx| {
12917                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12918                            {
12919                                let response = response
12920                                    .into_iter()
12921                                    .map(|(server_id, response)| {
12922                                        (
12923                                            server_id.to_proto(),
12924                                            T::response_to_proto(
12925                                                response,
12926                                                lsp_store,
12927                                                sender_id,
12928                                                &buffer_version,
12929                                                cx,
12930                                            )
12931                                            .into(),
12932                                        )
12933                                    })
12934                                    .collect::<HashMap<_, _>>();
12935                                match client.send_lsp_response::<T::ProtoRequest>(
12936                                    project_id,
12937                                    lsp_request_id,
12938                                    response,
12939                                ) {
12940                                    Ok(()) => {}
12941                                    Err(e) => {
12942                                        log::error!("Failed to send LSP response: {e:#}",)
12943                                    }
12944                                }
12945                            }
12946                        })
12947                        .ok();
12948                }),
12949            );
12950        })?;
12951        Ok(())
12952    }
12953
12954    fn take_text_document_sync_options(
12955        capabilities: &mut lsp::ServerCapabilities,
12956    ) -> lsp::TextDocumentSyncOptions {
12957        match capabilities.text_document_sync.take() {
12958            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12959            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12960                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12961                sync_options.change = Some(sync_kind);
12962                sync_options
12963            }
12964            None => lsp::TextDocumentSyncOptions::default(),
12965        }
12966    }
12967
12968    #[cfg(any(test, feature = "test-support"))]
12969    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12970        Some(
12971            self.lsp_data
12972                .get_mut(&buffer_id)?
12973                .code_lens
12974                .take()?
12975                .update
12976                .take()?
12977                .1,
12978        )
12979    }
12980
12981    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12982        self.downstream_client.clone()
12983    }
12984
12985    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12986        self.worktree_store.clone()
12987    }
12988
12989    /// Gets what's stored in the LSP data for the given buffer.
12990    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12991        self.lsp_data.get_mut(&buffer_id)
12992    }
12993
12994    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12995    /// new [`BufferLspData`] will be created to replace the previous state.
12996    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
12997        let (buffer_id, buffer_version) =
12998            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
12999        let lsp_data = self
13000            .lsp_data
13001            .entry(buffer_id)
13002            .or_insert_with(|| BufferLspData::new(buffer, cx));
13003        if buffer_version.changed_since(&lsp_data.buffer_version) {
13004            *lsp_data = BufferLspData::new(buffer, cx);
13005        }
13006        lsp_data
13007    }
13008}
13009
13010// Registration with registerOptions as null, should fallback to true.
13011// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13012fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13013    reg: lsp::Registration,
13014) -> Result<OneOf<bool, T>> {
13015    Ok(match reg.register_options {
13016        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13017        None => OneOf::Left(true),
13018    })
13019}
13020
13021fn subscribe_to_binary_statuses(
13022    languages: &Arc<LanguageRegistry>,
13023    cx: &mut Context<'_, LspStore>,
13024) -> Task<()> {
13025    let mut server_statuses = languages.language_server_binary_statuses();
13026    cx.spawn(async move |lsp_store, cx| {
13027        while let Some((server_name, binary_status)) = server_statuses.next().await {
13028            if lsp_store
13029                .update(cx, |_, cx| {
13030                    let mut message = None;
13031                    let binary_status = match binary_status {
13032                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13033                        BinaryStatus::CheckingForUpdate => {
13034                            proto::ServerBinaryStatus::CheckingForUpdate
13035                        }
13036                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13037                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13038                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13039                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13040                        BinaryStatus::Failed { error } => {
13041                            message = Some(error);
13042                            proto::ServerBinaryStatus::Failed
13043                        }
13044                    };
13045                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13046                        // Binary updates are about the binary that might not have any language server id at that point.
13047                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13048                        language_server_id: LanguageServerId(0),
13049                        name: Some(server_name),
13050                        message: proto::update_language_server::Variant::StatusUpdate(
13051                            proto::StatusUpdate {
13052                                message,
13053                                status: Some(proto::status_update::Status::Binary(
13054                                    binary_status as i32,
13055                                )),
13056                            },
13057                        ),
13058                    });
13059                })
13060                .is_err()
13061            {
13062                break;
13063            }
13064        }
13065    })
13066}
13067
13068fn lsp_workspace_diagnostics_refresh(
13069    registration_id: Option<String>,
13070    options: DiagnosticServerCapabilities,
13071    server: Arc<LanguageServer>,
13072    cx: &mut Context<'_, LspStore>,
13073) -> Option<WorkspaceRefreshTask> {
13074    let identifier = workspace_diagnostic_identifier(&options)?;
13075    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13076
13077    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13078    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13079    refresh_tx.try_send(()).ok();
13080
13081    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13082        let mut attempts = 0;
13083        let max_attempts = 50;
13084        let mut requests = 0;
13085
13086        loop {
13087            let Some(()) = refresh_rx.recv().await else {
13088                return;
13089            };
13090
13091            'request: loop {
13092                requests += 1;
13093                if attempts > max_attempts {
13094                    log::error!(
13095                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13096                    );
13097                    return;
13098                }
13099                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13100                cx.background_executor()
13101                    .timer(Duration::from_millis(backoff_millis))
13102                    .await;
13103                attempts += 1;
13104
13105                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13106                    lsp_store
13107                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13108                        .into_iter()
13109                        .filter_map(|(abs_path, result_id)| {
13110                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13111                            Some(lsp::PreviousResultId {
13112                                uri,
13113                                value: result_id.to_string(),
13114                            })
13115                        })
13116                        .collect()
13117                }) else {
13118                    return;
13119                };
13120
13121                let token = if let Some(registration_id) = &registration_id {
13122                    format!(
13123                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13124                        server.server_id(),
13125                    )
13126                } else {
13127                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13128                };
13129
13130                progress_rx.try_recv().ok();
13131                let timer =
13132                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13133                let progress = pin!(progress_rx.recv().fuse());
13134                let response_result = server
13135                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13136                        lsp::WorkspaceDiagnosticParams {
13137                            previous_result_ids,
13138                            identifier: identifier.clone(),
13139                            work_done_progress_params: Default::default(),
13140                            partial_result_params: lsp::PartialResultParams {
13141                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13142                            },
13143                        },
13144                        select(timer, progress).then(|either| match either {
13145                            Either::Left((message, ..)) => ready(message).left_future(),
13146                            Either::Right(..) => pending::<String>().right_future(),
13147                        }),
13148                    )
13149                    .await;
13150
13151                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13152                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13153                match response_result {
13154                    ConnectionResult::Timeout => {
13155                        log::error!("Timeout during workspace diagnostics pull");
13156                        continue 'request;
13157                    }
13158                    ConnectionResult::ConnectionReset => {
13159                        log::error!("Server closed a workspace diagnostics pull request");
13160                        continue 'request;
13161                    }
13162                    ConnectionResult::Result(Err(e)) => {
13163                        log::error!("Error during workspace diagnostics pull: {e:#}");
13164                        break 'request;
13165                    }
13166                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13167                        attempts = 0;
13168                        if lsp_store
13169                            .update(cx, |lsp_store, cx| {
13170                                lsp_store.apply_workspace_diagnostic_report(
13171                                    server.server_id(),
13172                                    pulled_diagnostics,
13173                                    registration_id_shared.clone(),
13174                                    cx,
13175                                )
13176                            })
13177                            .is_err()
13178                        {
13179                            return;
13180                        }
13181                        break 'request;
13182                    }
13183                }
13184            }
13185        }
13186    });
13187
13188    Some(WorkspaceRefreshTask {
13189        refresh_tx,
13190        progress_tx,
13191        task: workspace_query_language_server,
13192    })
13193}
13194
13195fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13196    match &options {
13197        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13198            diagnostic_options.identifier.clone()
13199        }
13200        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13201            let diagnostic_options = &registration_options.diagnostic_options;
13202            diagnostic_options.identifier.clone()
13203        }
13204    }
13205}
13206
13207fn workspace_diagnostic_identifier(
13208    options: &DiagnosticServerCapabilities,
13209) -> Option<Option<String>> {
13210    match &options {
13211        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13212            if !diagnostic_options.workspace_diagnostics {
13213                return None;
13214            }
13215            Some(diagnostic_options.identifier.clone())
13216        }
13217        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13218            let diagnostic_options = &registration_options.diagnostic_options;
13219            if !diagnostic_options.workspace_diagnostics {
13220                return None;
13221            }
13222            Some(diagnostic_options.identifier.clone())
13223        }
13224    }
13225}
13226
13227fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13228    let CompletionSource::BufferWord {
13229        word_range,
13230        resolved,
13231    } = &mut completion.source
13232    else {
13233        return;
13234    };
13235    if *resolved {
13236        return;
13237    }
13238
13239    if completion.new_text
13240        != snapshot
13241            .text_for_range(word_range.clone())
13242            .collect::<String>()
13243    {
13244        return;
13245    }
13246
13247    let mut offset = 0;
13248    for chunk in snapshot.chunks(word_range.clone(), true) {
13249        let end_offset = offset + chunk.text.len();
13250        if let Some(highlight_id) = chunk.syntax_highlight_id {
13251            completion
13252                .label
13253                .runs
13254                .push((offset..end_offset, highlight_id));
13255        }
13256        offset = end_offset;
13257    }
13258    *resolved = true;
13259}
13260
13261impl EventEmitter<LspStoreEvent> for LspStore {}
13262
13263fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13264    hover
13265        .contents
13266        .retain(|hover_block| !hover_block.text.trim().is_empty());
13267    if hover.contents.is_empty() {
13268        None
13269    } else {
13270        Some(hover)
13271    }
13272}
13273
13274async fn populate_labels_for_completions(
13275    new_completions: Vec<CoreCompletion>,
13276    language: Option<Arc<Language>>,
13277    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13278) -> Vec<Completion> {
13279    let lsp_completions = new_completions
13280        .iter()
13281        .filter_map(|new_completion| {
13282            new_completion
13283                .source
13284                .lsp_completion(true)
13285                .map(|lsp_completion| lsp_completion.into_owned())
13286        })
13287        .collect::<Vec<_>>();
13288
13289    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13290        lsp_adapter
13291            .labels_for_completions(&lsp_completions, language)
13292            .await
13293            .log_err()
13294            .unwrap_or_default()
13295    } else {
13296        Vec::new()
13297    }
13298    .into_iter()
13299    .fuse();
13300
13301    let mut completions = Vec::new();
13302    for completion in new_completions {
13303        match completion.source.lsp_completion(true) {
13304            Some(lsp_completion) => {
13305                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13306
13307                let mut label = labels.next().flatten().unwrap_or_else(|| {
13308                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13309                });
13310                ensure_uniform_list_compatible_label(&mut label);
13311                completions.push(Completion {
13312                    label,
13313                    documentation,
13314                    replace_range: completion.replace_range,
13315                    new_text: completion.new_text,
13316                    insert_text_mode: lsp_completion.insert_text_mode,
13317                    source: completion.source,
13318                    icon_path: None,
13319                    confirm: None,
13320                    match_start: None,
13321                    snippet_deduplication_key: None,
13322                });
13323            }
13324            None => {
13325                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13326                ensure_uniform_list_compatible_label(&mut label);
13327                completions.push(Completion {
13328                    label,
13329                    documentation: None,
13330                    replace_range: completion.replace_range,
13331                    new_text: completion.new_text,
13332                    source: completion.source,
13333                    insert_text_mode: None,
13334                    icon_path: None,
13335                    confirm: None,
13336                    match_start: None,
13337                    snippet_deduplication_key: None,
13338                });
13339            }
13340        }
13341    }
13342    completions
13343}
13344
13345#[derive(Debug)]
13346pub enum LanguageServerToQuery {
13347    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13348    FirstCapable,
13349    /// Query a specific language server.
13350    Other(LanguageServerId),
13351}
13352
13353#[derive(Default)]
13354struct RenamePathsWatchedForServer {
13355    did_rename: Vec<RenameActionPredicate>,
13356    will_rename: Vec<RenameActionPredicate>,
13357}
13358
13359impl RenamePathsWatchedForServer {
13360    fn with_did_rename_patterns(
13361        mut self,
13362        did_rename: Option<&FileOperationRegistrationOptions>,
13363    ) -> Self {
13364        if let Some(did_rename) = did_rename {
13365            self.did_rename = did_rename
13366                .filters
13367                .iter()
13368                .filter_map(|filter| filter.try_into().log_err())
13369                .collect();
13370        }
13371        self
13372    }
13373    fn with_will_rename_patterns(
13374        mut self,
13375        will_rename: Option<&FileOperationRegistrationOptions>,
13376    ) -> Self {
13377        if let Some(will_rename) = will_rename {
13378            self.will_rename = will_rename
13379                .filters
13380                .iter()
13381                .filter_map(|filter| filter.try_into().log_err())
13382                .collect();
13383        }
13384        self
13385    }
13386
13387    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13388        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13389    }
13390    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13391        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13392    }
13393}
13394
13395impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13396    type Error = globset::Error;
13397    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13398        Ok(Self {
13399            kind: ops.pattern.matches.clone(),
13400            glob: GlobBuilder::new(&ops.pattern.glob)
13401                .case_insensitive(
13402                    ops.pattern
13403                        .options
13404                        .as_ref()
13405                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13406                )
13407                .build()?
13408                .compile_matcher(),
13409        })
13410    }
13411}
13412struct RenameActionPredicate {
13413    glob: GlobMatcher,
13414    kind: Option<FileOperationPatternKind>,
13415}
13416
13417impl RenameActionPredicate {
13418    // Returns true if language server should be notified
13419    fn eval(&self, path: &str, is_dir: bool) -> bool {
13420        self.kind.as_ref().is_none_or(|kind| {
13421            let expected_kind = if is_dir {
13422                FileOperationPatternKind::Folder
13423            } else {
13424                FileOperationPatternKind::File
13425            };
13426            kind == &expected_kind
13427        }) && self.glob.is_match(path)
13428    }
13429}
13430
13431#[derive(Default)]
13432struct LanguageServerWatchedPaths {
13433    worktree_paths: HashMap<WorktreeId, GlobSet>,
13434    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13435}
13436
13437#[derive(Default)]
13438struct LanguageServerWatchedPathsBuilder {
13439    worktree_paths: HashMap<WorktreeId, GlobSet>,
13440    abs_paths: HashMap<Arc<Path>, GlobSet>,
13441}
13442
13443impl LanguageServerWatchedPathsBuilder {
13444    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13445        self.worktree_paths.insert(worktree_id, glob_set);
13446    }
13447    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13448        self.abs_paths.insert(path, glob_set);
13449    }
13450    fn build(
13451        self,
13452        fs: Arc<dyn Fs>,
13453        language_server_id: LanguageServerId,
13454        cx: &mut Context<LspStore>,
13455    ) -> LanguageServerWatchedPaths {
13456        let lsp_store = cx.weak_entity();
13457
13458        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13459        let abs_paths = self
13460            .abs_paths
13461            .into_iter()
13462            .map(|(abs_path, globset)| {
13463                let task = cx.spawn({
13464                    let abs_path = abs_path.clone();
13465                    let fs = fs.clone();
13466
13467                    let lsp_store = lsp_store.clone();
13468                    async move |_, cx| {
13469                        maybe!(async move {
13470                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13471                            while let Some(update) = push_updates.0.next().await {
13472                                let action = lsp_store
13473                                    .update(cx, |this, _| {
13474                                        let Some(local) = this.as_local() else {
13475                                            return ControlFlow::Break(());
13476                                        };
13477                                        let Some(watcher) = local
13478                                            .language_server_watched_paths
13479                                            .get(&language_server_id)
13480                                        else {
13481                                            return ControlFlow::Break(());
13482                                        };
13483                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13484                                            "Watched abs path is not registered with a watcher",
13485                                        );
13486                                        let matching_entries = update
13487                                            .into_iter()
13488                                            .filter(|event| globs.is_match(&event.path))
13489                                            .collect::<Vec<_>>();
13490                                        this.lsp_notify_abs_paths_changed(
13491                                            language_server_id,
13492                                            matching_entries,
13493                                        );
13494                                        ControlFlow::Continue(())
13495                                    })
13496                                    .ok()?;
13497
13498                                if action.is_break() {
13499                                    break;
13500                                }
13501                            }
13502                            Some(())
13503                        })
13504                        .await;
13505                    }
13506                });
13507                (abs_path, (globset, task))
13508            })
13509            .collect();
13510        LanguageServerWatchedPaths {
13511            worktree_paths: self.worktree_paths,
13512            abs_paths,
13513        }
13514    }
13515}
13516
13517struct LspBufferSnapshot {
13518    version: i32,
13519    snapshot: TextBufferSnapshot,
13520}
13521
13522/// A prompt requested by LSP server.
13523#[derive(Clone, Debug)]
13524pub struct LanguageServerPromptRequest {
13525    pub level: PromptLevel,
13526    pub message: String,
13527    pub actions: Vec<MessageActionItem>,
13528    pub lsp_name: String,
13529    pub(crate) response_channel: Sender<MessageActionItem>,
13530}
13531
13532impl LanguageServerPromptRequest {
13533    pub async fn respond(self, index: usize) -> Option<()> {
13534        if let Some(response) = self.actions.into_iter().nth(index) {
13535            self.response_channel.send(response).await.ok()
13536        } else {
13537            None
13538        }
13539    }
13540}
13541impl PartialEq for LanguageServerPromptRequest {
13542    fn eq(&self, other: &Self) -> bool {
13543        self.message == other.message && self.actions == other.actions
13544    }
13545}
13546
13547#[derive(Clone, Debug, PartialEq)]
13548pub enum LanguageServerLogType {
13549    Log(MessageType),
13550    Trace { verbose_info: Option<String> },
13551    Rpc { received: bool },
13552}
13553
13554impl LanguageServerLogType {
13555    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13556        match self {
13557            Self::Log(log_type) => {
13558                use proto::log_message::LogLevel;
13559                let level = match *log_type {
13560                    MessageType::ERROR => LogLevel::Error,
13561                    MessageType::WARNING => LogLevel::Warning,
13562                    MessageType::INFO => LogLevel::Info,
13563                    MessageType::LOG => LogLevel::Log,
13564                    other => {
13565                        log::warn!("Unknown lsp log message type: {other:?}");
13566                        LogLevel::Log
13567                    }
13568                };
13569                proto::language_server_log::LogType::Log(proto::LogMessage {
13570                    level: level as i32,
13571                })
13572            }
13573            Self::Trace { verbose_info } => {
13574                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13575                    verbose_info: verbose_info.to_owned(),
13576                })
13577            }
13578            Self::Rpc { received } => {
13579                let kind = if *received {
13580                    proto::rpc_message::Kind::Received
13581                } else {
13582                    proto::rpc_message::Kind::Sent
13583                };
13584                let kind = kind as i32;
13585                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13586            }
13587        }
13588    }
13589
13590    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13591        use proto::log_message::LogLevel;
13592        use proto::rpc_message;
13593        match log_type {
13594            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13595                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13596                    LogLevel::Error => MessageType::ERROR,
13597                    LogLevel::Warning => MessageType::WARNING,
13598                    LogLevel::Info => MessageType::INFO,
13599                    LogLevel::Log => MessageType::LOG,
13600                },
13601            ),
13602            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13603                verbose_info: trace_message.verbose_info,
13604            },
13605            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13606                received: match rpc_message::Kind::from_i32(message.kind)
13607                    .unwrap_or(rpc_message::Kind::Received)
13608                {
13609                    rpc_message::Kind::Received => true,
13610                    rpc_message::Kind::Sent => false,
13611                },
13612            },
13613        }
13614    }
13615}
13616
13617pub struct WorkspaceRefreshTask {
13618    refresh_tx: mpsc::Sender<()>,
13619    progress_tx: mpsc::Sender<()>,
13620    #[allow(dead_code)]
13621    task: Task<()>,
13622}
13623
13624pub enum LanguageServerState {
13625    Starting {
13626        startup: Task<Option<Arc<LanguageServer>>>,
13627        /// List of language servers that will be added to the workspace once it's initialization completes.
13628        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13629    },
13630
13631    Running {
13632        adapter: Arc<CachedLspAdapter>,
13633        server: Arc<LanguageServer>,
13634        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13635        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13636    },
13637}
13638
13639impl LanguageServerState {
13640    fn add_workspace_folder(&self, uri: Uri) {
13641        match self {
13642            LanguageServerState::Starting {
13643                pending_workspace_folders,
13644                ..
13645            } => {
13646                pending_workspace_folders.lock().insert(uri);
13647            }
13648            LanguageServerState::Running { server, .. } => {
13649                server.add_workspace_folder(uri);
13650            }
13651        }
13652    }
13653    fn _remove_workspace_folder(&self, uri: Uri) {
13654        match self {
13655            LanguageServerState::Starting {
13656                pending_workspace_folders,
13657                ..
13658            } => {
13659                pending_workspace_folders.lock().remove(&uri);
13660            }
13661            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13662        }
13663    }
13664}
13665
13666impl std::fmt::Debug for LanguageServerState {
13667    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13668        match self {
13669            LanguageServerState::Starting { .. } => {
13670                f.debug_struct("LanguageServerState::Starting").finish()
13671            }
13672            LanguageServerState::Running { .. } => {
13673                f.debug_struct("LanguageServerState::Running").finish()
13674            }
13675        }
13676    }
13677}
13678
13679#[derive(Clone, Debug, Serialize)]
13680pub struct LanguageServerProgress {
13681    pub is_disk_based_diagnostics_progress: bool,
13682    pub is_cancellable: bool,
13683    pub title: Option<String>,
13684    pub message: Option<String>,
13685    pub percentage: Option<usize>,
13686    #[serde(skip_serializing)]
13687    pub last_update_at: Instant,
13688}
13689
13690#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13691pub struct DiagnosticSummary {
13692    pub error_count: usize,
13693    pub warning_count: usize,
13694}
13695
13696impl DiagnosticSummary {
13697    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13698        let mut this = Self {
13699            error_count: 0,
13700            warning_count: 0,
13701        };
13702
13703        for entry in diagnostics {
13704            if entry.diagnostic.is_primary {
13705                match entry.diagnostic.severity {
13706                    DiagnosticSeverity::ERROR => this.error_count += 1,
13707                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13708                    _ => {}
13709                }
13710            }
13711        }
13712
13713        this
13714    }
13715
13716    pub fn is_empty(&self) -> bool {
13717        self.error_count == 0 && self.warning_count == 0
13718    }
13719
13720    pub fn to_proto(
13721        self,
13722        language_server_id: LanguageServerId,
13723        path: &RelPath,
13724    ) -> proto::DiagnosticSummary {
13725        proto::DiagnosticSummary {
13726            path: path.to_proto(),
13727            language_server_id: language_server_id.0 as u64,
13728            error_count: self.error_count as u32,
13729            warning_count: self.warning_count as u32,
13730        }
13731    }
13732}
13733
13734#[derive(Clone, Debug)]
13735pub enum CompletionDocumentation {
13736    /// There is no documentation for this completion.
13737    Undocumented,
13738    /// A single line of documentation.
13739    SingleLine(SharedString),
13740    /// Multiple lines of plain text documentation.
13741    MultiLinePlainText(SharedString),
13742    /// Markdown documentation.
13743    MultiLineMarkdown(SharedString),
13744    /// Both single line and multiple lines of plain text documentation.
13745    SingleLineAndMultiLinePlainText {
13746        single_line: SharedString,
13747        plain_text: Option<SharedString>,
13748    },
13749}
13750
13751impl CompletionDocumentation {
13752    #[cfg(any(test, feature = "test-support"))]
13753    pub fn text(&self) -> SharedString {
13754        match self {
13755            CompletionDocumentation::Undocumented => "".into(),
13756            CompletionDocumentation::SingleLine(s) => s.clone(),
13757            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13758            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13759            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13760                single_line.clone()
13761            }
13762        }
13763    }
13764}
13765
13766impl From<lsp::Documentation> for CompletionDocumentation {
13767    fn from(docs: lsp::Documentation) -> Self {
13768        match docs {
13769            lsp::Documentation::String(text) => {
13770                if text.lines().count() <= 1 {
13771                    CompletionDocumentation::SingleLine(text.into())
13772                } else {
13773                    CompletionDocumentation::MultiLinePlainText(text.into())
13774                }
13775            }
13776
13777            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13778                lsp::MarkupKind::PlainText => {
13779                    if value.lines().count() <= 1 {
13780                        CompletionDocumentation::SingleLine(value.into())
13781                    } else {
13782                        CompletionDocumentation::MultiLinePlainText(value.into())
13783                    }
13784                }
13785
13786                lsp::MarkupKind::Markdown => {
13787                    CompletionDocumentation::MultiLineMarkdown(value.into())
13788                }
13789            },
13790        }
13791    }
13792}
13793
13794pub enum ResolvedHint {
13795    Resolved(InlayHint),
13796    Resolving(Shared<Task<()>>),
13797}
13798
13799fn glob_literal_prefix(glob: &Path) -> PathBuf {
13800    glob.components()
13801        .take_while(|component| match component {
13802            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13803            _ => true,
13804        })
13805        .collect()
13806}
13807
13808pub struct SshLspAdapter {
13809    name: LanguageServerName,
13810    binary: LanguageServerBinary,
13811    initialization_options: Option<String>,
13812    code_action_kinds: Option<Vec<CodeActionKind>>,
13813}
13814
13815impl SshLspAdapter {
13816    pub fn new(
13817        name: LanguageServerName,
13818        binary: LanguageServerBinary,
13819        initialization_options: Option<String>,
13820        code_action_kinds: Option<String>,
13821    ) -> Self {
13822        Self {
13823            name,
13824            binary,
13825            initialization_options,
13826            code_action_kinds: code_action_kinds
13827                .as_ref()
13828                .and_then(|c| serde_json::from_str(c).ok()),
13829        }
13830    }
13831}
13832
13833impl LspInstaller for SshLspAdapter {
13834    type BinaryVersion = ();
13835    async fn check_if_user_installed(
13836        &self,
13837        _: &dyn LspAdapterDelegate,
13838        _: Option<Toolchain>,
13839        _: &AsyncApp,
13840    ) -> Option<LanguageServerBinary> {
13841        Some(self.binary.clone())
13842    }
13843
13844    async fn cached_server_binary(
13845        &self,
13846        _: PathBuf,
13847        _: &dyn LspAdapterDelegate,
13848    ) -> Option<LanguageServerBinary> {
13849        None
13850    }
13851
13852    async fn fetch_latest_server_version(
13853        &self,
13854        _: &dyn LspAdapterDelegate,
13855        _: bool,
13856        _: &mut AsyncApp,
13857    ) -> Result<()> {
13858        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13859    }
13860
13861    async fn fetch_server_binary(
13862        &self,
13863        _: (),
13864        _: PathBuf,
13865        _: &dyn LspAdapterDelegate,
13866    ) -> Result<LanguageServerBinary> {
13867        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13868    }
13869}
13870
13871#[async_trait(?Send)]
13872impl LspAdapter for SshLspAdapter {
13873    fn name(&self) -> LanguageServerName {
13874        self.name.clone()
13875    }
13876
13877    async fn initialization_options(
13878        self: Arc<Self>,
13879        _: &Arc<dyn LspAdapterDelegate>,
13880    ) -> Result<Option<serde_json::Value>> {
13881        let Some(options) = &self.initialization_options else {
13882            return Ok(None);
13883        };
13884        let result = serde_json::from_str(options)?;
13885        Ok(result)
13886    }
13887
13888    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13889        self.code_action_kinds.clone()
13890    }
13891}
13892
13893pub fn language_server_settings<'a>(
13894    delegate: &'a dyn LspAdapterDelegate,
13895    language: &LanguageServerName,
13896    cx: &'a App,
13897) -> Option<&'a LspSettings> {
13898    language_server_settings_for(
13899        SettingsLocation {
13900            worktree_id: delegate.worktree_id(),
13901            path: RelPath::empty(),
13902        },
13903        language,
13904        cx,
13905    )
13906}
13907
13908pub fn language_server_settings_for<'a>(
13909    location: SettingsLocation<'a>,
13910    language: &LanguageServerName,
13911    cx: &'a App,
13912) -> Option<&'a LspSettings> {
13913    ProjectSettings::get(Some(location), cx).lsp.get(language)
13914}
13915
13916pub struct LocalLspAdapterDelegate {
13917    lsp_store: WeakEntity<LspStore>,
13918    worktree: worktree::Snapshot,
13919    fs: Arc<dyn Fs>,
13920    http_client: Arc<dyn HttpClient>,
13921    language_registry: Arc<LanguageRegistry>,
13922    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13923}
13924
13925impl LocalLspAdapterDelegate {
13926    pub fn new(
13927        language_registry: Arc<LanguageRegistry>,
13928        environment: &Entity<ProjectEnvironment>,
13929        lsp_store: WeakEntity<LspStore>,
13930        worktree: &Entity<Worktree>,
13931        http_client: Arc<dyn HttpClient>,
13932        fs: Arc<dyn Fs>,
13933        cx: &mut App,
13934    ) -> Arc<Self> {
13935        let load_shell_env_task =
13936            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
13937
13938        Arc::new(Self {
13939            lsp_store,
13940            worktree: worktree.read(cx).snapshot(),
13941            fs,
13942            http_client,
13943            language_registry,
13944            load_shell_env_task,
13945        })
13946    }
13947
13948    fn from_local_lsp(
13949        local: &LocalLspStore,
13950        worktree: &Entity<Worktree>,
13951        cx: &mut App,
13952    ) -> Arc<Self> {
13953        Self::new(
13954            local.languages.clone(),
13955            &local.environment,
13956            local.weak.clone(),
13957            worktree,
13958            local.http_client.clone(),
13959            local.fs.clone(),
13960            cx,
13961        )
13962    }
13963}
13964
13965#[async_trait]
13966impl LspAdapterDelegate for LocalLspAdapterDelegate {
13967    fn show_notification(&self, message: &str, cx: &mut App) {
13968        self.lsp_store
13969            .update(cx, |_, cx| {
13970                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13971            })
13972            .ok();
13973    }
13974
13975    fn http_client(&self) -> Arc<dyn HttpClient> {
13976        self.http_client.clone()
13977    }
13978
13979    fn worktree_id(&self) -> WorktreeId {
13980        self.worktree.id()
13981    }
13982
13983    fn worktree_root_path(&self) -> &Path {
13984        self.worktree.abs_path().as_ref()
13985    }
13986
13987    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
13988        self.worktree.resolve_executable_path(path)
13989    }
13990
13991    async fn shell_env(&self) -> HashMap<String, String> {
13992        let task = self.load_shell_env_task.clone();
13993        task.await.unwrap_or_default()
13994    }
13995
13996    async fn npm_package_installed_version(
13997        &self,
13998        package_name: &str,
13999    ) -> Result<Option<(PathBuf, Version)>> {
14000        let local_package_directory = self.worktree_root_path();
14001        let node_modules_directory = local_package_directory.join("node_modules");
14002
14003        if let Some(version) =
14004            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14005        {
14006            return Ok(Some((node_modules_directory, version)));
14007        }
14008        let Some(npm) = self.which("npm".as_ref()).await else {
14009            log::warn!(
14010                "Failed to find npm executable for {:?}",
14011                local_package_directory
14012            );
14013            return Ok(None);
14014        };
14015
14016        let env = self.shell_env().await;
14017        let output = util::command::new_smol_command(&npm)
14018            .args(["root", "-g"])
14019            .envs(env)
14020            .current_dir(local_package_directory)
14021            .output()
14022            .await?;
14023        let global_node_modules =
14024            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14025
14026        if let Some(version) =
14027            read_package_installed_version(global_node_modules.clone(), package_name).await?
14028        {
14029            return Ok(Some((global_node_modules, version)));
14030        }
14031        return Ok(None);
14032    }
14033
14034    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14035        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14036        if self.fs.is_file(&worktree_abs_path).await {
14037            worktree_abs_path.pop();
14038        }
14039
14040        let env = self.shell_env().await;
14041
14042        let shell_path = env.get("PATH").cloned();
14043
14044        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14045    }
14046
14047    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14048        let mut working_dir = self.worktree_root_path().to_path_buf();
14049        if self.fs.is_file(&working_dir).await {
14050            working_dir.pop();
14051        }
14052        let output = util::command::new_smol_command(&command.path)
14053            .args(command.arguments)
14054            .envs(command.env.clone().unwrap_or_default())
14055            .current_dir(working_dir)
14056            .output()
14057            .await?;
14058
14059        anyhow::ensure!(
14060            output.status.success(),
14061            "{}, stdout: {:?}, stderr: {:?}",
14062            output.status,
14063            String::from_utf8_lossy(&output.stdout),
14064            String::from_utf8_lossy(&output.stderr)
14065        );
14066        Ok(())
14067    }
14068
14069    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14070        self.language_registry
14071            .update_lsp_binary_status(server_name, status);
14072    }
14073
14074    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14075        self.language_registry
14076            .all_lsp_adapters()
14077            .into_iter()
14078            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14079            .collect()
14080    }
14081
14082    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14083        let dir = self.language_registry.language_server_download_dir(name)?;
14084
14085        if !dir.exists() {
14086            smol::fs::create_dir_all(&dir)
14087                .await
14088                .context("failed to create container directory")
14089                .log_err()?;
14090        }
14091
14092        Some(dir)
14093    }
14094
14095    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14096        let entry = self
14097            .worktree
14098            .entry_for_path(path)
14099            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14100        let abs_path = self.worktree.absolutize(&entry.path);
14101        self.fs.load(&abs_path).await
14102    }
14103}
14104
14105async fn populate_labels_for_symbols(
14106    symbols: Vec<CoreSymbol>,
14107    language_registry: &Arc<LanguageRegistry>,
14108    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14109    output: &mut Vec<Symbol>,
14110) {
14111    #[allow(clippy::mutable_key_type)]
14112    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14113
14114    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14115    for symbol in symbols {
14116        let Some(file_name) = symbol.path.file_name() else {
14117            continue;
14118        };
14119        let language = language_registry
14120            .load_language_for_file_path(Path::new(file_name))
14121            .await
14122            .ok()
14123            .or_else(|| {
14124                unknown_paths.insert(file_name.into());
14125                None
14126            });
14127        symbols_by_language
14128            .entry(language)
14129            .or_default()
14130            .push(symbol);
14131    }
14132
14133    for unknown_path in unknown_paths {
14134        log::info!("no language found for symbol in file {unknown_path:?}");
14135    }
14136
14137    let mut label_params = Vec::new();
14138    for (language, mut symbols) in symbols_by_language {
14139        label_params.clear();
14140        label_params.extend(
14141            symbols
14142                .iter_mut()
14143                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14144        );
14145
14146        let mut labels = Vec::new();
14147        if let Some(language) = language {
14148            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14149                language_registry
14150                    .lsp_adapters(&language.name())
14151                    .first()
14152                    .cloned()
14153            });
14154            if let Some(lsp_adapter) = lsp_adapter {
14155                labels = lsp_adapter
14156                    .labels_for_symbols(&label_params, &language)
14157                    .await
14158                    .log_err()
14159                    .unwrap_or_default();
14160            }
14161        }
14162
14163        for ((symbol, (name, _)), label) in symbols
14164            .into_iter()
14165            .zip(label_params.drain(..))
14166            .zip(labels.into_iter().chain(iter::repeat(None)))
14167        {
14168            output.push(Symbol {
14169                language_server_name: symbol.language_server_name,
14170                source_worktree_id: symbol.source_worktree_id,
14171                source_language_server_id: symbol.source_language_server_id,
14172                path: symbol.path,
14173                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14174                name,
14175                kind: symbol.kind,
14176                range: symbol.range,
14177            });
14178        }
14179    }
14180}
14181
14182fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14183    match server.capabilities().text_document_sync.as_ref()? {
14184        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14185            // Server wants didSave but didn't specify includeText.
14186            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14187            // Server doesn't want didSave at all.
14188            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14189            // Server provided SaveOptions.
14190            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14191                Some(save_options.include_text.unwrap_or(false))
14192            }
14193        },
14194        // We do not have any save info. Kind affects didChange only.
14195        lsp::TextDocumentSyncCapability::Kind(_) => None,
14196    }
14197}
14198
14199/// Completion items are displayed in a `UniformList`.
14200/// Usually, those items are single-line strings, but in LSP responses,
14201/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14202/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14203/// 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,
14204/// breaking the completions menu presentation.
14205///
14206/// 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.
14207fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14208    let mut new_text = String::with_capacity(label.text.len());
14209    let mut offset_map = vec![0; label.text.len() + 1];
14210    let mut last_char_was_space = false;
14211    let mut new_idx = 0;
14212    let chars = label.text.char_indices().fuse();
14213    let mut newlines_removed = false;
14214
14215    for (idx, c) in chars {
14216        offset_map[idx] = new_idx;
14217
14218        match c {
14219            '\n' if last_char_was_space => {
14220                newlines_removed = true;
14221            }
14222            '\t' | ' ' if last_char_was_space => {}
14223            '\n' if !last_char_was_space => {
14224                new_text.push(' ');
14225                new_idx += 1;
14226                last_char_was_space = true;
14227                newlines_removed = true;
14228            }
14229            ' ' | '\t' => {
14230                new_text.push(' ');
14231                new_idx += 1;
14232                last_char_was_space = true;
14233            }
14234            _ => {
14235                new_text.push(c);
14236                new_idx += c.len_utf8();
14237                last_char_was_space = false;
14238            }
14239        }
14240    }
14241    offset_map[label.text.len()] = new_idx;
14242
14243    // Only modify the label if newlines were removed.
14244    if !newlines_removed {
14245        return;
14246    }
14247
14248    let last_index = new_idx;
14249    let mut run_ranges_errors = Vec::new();
14250    label.runs.retain_mut(|(range, _)| {
14251        match offset_map.get(range.start) {
14252            Some(&start) => range.start = start,
14253            None => {
14254                run_ranges_errors.push(range.clone());
14255                return false;
14256            }
14257        }
14258
14259        match offset_map.get(range.end) {
14260            Some(&end) => range.end = end,
14261            None => {
14262                run_ranges_errors.push(range.clone());
14263                range.end = last_index;
14264            }
14265        }
14266        true
14267    });
14268    if !run_ranges_errors.is_empty() {
14269        log::error!(
14270            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14271            label.text
14272        );
14273    }
14274
14275    let mut wrong_filter_range = None;
14276    if label.filter_range == (0..label.text.len()) {
14277        label.filter_range = 0..new_text.len();
14278    } else {
14279        let mut original_filter_range = Some(label.filter_range.clone());
14280        match offset_map.get(label.filter_range.start) {
14281            Some(&start) => label.filter_range.start = start,
14282            None => {
14283                wrong_filter_range = original_filter_range.take();
14284                label.filter_range.start = last_index;
14285            }
14286        }
14287
14288        match offset_map.get(label.filter_range.end) {
14289            Some(&end) => label.filter_range.end = end,
14290            None => {
14291                wrong_filter_range = original_filter_range.take();
14292                label.filter_range.end = last_index;
14293            }
14294        }
14295    }
14296    if let Some(wrong_filter_range) = wrong_filter_range {
14297        log::error!(
14298            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14299            label.text
14300        );
14301    }
14302
14303    label.text = new_text;
14304}
14305
14306#[cfg(test)]
14307mod tests {
14308    use language::HighlightId;
14309
14310    use super::*;
14311
14312    #[test]
14313    fn test_glob_literal_prefix() {
14314        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14315        assert_eq!(
14316            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14317            Path::new("node_modules")
14318        );
14319        assert_eq!(
14320            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14321            Path::new("foo")
14322        );
14323        assert_eq!(
14324            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14325            Path::new("foo/bar/baz.js")
14326        );
14327
14328        #[cfg(target_os = "windows")]
14329        {
14330            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14331            assert_eq!(
14332                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14333                Path::new("node_modules")
14334            );
14335            assert_eq!(
14336                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14337                Path::new("foo")
14338            );
14339            assert_eq!(
14340                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14341                Path::new("foo/bar/baz.js")
14342            );
14343        }
14344    }
14345
14346    #[test]
14347    fn test_multi_len_chars_normalization() {
14348        let mut label = CodeLabel::new(
14349            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14350            0..6,
14351            vec![(0..6, HighlightId(1))],
14352        );
14353        ensure_uniform_list_compatible_label(&mut label);
14354        assert_eq!(
14355            label,
14356            CodeLabel::new(
14357                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14358                0..6,
14359                vec![(0..6, HighlightId(1))],
14360            )
14361        );
14362    }
14363}