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, _| {
 3315            if let Some(transaction) = transaction {
 3316                this.as_local_mut()
 3317                    .unwrap()
 3318                    .last_workspace_edits_by_language_server
 3319                    .insert(server_id, transaction);
 3320            }
 3321        })?;
 3322        Ok(lsp::ApplyWorkspaceEditResponse {
 3323            applied: true,
 3324            failed_change: None,
 3325            failure_reason: None,
 3326        })
 3327    }
 3328
 3329    fn remove_worktree(
 3330        &mut self,
 3331        id_to_remove: WorktreeId,
 3332        cx: &mut Context<LspStore>,
 3333    ) -> Vec<LanguageServerId> {
 3334        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3335        self.diagnostics.remove(&id_to_remove);
 3336        self.prettier_store.update(cx, |prettier_store, cx| {
 3337            prettier_store.remove_worktree(id_to_remove, cx);
 3338        });
 3339
 3340        let mut servers_to_remove = BTreeSet::default();
 3341        let mut servers_to_preserve = HashSet::default();
 3342        for (seed, state) in &self.language_server_ids {
 3343            if seed.worktree_id == id_to_remove {
 3344                servers_to_remove.insert(state.id);
 3345            } else {
 3346                servers_to_preserve.insert(state.id);
 3347            }
 3348        }
 3349        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3350        self.language_server_ids
 3351            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3352        for server_id_to_remove in &servers_to_remove {
 3353            self.language_server_watched_paths
 3354                .remove(server_id_to_remove);
 3355            self.language_server_paths_watched_for_rename
 3356                .remove(server_id_to_remove);
 3357            self.last_workspace_edits_by_language_server
 3358                .remove(server_id_to_remove);
 3359            self.language_servers.remove(server_id_to_remove);
 3360            self.buffer_pull_diagnostics_result_ids
 3361                .remove(server_id_to_remove);
 3362            self.workspace_pull_diagnostics_result_ids
 3363                .remove(server_id_to_remove);
 3364            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3365                buffer_servers.remove(server_id_to_remove);
 3366            }
 3367            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3368        }
 3369        servers_to_remove.into_iter().collect()
 3370    }
 3371
 3372    fn rebuild_watched_paths_inner<'a>(
 3373        &'a self,
 3374        language_server_id: LanguageServerId,
 3375        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3376        cx: &mut Context<LspStore>,
 3377    ) -> LanguageServerWatchedPathsBuilder {
 3378        let worktrees = self
 3379            .worktree_store
 3380            .read(cx)
 3381            .worktrees()
 3382            .filter_map(|worktree| {
 3383                self.language_servers_for_worktree(worktree.read(cx).id())
 3384                    .find(|server| server.server_id() == language_server_id)
 3385                    .map(|_| worktree)
 3386            })
 3387            .collect::<Vec<_>>();
 3388
 3389        let mut worktree_globs = HashMap::default();
 3390        let mut abs_globs = HashMap::default();
 3391        log::trace!(
 3392            "Processing new watcher paths for language server with id {}",
 3393            language_server_id
 3394        );
 3395
 3396        for watcher in watchers {
 3397            if let Some((worktree, literal_prefix, pattern)) =
 3398                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3399            {
 3400                worktree.update(cx, |worktree, _| {
 3401                    if let Some((tree, glob)) =
 3402                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3403                    {
 3404                        tree.add_path_prefix_to_scan(literal_prefix);
 3405                        worktree_globs
 3406                            .entry(tree.id())
 3407                            .or_insert_with(GlobSetBuilder::new)
 3408                            .add(glob);
 3409                    }
 3410                });
 3411            } else {
 3412                let (path, pattern) = match &watcher.glob_pattern {
 3413                    lsp::GlobPattern::String(s) => {
 3414                        let watcher_path = SanitizedPath::new(s);
 3415                        let path = glob_literal_prefix(watcher_path.as_path());
 3416                        let pattern = watcher_path
 3417                            .as_path()
 3418                            .strip_prefix(&path)
 3419                            .map(|p| p.to_string_lossy().into_owned())
 3420                            .unwrap_or_else(|e| {
 3421                                debug_panic!(
 3422                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3423                                    s,
 3424                                    path.display(),
 3425                                    e
 3426                                );
 3427                                watcher_path.as_path().to_string_lossy().into_owned()
 3428                            });
 3429                        (path, pattern)
 3430                    }
 3431                    lsp::GlobPattern::Relative(rp) => {
 3432                        let Ok(mut base_uri) = match &rp.base_uri {
 3433                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3434                            lsp::OneOf::Right(base_uri) => base_uri,
 3435                        }
 3436                        .to_file_path() else {
 3437                            continue;
 3438                        };
 3439
 3440                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3441                        let pattern = Path::new(&rp.pattern)
 3442                            .strip_prefix(&path)
 3443                            .map(|p| p.to_string_lossy().into_owned())
 3444                            .unwrap_or_else(|e| {
 3445                                debug_panic!(
 3446                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3447                                    rp.pattern,
 3448                                    path.display(),
 3449                                    e
 3450                                );
 3451                                rp.pattern.clone()
 3452                            });
 3453                        base_uri.push(path);
 3454                        (base_uri, pattern)
 3455                    }
 3456                };
 3457
 3458                if let Some(glob) = Glob::new(&pattern).log_err() {
 3459                    if !path
 3460                        .components()
 3461                        .any(|c| matches!(c, path::Component::Normal(_)))
 3462                    {
 3463                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3464                        // rather than adding a new watcher for `/`.
 3465                        for worktree in &worktrees {
 3466                            worktree_globs
 3467                                .entry(worktree.read(cx).id())
 3468                                .or_insert_with(GlobSetBuilder::new)
 3469                                .add(glob.clone());
 3470                        }
 3471                    } else {
 3472                        abs_globs
 3473                            .entry(path.into())
 3474                            .or_insert_with(GlobSetBuilder::new)
 3475                            .add(glob);
 3476                    }
 3477                }
 3478            }
 3479        }
 3480
 3481        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3482        for (worktree_id, builder) in worktree_globs {
 3483            if let Ok(globset) = builder.build() {
 3484                watch_builder.watch_worktree(worktree_id, globset);
 3485            }
 3486        }
 3487        for (abs_path, builder) in abs_globs {
 3488            if let Ok(globset) = builder.build() {
 3489                watch_builder.watch_abs_path(abs_path, globset);
 3490            }
 3491        }
 3492        watch_builder
 3493    }
 3494
 3495    fn worktree_and_path_for_file_watcher(
 3496        worktrees: &[Entity<Worktree>],
 3497        watcher: &FileSystemWatcher,
 3498        cx: &App,
 3499    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3500        worktrees.iter().find_map(|worktree| {
 3501            let tree = worktree.read(cx);
 3502            let worktree_root_path = tree.abs_path();
 3503            let path_style = tree.path_style();
 3504            match &watcher.glob_pattern {
 3505                lsp::GlobPattern::String(s) => {
 3506                    let watcher_path = SanitizedPath::new(s);
 3507                    let relative = watcher_path
 3508                        .as_path()
 3509                        .strip_prefix(&worktree_root_path)
 3510                        .ok()?;
 3511                    let literal_prefix = glob_literal_prefix(relative);
 3512                    Some((
 3513                        worktree.clone(),
 3514                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3515                        relative.to_string_lossy().into_owned(),
 3516                    ))
 3517                }
 3518                lsp::GlobPattern::Relative(rp) => {
 3519                    let base_uri = match &rp.base_uri {
 3520                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3521                        lsp::OneOf::Right(base_uri) => base_uri,
 3522                    }
 3523                    .to_file_path()
 3524                    .ok()?;
 3525                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3526                    let mut literal_prefix = relative.to_owned();
 3527                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3528                    Some((
 3529                        worktree.clone(),
 3530                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3531                        rp.pattern.clone(),
 3532                    ))
 3533                }
 3534            }
 3535        })
 3536    }
 3537
 3538    fn rebuild_watched_paths(
 3539        &mut self,
 3540        language_server_id: LanguageServerId,
 3541        cx: &mut Context<LspStore>,
 3542    ) {
 3543        let Some(registrations) = self
 3544            .language_server_dynamic_registrations
 3545            .get(&language_server_id)
 3546        else {
 3547            return;
 3548        };
 3549
 3550        let watch_builder = self.rebuild_watched_paths_inner(
 3551            language_server_id,
 3552            registrations.did_change_watched_files.values().flatten(),
 3553            cx,
 3554        );
 3555        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3556        self.language_server_watched_paths
 3557            .insert(language_server_id, watcher);
 3558
 3559        cx.notify();
 3560    }
 3561
 3562    fn on_lsp_did_change_watched_files(
 3563        &mut self,
 3564        language_server_id: LanguageServerId,
 3565        registration_id: &str,
 3566        params: DidChangeWatchedFilesRegistrationOptions,
 3567        cx: &mut Context<LspStore>,
 3568    ) {
 3569        let registrations = self
 3570            .language_server_dynamic_registrations
 3571            .entry(language_server_id)
 3572            .or_default();
 3573
 3574        registrations
 3575            .did_change_watched_files
 3576            .insert(registration_id.to_string(), params.watchers);
 3577
 3578        self.rebuild_watched_paths(language_server_id, cx);
 3579    }
 3580
 3581    fn on_lsp_unregister_did_change_watched_files(
 3582        &mut self,
 3583        language_server_id: LanguageServerId,
 3584        registration_id: &str,
 3585        cx: &mut Context<LspStore>,
 3586    ) {
 3587        let registrations = self
 3588            .language_server_dynamic_registrations
 3589            .entry(language_server_id)
 3590            .or_default();
 3591
 3592        if registrations
 3593            .did_change_watched_files
 3594            .remove(registration_id)
 3595            .is_some()
 3596        {
 3597            log::info!(
 3598                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3599                language_server_id,
 3600                registration_id
 3601            );
 3602        } else {
 3603            log::warn!(
 3604                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3605                language_server_id,
 3606                registration_id
 3607            );
 3608        }
 3609
 3610        self.rebuild_watched_paths(language_server_id, cx);
 3611    }
 3612
 3613    async fn initialization_options_for_adapter(
 3614        adapter: Arc<dyn LspAdapter>,
 3615        delegate: &Arc<dyn LspAdapterDelegate>,
 3616    ) -> Result<Option<serde_json::Value>> {
 3617        let Some(mut initialization_config) =
 3618            adapter.clone().initialization_options(delegate).await?
 3619        else {
 3620            return Ok(None);
 3621        };
 3622
 3623        for other_adapter in delegate.registered_lsp_adapters() {
 3624            if other_adapter.name() == adapter.name() {
 3625                continue;
 3626            }
 3627            if let Ok(Some(target_config)) = other_adapter
 3628                .clone()
 3629                .additional_initialization_options(adapter.name(), delegate)
 3630                .await
 3631            {
 3632                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3633            }
 3634        }
 3635
 3636        Ok(Some(initialization_config))
 3637    }
 3638
 3639    async fn workspace_configuration_for_adapter(
 3640        adapter: Arc<dyn LspAdapter>,
 3641        delegate: &Arc<dyn LspAdapterDelegate>,
 3642        toolchain: Option<Toolchain>,
 3643        requested_uri: Option<Uri>,
 3644        cx: &mut AsyncApp,
 3645    ) -> Result<serde_json::Value> {
 3646        let mut workspace_config = adapter
 3647            .clone()
 3648            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3649            .await?;
 3650
 3651        for other_adapter in delegate.registered_lsp_adapters() {
 3652            if other_adapter.name() == adapter.name() {
 3653                continue;
 3654            }
 3655            if let Ok(Some(target_config)) = other_adapter
 3656                .clone()
 3657                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3658                .await
 3659            {
 3660                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3661            }
 3662        }
 3663
 3664        Ok(workspace_config)
 3665    }
 3666
 3667    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3668        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3669            Some(server.clone())
 3670        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3671            Some(Arc::clone(server))
 3672        } else {
 3673            None
 3674        }
 3675    }
 3676}
 3677
 3678fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3679    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3680        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3681            language_server_id: server.server_id(),
 3682            name: Some(server.name()),
 3683            message: proto::update_language_server::Variant::MetadataUpdated(
 3684                proto::ServerMetadataUpdated {
 3685                    capabilities: Some(capabilities),
 3686                    binary: Some(proto::LanguageServerBinaryInfo {
 3687                        path: server.binary().path.to_string_lossy().into_owned(),
 3688                        arguments: server
 3689                            .binary()
 3690                            .arguments
 3691                            .iter()
 3692                            .map(|arg| arg.to_string_lossy().into_owned())
 3693                            .collect(),
 3694                    }),
 3695                    configuration: serde_json::to_string(server.configuration()).ok(),
 3696                    workspace_folders: server
 3697                        .workspace_folders()
 3698                        .iter()
 3699                        .map(|uri| uri.to_string())
 3700                        .collect(),
 3701                },
 3702            ),
 3703        });
 3704    }
 3705}
 3706
 3707#[derive(Debug)]
 3708pub struct FormattableBuffer {
 3709    handle: Entity<Buffer>,
 3710    abs_path: Option<PathBuf>,
 3711    env: Option<HashMap<String, String>>,
 3712    ranges: Option<Vec<Range<Anchor>>>,
 3713}
 3714
 3715pub struct RemoteLspStore {
 3716    upstream_client: Option<AnyProtoClient>,
 3717    upstream_project_id: u64,
 3718}
 3719
 3720pub(crate) enum LspStoreMode {
 3721    Local(LocalLspStore),   // ssh host and collab host
 3722    Remote(RemoteLspStore), // collab guest
 3723}
 3724
 3725impl LspStoreMode {
 3726    fn is_local(&self) -> bool {
 3727        matches!(self, LspStoreMode::Local(_))
 3728    }
 3729}
 3730
 3731pub struct LspStore {
 3732    mode: LspStoreMode,
 3733    last_formatting_failure: Option<String>,
 3734    downstream_client: Option<(AnyProtoClient, u64)>,
 3735    nonce: u128,
 3736    buffer_store: Entity<BufferStore>,
 3737    worktree_store: Entity<WorktreeStore>,
 3738    pub languages: Arc<LanguageRegistry>,
 3739    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3740    active_entry: Option<ProjectEntryId>,
 3741    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3742    _maintain_buffer_languages: Task<()>,
 3743    diagnostic_summaries:
 3744        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3745    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3746    lsp_data: HashMap<BufferId, BufferLspData>,
 3747    next_hint_id: Arc<AtomicUsize>,
 3748}
 3749
 3750#[derive(Debug)]
 3751pub struct BufferLspData {
 3752    buffer_version: Global,
 3753    document_colors: Option<DocumentColorData>,
 3754    code_lens: Option<CodeLensData>,
 3755    inlay_hints: BufferInlayHints,
 3756    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3757    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3758}
 3759
 3760#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3761struct LspKey {
 3762    request_type: TypeId,
 3763    server_queried: Option<LanguageServerId>,
 3764}
 3765
 3766impl BufferLspData {
 3767    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3768        Self {
 3769            buffer_version: buffer.read(cx).version(),
 3770            document_colors: None,
 3771            code_lens: None,
 3772            inlay_hints: BufferInlayHints::new(buffer, cx),
 3773            lsp_requests: HashMap::default(),
 3774            chunk_lsp_requests: HashMap::default(),
 3775        }
 3776    }
 3777
 3778    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3779        if let Some(document_colors) = &mut self.document_colors {
 3780            document_colors.colors.remove(&for_server);
 3781            document_colors.cache_version += 1;
 3782        }
 3783
 3784        if let Some(code_lens) = &mut self.code_lens {
 3785            code_lens.lens.remove(&for_server);
 3786        }
 3787
 3788        self.inlay_hints.remove_server_data(for_server);
 3789    }
 3790
 3791    #[cfg(any(test, feature = "test-support"))]
 3792    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3793        &self.inlay_hints
 3794    }
 3795}
 3796
 3797#[derive(Debug, Default, Clone)]
 3798pub struct DocumentColors {
 3799    pub colors: HashSet<DocumentColor>,
 3800    pub cache_version: Option<usize>,
 3801}
 3802
 3803type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3804type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3805
 3806#[derive(Debug, Default)]
 3807struct DocumentColorData {
 3808    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3809    cache_version: usize,
 3810    colors_update: Option<(Global, DocumentColorTask)>,
 3811}
 3812
 3813#[derive(Debug, Default)]
 3814struct CodeLensData {
 3815    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3816    update: Option<(Global, CodeLensTask)>,
 3817}
 3818
 3819#[derive(Debug)]
 3820pub enum LspStoreEvent {
 3821    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3822    LanguageServerRemoved(LanguageServerId),
 3823    LanguageServerUpdate {
 3824        language_server_id: LanguageServerId,
 3825        name: Option<LanguageServerName>,
 3826        message: proto::update_language_server::Variant,
 3827    },
 3828    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3829    LanguageServerPrompt(LanguageServerPromptRequest),
 3830    LanguageDetected {
 3831        buffer: Entity<Buffer>,
 3832        new_language: Option<Arc<Language>>,
 3833    },
 3834    Notification(String),
 3835    RefreshInlayHints {
 3836        server_id: LanguageServerId,
 3837        request_id: Option<usize>,
 3838    },
 3839    RefreshCodeLens,
 3840    DiagnosticsUpdated {
 3841        server_id: LanguageServerId,
 3842        paths: Vec<ProjectPath>,
 3843    },
 3844    DiskBasedDiagnosticsStarted {
 3845        language_server_id: LanguageServerId,
 3846    },
 3847    DiskBasedDiagnosticsFinished {
 3848        language_server_id: LanguageServerId,
 3849    },
 3850    SnippetEdit {
 3851        buffer_id: BufferId,
 3852        edits: Vec<(lsp::Range, Snippet)>,
 3853        most_recent_edit: clock::Lamport,
 3854    },
 3855}
 3856
 3857#[derive(Clone, Debug, Serialize)]
 3858pub struct LanguageServerStatus {
 3859    pub name: LanguageServerName,
 3860    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3861    pub has_pending_diagnostic_updates: bool,
 3862    pub progress_tokens: HashSet<ProgressToken>,
 3863    pub worktree: Option<WorktreeId>,
 3864    pub binary: Option<LanguageServerBinary>,
 3865    pub configuration: Option<Value>,
 3866    pub workspace_folders: BTreeSet<Uri>,
 3867}
 3868
 3869#[derive(Clone, Debug)]
 3870struct CoreSymbol {
 3871    pub language_server_name: LanguageServerName,
 3872    pub source_worktree_id: WorktreeId,
 3873    pub source_language_server_id: LanguageServerId,
 3874    pub path: SymbolLocation,
 3875    pub name: String,
 3876    pub kind: lsp::SymbolKind,
 3877    pub range: Range<Unclipped<PointUtf16>>,
 3878}
 3879
 3880#[derive(Clone, Debug, PartialEq, Eq)]
 3881pub enum SymbolLocation {
 3882    InProject(ProjectPath),
 3883    OutsideProject {
 3884        abs_path: Arc<Path>,
 3885        signature: [u8; 32],
 3886    },
 3887}
 3888
 3889impl SymbolLocation {
 3890    fn file_name(&self) -> Option<&str> {
 3891        match self {
 3892            Self::InProject(path) => path.path.file_name(),
 3893            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3894        }
 3895    }
 3896}
 3897
 3898impl LspStore {
 3899    pub fn init(client: &AnyProtoClient) {
 3900        client.add_entity_request_handler(Self::handle_lsp_query);
 3901        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3902        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3903        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3904        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3905        client.add_entity_message_handler(Self::handle_start_language_server);
 3906        client.add_entity_message_handler(Self::handle_update_language_server);
 3907        client.add_entity_message_handler(Self::handle_language_server_log);
 3908        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3909        client.add_entity_request_handler(Self::handle_format_buffers);
 3910        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3911        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3912        client.add_entity_request_handler(Self::handle_apply_code_action);
 3913        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3914        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3915        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3916        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3917        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3918        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3919        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3920        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3921        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3922        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3923        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3924        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3925        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3926        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3927        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3928        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3929        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3930
 3931        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3932        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3933        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3934        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3935        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3936        client.add_entity_request_handler(
 3937            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3938        );
 3939        client.add_entity_request_handler(
 3940            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3941        );
 3942        client.add_entity_request_handler(
 3943            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3944        );
 3945    }
 3946
 3947    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3948        match &self.mode {
 3949            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3950            _ => None,
 3951        }
 3952    }
 3953
 3954    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3955        match &self.mode {
 3956            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3957            _ => None,
 3958        }
 3959    }
 3960
 3961    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3962        match &mut self.mode {
 3963            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3964            _ => None,
 3965        }
 3966    }
 3967
 3968    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3969        match &self.mode {
 3970            LspStoreMode::Remote(RemoteLspStore {
 3971                upstream_client: Some(upstream_client),
 3972                upstream_project_id,
 3973                ..
 3974            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3975
 3976            LspStoreMode::Remote(RemoteLspStore {
 3977                upstream_client: None,
 3978                ..
 3979            }) => None,
 3980            LspStoreMode::Local(_) => None,
 3981        }
 3982    }
 3983
 3984    pub fn new_local(
 3985        buffer_store: Entity<BufferStore>,
 3986        worktree_store: Entity<WorktreeStore>,
 3987        prettier_store: Entity<PrettierStore>,
 3988        toolchain_store: Entity<LocalToolchainStore>,
 3989        environment: Entity<ProjectEnvironment>,
 3990        manifest_tree: Entity<ManifestTree>,
 3991        languages: Arc<LanguageRegistry>,
 3992        http_client: Arc<dyn HttpClient>,
 3993        fs: Arc<dyn Fs>,
 3994        cx: &mut Context<Self>,
 3995    ) -> Self {
 3996        let yarn = YarnPathStore::new(fs.clone(), cx);
 3997        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3998            .detach();
 3999        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4000            .detach();
 4001        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4002            .detach();
 4003        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4004            .detach();
 4005        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4006            .detach();
 4007        subscribe_to_binary_statuses(&languages, cx).detach();
 4008
 4009        let _maintain_workspace_config = {
 4010            let (sender, receiver) = watch::channel();
 4011            (Self::maintain_workspace_config(receiver, cx), sender)
 4012        };
 4013
 4014        Self {
 4015            mode: LspStoreMode::Local(LocalLspStore {
 4016                weak: cx.weak_entity(),
 4017                worktree_store: worktree_store.clone(),
 4018
 4019                supplementary_language_servers: Default::default(),
 4020                languages: languages.clone(),
 4021                language_server_ids: Default::default(),
 4022                language_servers: Default::default(),
 4023                last_workspace_edits_by_language_server: Default::default(),
 4024                language_server_watched_paths: Default::default(),
 4025                language_server_paths_watched_for_rename: Default::default(),
 4026                language_server_dynamic_registrations: Default::default(),
 4027                buffers_being_formatted: Default::default(),
 4028                buffer_snapshots: Default::default(),
 4029                prettier_store,
 4030                environment,
 4031                http_client,
 4032                fs,
 4033                yarn,
 4034                next_diagnostic_group_id: Default::default(),
 4035                diagnostics: Default::default(),
 4036                _subscription: cx.on_app_quit(|this, cx| {
 4037                    this.as_local_mut()
 4038                        .unwrap()
 4039                        .shutdown_language_servers_on_quit(cx)
 4040                }),
 4041                lsp_tree: LanguageServerTree::new(
 4042                    manifest_tree,
 4043                    languages.clone(),
 4044                    toolchain_store.clone(),
 4045                ),
 4046                toolchain_store,
 4047                registered_buffers: HashMap::default(),
 4048                buffers_opened_in_servers: HashMap::default(),
 4049                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4050                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4051                restricted_worktrees_tasks: HashMap::default(),
 4052                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4053                    .manifest_file_names(),
 4054            }),
 4055            last_formatting_failure: None,
 4056            downstream_client: None,
 4057            buffer_store,
 4058            worktree_store,
 4059            languages: languages.clone(),
 4060            language_server_statuses: Default::default(),
 4061            nonce: StdRng::from_os_rng().random(),
 4062            diagnostic_summaries: HashMap::default(),
 4063            lsp_server_capabilities: HashMap::default(),
 4064            lsp_data: HashMap::default(),
 4065            next_hint_id: Arc::default(),
 4066            active_entry: None,
 4067            _maintain_workspace_config,
 4068            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4069        }
 4070    }
 4071
 4072    fn send_lsp_proto_request<R: LspCommand>(
 4073        &self,
 4074        buffer: Entity<Buffer>,
 4075        client: AnyProtoClient,
 4076        upstream_project_id: u64,
 4077        request: R,
 4078        cx: &mut Context<LspStore>,
 4079    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4080        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4081            return Task::ready(Ok(R::Response::default()));
 4082        }
 4083        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4084        cx.spawn(async move |this, cx| {
 4085            let response = client.request(message).await?;
 4086            let this = this.upgrade().context("project dropped")?;
 4087            request
 4088                .response_from_proto(response, this, buffer, cx.clone())
 4089                .await
 4090        })
 4091    }
 4092
 4093    pub(super) fn new_remote(
 4094        buffer_store: Entity<BufferStore>,
 4095        worktree_store: Entity<WorktreeStore>,
 4096        languages: Arc<LanguageRegistry>,
 4097        upstream_client: AnyProtoClient,
 4098        project_id: u64,
 4099        cx: &mut Context<Self>,
 4100    ) -> Self {
 4101        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4102            .detach();
 4103        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4104            .detach();
 4105        subscribe_to_binary_statuses(&languages, cx).detach();
 4106        let _maintain_workspace_config = {
 4107            let (sender, receiver) = watch::channel();
 4108            (Self::maintain_workspace_config(receiver, cx), sender)
 4109        };
 4110        Self {
 4111            mode: LspStoreMode::Remote(RemoteLspStore {
 4112                upstream_client: Some(upstream_client),
 4113                upstream_project_id: project_id,
 4114            }),
 4115            downstream_client: None,
 4116            last_formatting_failure: None,
 4117            buffer_store,
 4118            worktree_store,
 4119            languages: languages.clone(),
 4120            language_server_statuses: Default::default(),
 4121            nonce: StdRng::from_os_rng().random(),
 4122            diagnostic_summaries: HashMap::default(),
 4123            lsp_server_capabilities: HashMap::default(),
 4124            next_hint_id: Arc::default(),
 4125            lsp_data: HashMap::default(),
 4126            active_entry: None,
 4127
 4128            _maintain_workspace_config,
 4129            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4130        }
 4131    }
 4132
 4133    fn on_buffer_store_event(
 4134        &mut self,
 4135        _: Entity<BufferStore>,
 4136        event: &BufferStoreEvent,
 4137        cx: &mut Context<Self>,
 4138    ) {
 4139        match event {
 4140            BufferStoreEvent::BufferAdded(buffer) => {
 4141                self.on_buffer_added(buffer, cx).log_err();
 4142            }
 4143            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4144                let buffer_id = buffer.read(cx).remote_id();
 4145                if let Some(local) = self.as_local_mut()
 4146                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4147                {
 4148                    local.reset_buffer(buffer, old_file, cx);
 4149
 4150                    if local.registered_buffers.contains_key(&buffer_id) {
 4151                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4152                    }
 4153                }
 4154
 4155                self.detect_language_for_buffer(buffer, cx);
 4156                if let Some(local) = self.as_local_mut() {
 4157                    local.initialize_buffer(buffer, cx);
 4158                    if local.registered_buffers.contains_key(&buffer_id) {
 4159                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4160                    }
 4161                }
 4162            }
 4163            _ => {}
 4164        }
 4165    }
 4166
 4167    fn on_worktree_store_event(
 4168        &mut self,
 4169        _: Entity<WorktreeStore>,
 4170        event: &WorktreeStoreEvent,
 4171        cx: &mut Context<Self>,
 4172    ) {
 4173        match event {
 4174            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4175                if !worktree.read(cx).is_local() {
 4176                    return;
 4177                }
 4178                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4179                    worktree::Event::UpdatedEntries(changes) => {
 4180                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4181                    }
 4182                    worktree::Event::UpdatedGitRepositories(_)
 4183                    | worktree::Event::DeletedEntry(_) => {}
 4184                })
 4185                .detach()
 4186            }
 4187            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4188            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4189                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4190            }
 4191            WorktreeStoreEvent::WorktreeReleased(..)
 4192            | WorktreeStoreEvent::WorktreeOrderChanged
 4193            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4194            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4195            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4196        }
 4197    }
 4198
 4199    fn on_prettier_store_event(
 4200        &mut self,
 4201        _: Entity<PrettierStore>,
 4202        event: &PrettierStoreEvent,
 4203        cx: &mut Context<Self>,
 4204    ) {
 4205        match event {
 4206            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4207                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4208            }
 4209            PrettierStoreEvent::LanguageServerAdded {
 4210                new_server_id,
 4211                name,
 4212                prettier_server,
 4213            } => {
 4214                self.register_supplementary_language_server(
 4215                    *new_server_id,
 4216                    name.clone(),
 4217                    prettier_server.clone(),
 4218                    cx,
 4219                );
 4220            }
 4221        }
 4222    }
 4223
 4224    fn on_toolchain_store_event(
 4225        &mut self,
 4226        _: Entity<LocalToolchainStore>,
 4227        event: &ToolchainStoreEvent,
 4228        _: &mut Context<Self>,
 4229    ) {
 4230        if let ToolchainStoreEvent::ToolchainActivated = event {
 4231            self.request_workspace_config_refresh()
 4232        }
 4233    }
 4234
 4235    fn request_workspace_config_refresh(&mut self) {
 4236        *self._maintain_workspace_config.1.borrow_mut() = ();
 4237    }
 4238
 4239    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4240        self.as_local().map(|local| local.prettier_store.clone())
 4241    }
 4242
 4243    fn on_buffer_event(
 4244        &mut self,
 4245        buffer: Entity<Buffer>,
 4246        event: &language::BufferEvent,
 4247        cx: &mut Context<Self>,
 4248    ) {
 4249        match event {
 4250            language::BufferEvent::Edited => {
 4251                self.on_buffer_edited(buffer, cx);
 4252            }
 4253
 4254            language::BufferEvent::Saved => {
 4255                self.on_buffer_saved(buffer, cx);
 4256            }
 4257
 4258            _ => {}
 4259        }
 4260    }
 4261
 4262    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4263        buffer
 4264            .read(cx)
 4265            .set_language_registry(self.languages.clone());
 4266
 4267        cx.subscribe(buffer, |this, buffer, event, cx| {
 4268            this.on_buffer_event(buffer, event, cx);
 4269        })
 4270        .detach();
 4271
 4272        self.detect_language_for_buffer(buffer, cx);
 4273        if let Some(local) = self.as_local_mut() {
 4274            local.initialize_buffer(buffer, cx);
 4275        }
 4276
 4277        Ok(())
 4278    }
 4279
 4280    pub(crate) fn register_buffer_with_language_servers(
 4281        &mut self,
 4282        buffer: &Entity<Buffer>,
 4283        only_register_servers: HashSet<LanguageServerSelector>,
 4284        ignore_refcounts: bool,
 4285        cx: &mut Context<Self>,
 4286    ) -> OpenLspBufferHandle {
 4287        let buffer_id = buffer.read(cx).remote_id();
 4288        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4289        if let Some(local) = self.as_local_mut() {
 4290            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4291            if !ignore_refcounts {
 4292                *refcount += 1;
 4293            }
 4294
 4295            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4296            // 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
 4297            // 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
 4298            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4299            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4300                return handle;
 4301            };
 4302            if !file.is_local() {
 4303                return handle;
 4304            }
 4305
 4306            if ignore_refcounts || *refcount == 1 {
 4307                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4308            }
 4309            if !ignore_refcounts {
 4310                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4311                    let refcount = {
 4312                        let local = lsp_store.as_local_mut().unwrap();
 4313                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4314                            debug_panic!("bad refcounting");
 4315                            return;
 4316                        };
 4317
 4318                        *refcount -= 1;
 4319                        *refcount
 4320                    };
 4321                    if refcount == 0 {
 4322                        lsp_store.lsp_data.remove(&buffer_id);
 4323                        let local = lsp_store.as_local_mut().unwrap();
 4324                        local.registered_buffers.remove(&buffer_id);
 4325
 4326                        local.buffers_opened_in_servers.remove(&buffer_id);
 4327                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4328                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4329
 4330                            let buffer_abs_path = file.abs_path(cx);
 4331                            for (_, buffer_pull_diagnostics_result_ids) in
 4332                                &mut local.buffer_pull_diagnostics_result_ids
 4333                            {
 4334                                buffer_pull_diagnostics_result_ids.retain(
 4335                                    |_, buffer_result_ids| {
 4336                                        buffer_result_ids.remove(&buffer_abs_path);
 4337                                        !buffer_result_ids.is_empty()
 4338                                    },
 4339                                );
 4340                            }
 4341
 4342                            let diagnostic_updates = local
 4343                                .language_servers
 4344                                .keys()
 4345                                .cloned()
 4346                                .map(|server_id| DocumentDiagnosticsUpdate {
 4347                                    diagnostics: DocumentDiagnostics {
 4348                                        document_abs_path: buffer_abs_path.clone(),
 4349                                        version: None,
 4350                                        diagnostics: Vec::new(),
 4351                                    },
 4352                                    result_id: None,
 4353                                    registration_id: None,
 4354                                    server_id: server_id,
 4355                                    disk_based_sources: Cow::Borrowed(&[]),
 4356                                })
 4357                                .collect::<Vec<_>>();
 4358
 4359                            lsp_store
 4360                                .merge_diagnostic_entries(
 4361                                    diagnostic_updates,
 4362                                    |_, diagnostic, _| {
 4363                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4364                                    },
 4365                                    cx,
 4366                                )
 4367                                .context("Clearing diagnostics for the closed buffer")
 4368                                .log_err();
 4369                        }
 4370                    }
 4371                })
 4372                .detach();
 4373            }
 4374        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4375            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4376            cx.background_spawn(async move {
 4377                upstream_client
 4378                    .request(proto::RegisterBufferWithLanguageServers {
 4379                        project_id: upstream_project_id,
 4380                        buffer_id,
 4381                        only_servers: only_register_servers
 4382                            .into_iter()
 4383                            .map(|selector| {
 4384                                let selector = match selector {
 4385                                    LanguageServerSelector::Id(language_server_id) => {
 4386                                        proto::language_server_selector::Selector::ServerId(
 4387                                            language_server_id.to_proto(),
 4388                                        )
 4389                                    }
 4390                                    LanguageServerSelector::Name(language_server_name) => {
 4391                                        proto::language_server_selector::Selector::Name(
 4392                                            language_server_name.to_string(),
 4393                                        )
 4394                                    }
 4395                                };
 4396                                proto::LanguageServerSelector {
 4397                                    selector: Some(selector),
 4398                                }
 4399                            })
 4400                            .collect(),
 4401                    })
 4402                    .await
 4403            })
 4404            .detach();
 4405        } else {
 4406            // Our remote connection got closed
 4407        }
 4408        handle
 4409    }
 4410
 4411    fn maintain_buffer_languages(
 4412        languages: Arc<LanguageRegistry>,
 4413        cx: &mut Context<Self>,
 4414    ) -> Task<()> {
 4415        let mut subscription = languages.subscribe();
 4416        let mut prev_reload_count = languages.reload_count();
 4417        cx.spawn(async move |this, cx| {
 4418            while let Some(()) = subscription.next().await {
 4419                if let Some(this) = this.upgrade() {
 4420                    // If the language registry has been reloaded, then remove and
 4421                    // re-assign the languages on all open buffers.
 4422                    let reload_count = languages.reload_count();
 4423                    if reload_count > prev_reload_count {
 4424                        prev_reload_count = reload_count;
 4425                        this.update(cx, |this, cx| {
 4426                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4427                                for buffer in buffer_store.buffers() {
 4428                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4429                                    {
 4430                                        buffer.update(cx, |buffer, cx| {
 4431                                            buffer.set_language_async(None, cx)
 4432                                        });
 4433                                        if let Some(local) = this.as_local_mut() {
 4434                                            local.reset_buffer(&buffer, &f, cx);
 4435
 4436                                            if local
 4437                                                .registered_buffers
 4438                                                .contains_key(&buffer.read(cx).remote_id())
 4439                                                && let Some(file_url) =
 4440                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4441                                            {
 4442                                                local.unregister_buffer_from_language_servers(
 4443                                                    &buffer, &file_url, cx,
 4444                                                );
 4445                                            }
 4446                                        }
 4447                                    }
 4448                                }
 4449                            });
 4450                        })
 4451                        .ok();
 4452                    }
 4453
 4454                    this.update(cx, |this, cx| {
 4455                        let mut plain_text_buffers = Vec::new();
 4456                        let mut buffers_with_unknown_injections = Vec::new();
 4457                        for handle in this.buffer_store.read(cx).buffers() {
 4458                            let buffer = handle.read(cx);
 4459                            if buffer.language().is_none()
 4460                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4461                            {
 4462                                plain_text_buffers.push(handle);
 4463                            } else if buffer.contains_unknown_injections() {
 4464                                buffers_with_unknown_injections.push(handle);
 4465                            }
 4466                        }
 4467
 4468                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4469                        // and reused later in the invisible worktrees.
 4470                        plain_text_buffers.sort_by_key(|buffer| {
 4471                            Reverse(
 4472                                File::from_dyn(buffer.read(cx).file())
 4473                                    .map(|file| file.worktree.read(cx).is_visible()),
 4474                            )
 4475                        });
 4476
 4477                        for buffer in plain_text_buffers {
 4478                            this.detect_language_for_buffer(&buffer, cx);
 4479                            if let Some(local) = this.as_local_mut() {
 4480                                local.initialize_buffer(&buffer, cx);
 4481                                if local
 4482                                    .registered_buffers
 4483                                    .contains_key(&buffer.read(cx).remote_id())
 4484                                {
 4485                                    local.register_buffer_with_language_servers(
 4486                                        &buffer,
 4487                                        HashSet::default(),
 4488                                        cx,
 4489                                    );
 4490                                }
 4491                            }
 4492                        }
 4493
 4494                        for buffer in buffers_with_unknown_injections {
 4495                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4496                        }
 4497                    })
 4498                    .ok();
 4499                }
 4500            }
 4501        })
 4502    }
 4503
 4504    fn detect_language_for_buffer(
 4505        &mut self,
 4506        buffer_handle: &Entity<Buffer>,
 4507        cx: &mut Context<Self>,
 4508    ) -> Option<language::AvailableLanguage> {
 4509        // If the buffer has a language, set it and start the language server if we haven't already.
 4510        let buffer = buffer_handle.read(cx);
 4511        let file = buffer.file()?;
 4512
 4513        let content = buffer.as_rope();
 4514        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4515        if let Some(available_language) = &available_language {
 4516            if let Some(Ok(Ok(new_language))) = self
 4517                .languages
 4518                .load_language(available_language)
 4519                .now_or_never()
 4520            {
 4521                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4522            }
 4523        } else {
 4524            cx.emit(LspStoreEvent::LanguageDetected {
 4525                buffer: buffer_handle.clone(),
 4526                new_language: None,
 4527            });
 4528        }
 4529
 4530        available_language
 4531    }
 4532
 4533    pub(crate) fn set_language_for_buffer(
 4534        &mut self,
 4535        buffer_entity: &Entity<Buffer>,
 4536        new_language: Arc<Language>,
 4537        cx: &mut Context<Self>,
 4538    ) {
 4539        let buffer = buffer_entity.read(cx);
 4540        let buffer_file = buffer.file().cloned();
 4541        let buffer_id = buffer.remote_id();
 4542        if let Some(local_store) = self.as_local_mut()
 4543            && local_store.registered_buffers.contains_key(&buffer_id)
 4544            && let Some(abs_path) =
 4545                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4546            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4547        {
 4548            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4549        }
 4550        buffer_entity.update(cx, |buffer, cx| {
 4551            if buffer
 4552                .language()
 4553                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4554            {
 4555                buffer.set_language_async(Some(new_language.clone()), cx);
 4556            }
 4557        });
 4558
 4559        let settings =
 4560            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4561        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4562
 4563        let worktree_id = if let Some(file) = buffer_file {
 4564            let worktree = file.worktree.clone();
 4565
 4566            if let Some(local) = self.as_local_mut()
 4567                && local.registered_buffers.contains_key(&buffer_id)
 4568            {
 4569                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4570            }
 4571            Some(worktree.read(cx).id())
 4572        } else {
 4573            None
 4574        };
 4575
 4576        if settings.prettier.allowed
 4577            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4578        {
 4579            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4580            if let Some(prettier_store) = prettier_store {
 4581                prettier_store.update(cx, |prettier_store, cx| {
 4582                    prettier_store.install_default_prettier(
 4583                        worktree_id,
 4584                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4585                        cx,
 4586                    )
 4587                })
 4588            }
 4589        }
 4590
 4591        cx.emit(LspStoreEvent::LanguageDetected {
 4592            buffer: buffer_entity.clone(),
 4593            new_language: Some(new_language),
 4594        })
 4595    }
 4596
 4597    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4598        self.buffer_store.clone()
 4599    }
 4600
 4601    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4602        self.active_entry = active_entry;
 4603    }
 4604
 4605    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4606        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4607            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4608        {
 4609            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4610                summaries
 4611                    .iter()
 4612                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4613            });
 4614            if let Some(summary) = summaries.next() {
 4615                client
 4616                    .send(proto::UpdateDiagnosticSummary {
 4617                        project_id: downstream_project_id,
 4618                        worktree_id: worktree.id().to_proto(),
 4619                        summary: Some(summary),
 4620                        more_summaries: summaries.collect(),
 4621                    })
 4622                    .log_err();
 4623            }
 4624        }
 4625    }
 4626
 4627    fn is_capable_for_proto_request<R>(
 4628        &self,
 4629        buffer: &Entity<Buffer>,
 4630        request: &R,
 4631        cx: &App,
 4632    ) -> bool
 4633    where
 4634        R: LspCommand,
 4635    {
 4636        self.check_if_capable_for_proto_request(
 4637            buffer,
 4638            |capabilities| {
 4639                request.check_capabilities(AdapterServerCapabilities {
 4640                    server_capabilities: capabilities.clone(),
 4641                    code_action_kinds: None,
 4642                })
 4643            },
 4644            cx,
 4645        )
 4646    }
 4647
 4648    fn check_if_capable_for_proto_request<F>(
 4649        &self,
 4650        buffer: &Entity<Buffer>,
 4651        check: F,
 4652        cx: &App,
 4653    ) -> bool
 4654    where
 4655        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4656    {
 4657        let Some(language) = buffer.read(cx).language().cloned() else {
 4658            return false;
 4659        };
 4660        let relevant_language_servers = self
 4661            .languages
 4662            .lsp_adapters(&language.name())
 4663            .into_iter()
 4664            .map(|lsp_adapter| lsp_adapter.name())
 4665            .collect::<HashSet<_>>();
 4666        self.language_server_statuses
 4667            .iter()
 4668            .filter_map(|(server_id, server_status)| {
 4669                relevant_language_servers
 4670                    .contains(&server_status.name)
 4671                    .then_some(server_id)
 4672            })
 4673            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4674            .any(check)
 4675    }
 4676
 4677    fn all_capable_for_proto_request<F>(
 4678        &self,
 4679        buffer: &Entity<Buffer>,
 4680        mut check: F,
 4681        cx: &App,
 4682    ) -> Vec<lsp::LanguageServerId>
 4683    where
 4684        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4685    {
 4686        let Some(language) = buffer.read(cx).language().cloned() else {
 4687            return Vec::default();
 4688        };
 4689        let relevant_language_servers = self
 4690            .languages
 4691            .lsp_adapters(&language.name())
 4692            .into_iter()
 4693            .map(|lsp_adapter| lsp_adapter.name())
 4694            .collect::<HashSet<_>>();
 4695        self.language_server_statuses
 4696            .iter()
 4697            .filter_map(|(server_id, server_status)| {
 4698                relevant_language_servers
 4699                    .contains(&server_status.name)
 4700                    .then_some((server_id, &server_status.name))
 4701            })
 4702            .filter_map(|(server_id, server_name)| {
 4703                self.lsp_server_capabilities
 4704                    .get(server_id)
 4705                    .map(|c| (server_id, server_name, c))
 4706            })
 4707            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4708            .map(|(server_id, _, _)| *server_id)
 4709            .collect()
 4710    }
 4711
 4712    pub fn request_lsp<R>(
 4713        &mut self,
 4714        buffer: Entity<Buffer>,
 4715        server: LanguageServerToQuery,
 4716        request: R,
 4717        cx: &mut Context<Self>,
 4718    ) -> Task<Result<R::Response>>
 4719    where
 4720        R: LspCommand,
 4721        <R::LspRequest as lsp::request::Request>::Result: Send,
 4722        <R::LspRequest as lsp::request::Request>::Params: Send,
 4723    {
 4724        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4725            return self.send_lsp_proto_request(
 4726                buffer,
 4727                upstream_client,
 4728                upstream_project_id,
 4729                request,
 4730                cx,
 4731            );
 4732        }
 4733
 4734        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4735            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4736                local
 4737                    .language_servers_for_buffer(buffer, cx)
 4738                    .find(|(_, server)| {
 4739                        request.check_capabilities(server.adapter_server_capabilities())
 4740                    })
 4741                    .map(|(_, server)| server.clone())
 4742            }),
 4743            LanguageServerToQuery::Other(id) => self
 4744                .language_server_for_local_buffer(buffer, id, cx)
 4745                .and_then(|(_, server)| {
 4746                    request
 4747                        .check_capabilities(server.adapter_server_capabilities())
 4748                        .then(|| Arc::clone(server))
 4749                }),
 4750        }) else {
 4751            return Task::ready(Ok(Default::default()));
 4752        };
 4753
 4754        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4755
 4756        let Some(file) = file else {
 4757            return Task::ready(Ok(Default::default()));
 4758        };
 4759
 4760        let lsp_params = match request.to_lsp_params_or_response(
 4761            &file.abs_path(cx),
 4762            buffer.read(cx),
 4763            &language_server,
 4764            cx,
 4765        ) {
 4766            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4767            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4768            Err(err) => {
 4769                let message = format!(
 4770                    "{} via {} failed: {}",
 4771                    request.display_name(),
 4772                    language_server.name(),
 4773                    err
 4774                );
 4775                // rust-analyzer likes to error with this when its still loading up
 4776                if !message.ends_with("content modified") {
 4777                    log::warn!("{message}");
 4778                }
 4779                return Task::ready(Err(anyhow!(message)));
 4780            }
 4781        };
 4782
 4783        let status = request.status();
 4784        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4785            return Task::ready(Ok(Default::default()));
 4786        }
 4787        cx.spawn(async move |this, cx| {
 4788            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4789
 4790            let id = lsp_request.id();
 4791            let _cleanup = if status.is_some() {
 4792                cx.update(|cx| {
 4793                    this.update(cx, |this, cx| {
 4794                        this.on_lsp_work_start(
 4795                            language_server.server_id(),
 4796                            ProgressToken::Number(id),
 4797                            LanguageServerProgress {
 4798                                is_disk_based_diagnostics_progress: false,
 4799                                is_cancellable: false,
 4800                                title: None,
 4801                                message: status.clone(),
 4802                                percentage: None,
 4803                                last_update_at: cx.background_executor().now(),
 4804                            },
 4805                            cx,
 4806                        );
 4807                    })
 4808                })
 4809                .log_err();
 4810
 4811                Some(defer(|| {
 4812                    cx.update(|cx| {
 4813                        this.update(cx, |this, cx| {
 4814                            this.on_lsp_work_end(
 4815                                language_server.server_id(),
 4816                                ProgressToken::Number(id),
 4817                                cx,
 4818                            );
 4819                        })
 4820                    })
 4821                    .log_err();
 4822                }))
 4823            } else {
 4824                None
 4825            };
 4826
 4827            let result = lsp_request.await.into_response();
 4828
 4829            let response = result.map_err(|err| {
 4830                let message = format!(
 4831                    "{} via {} failed: {}",
 4832                    request.display_name(),
 4833                    language_server.name(),
 4834                    err
 4835                );
 4836                // rust-analyzer likes to error with this when its still loading up
 4837                if !message.ends_with("content modified") {
 4838                    log::warn!("{message}");
 4839                }
 4840                anyhow::anyhow!(message)
 4841            })?;
 4842
 4843            request
 4844                .response_from_lsp(
 4845                    response,
 4846                    this.upgrade().context("no app context")?,
 4847                    buffer,
 4848                    language_server.server_id(),
 4849                    cx.clone(),
 4850                )
 4851                .await
 4852        })
 4853    }
 4854
 4855    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4856        let mut language_formatters_to_check = Vec::new();
 4857        for buffer in self.buffer_store.read(cx).buffers() {
 4858            let buffer = buffer.read(cx);
 4859            let buffer_file = File::from_dyn(buffer.file());
 4860            let buffer_language = buffer.language();
 4861            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4862            if buffer_language.is_some() {
 4863                language_formatters_to_check.push((
 4864                    buffer_file.map(|f| f.worktree_id(cx)),
 4865                    settings.into_owned(),
 4866                ));
 4867            }
 4868        }
 4869
 4870        self.request_workspace_config_refresh();
 4871
 4872        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4873            prettier_store.update(cx, |prettier_store, cx| {
 4874                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4875            })
 4876        }
 4877
 4878        cx.notify();
 4879    }
 4880
 4881    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4882        let buffer_store = self.buffer_store.clone();
 4883        let Some(local) = self.as_local_mut() else {
 4884            return;
 4885        };
 4886        let mut adapters = BTreeMap::default();
 4887        let get_adapter = {
 4888            let languages = local.languages.clone();
 4889            let environment = local.environment.clone();
 4890            let weak = local.weak.clone();
 4891            let worktree_store = local.worktree_store.clone();
 4892            let http_client = local.http_client.clone();
 4893            let fs = local.fs.clone();
 4894            move |worktree_id, cx: &mut App| {
 4895                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4896                Some(LocalLspAdapterDelegate::new(
 4897                    languages.clone(),
 4898                    &environment,
 4899                    weak.clone(),
 4900                    &worktree,
 4901                    http_client.clone(),
 4902                    fs.clone(),
 4903                    cx,
 4904                ))
 4905            }
 4906        };
 4907
 4908        let mut messages_to_report = Vec::new();
 4909        let (new_tree, to_stop) = {
 4910            let mut rebase = local.lsp_tree.rebase();
 4911            let buffers = buffer_store
 4912                .read(cx)
 4913                .buffers()
 4914                .filter_map(|buffer| {
 4915                    let raw_buffer = buffer.read(cx);
 4916                    if !local
 4917                        .registered_buffers
 4918                        .contains_key(&raw_buffer.remote_id())
 4919                    {
 4920                        return None;
 4921                    }
 4922                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4923                    let language = raw_buffer.language().cloned()?;
 4924                    Some((file, language, raw_buffer.remote_id()))
 4925                })
 4926                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4927            for (file, language, buffer_id) in buffers {
 4928                let worktree_id = file.worktree_id(cx);
 4929                let Some(worktree) = local
 4930                    .worktree_store
 4931                    .read(cx)
 4932                    .worktree_for_id(worktree_id, cx)
 4933                else {
 4934                    continue;
 4935                };
 4936
 4937                if let Some((_, apply)) = local.reuse_existing_language_server(
 4938                    rebase.server_tree(),
 4939                    &worktree,
 4940                    &language.name(),
 4941                    cx,
 4942                ) {
 4943                    (apply)(rebase.server_tree());
 4944                } else if let Some(lsp_delegate) = adapters
 4945                    .entry(worktree_id)
 4946                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4947                    .clone()
 4948                {
 4949                    let delegate =
 4950                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4951                    let path = file
 4952                        .path()
 4953                        .parent()
 4954                        .map(Arc::from)
 4955                        .unwrap_or_else(|| file.path().clone());
 4956                    let worktree_path = ProjectPath { worktree_id, path };
 4957                    let abs_path = file.abs_path(cx);
 4958                    let nodes = rebase
 4959                        .walk(
 4960                            worktree_path,
 4961                            language.name(),
 4962                            language.manifest(),
 4963                            delegate.clone(),
 4964                            cx,
 4965                        )
 4966                        .collect::<Vec<_>>();
 4967                    for node in nodes {
 4968                        let server_id = node.server_id_or_init(|disposition| {
 4969                            let path = &disposition.path;
 4970                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4971                            let key = LanguageServerSeed {
 4972                                worktree_id,
 4973                                name: disposition.server_name.clone(),
 4974                                settings: disposition.settings.clone(),
 4975                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4976                                    path.worktree_id,
 4977                                    &path.path,
 4978                                    language.name(),
 4979                                ),
 4980                            };
 4981                            local.language_server_ids.remove(&key);
 4982
 4983                            let server_id = local.get_or_insert_language_server(
 4984                                &worktree,
 4985                                lsp_delegate.clone(),
 4986                                disposition,
 4987                                &language.name(),
 4988                                cx,
 4989                            );
 4990                            if let Some(state) = local.language_servers.get(&server_id)
 4991                                && let Ok(uri) = uri
 4992                            {
 4993                                state.add_workspace_folder(uri);
 4994                            };
 4995                            server_id
 4996                        });
 4997
 4998                        if let Some(language_server_id) = server_id {
 4999                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5000                                language_server_id,
 5001                                name: node.name(),
 5002                                message:
 5003                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5004                                        proto::RegisteredForBuffer {
 5005                                            buffer_abs_path: abs_path
 5006                                                .to_string_lossy()
 5007                                                .into_owned(),
 5008                                            buffer_id: buffer_id.to_proto(),
 5009                                        },
 5010                                    ),
 5011                            });
 5012                        }
 5013                    }
 5014                } else {
 5015                    continue;
 5016                }
 5017            }
 5018            rebase.finish()
 5019        };
 5020        for message in messages_to_report {
 5021            cx.emit(message);
 5022        }
 5023        local.lsp_tree = new_tree;
 5024        for (id, _) in to_stop {
 5025            self.stop_local_language_server(id, cx).detach();
 5026        }
 5027    }
 5028
 5029    pub fn apply_code_action(
 5030        &self,
 5031        buffer_handle: Entity<Buffer>,
 5032        mut action: CodeAction,
 5033        push_to_history: bool,
 5034        cx: &mut Context<Self>,
 5035    ) -> Task<Result<ProjectTransaction>> {
 5036        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5037            let request = proto::ApplyCodeAction {
 5038                project_id,
 5039                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5040                action: Some(Self::serialize_code_action(&action)),
 5041            };
 5042            let buffer_store = self.buffer_store();
 5043            cx.spawn(async move |_, cx| {
 5044                let response = upstream_client
 5045                    .request(request)
 5046                    .await?
 5047                    .transaction
 5048                    .context("missing transaction")?;
 5049
 5050                buffer_store
 5051                    .update(cx, |buffer_store, cx| {
 5052                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5053                    })?
 5054                    .await
 5055            })
 5056        } else if self.mode.is_local() {
 5057            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 5058                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5059                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 5060            }) else {
 5061                return Task::ready(Ok(ProjectTransaction::default()));
 5062            };
 5063            cx.spawn(async move |this,  cx| {
 5064                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 5065                    .await
 5066                    .context("resolving a code action")?;
 5067                if let Some(edit) = action.lsp_action.edit()
 5068                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5069                        return LocalLspStore::deserialize_workspace_edit(
 5070                            this.upgrade().context("no app present")?,
 5071                            edit.clone(),
 5072                            push_to_history,
 5073
 5074                            lang_server.clone(),
 5075                            cx,
 5076                        )
 5077                        .await;
 5078                    }
 5079
 5080                if let Some(command) = action.lsp_action.command() {
 5081                    let server_capabilities = lang_server.capabilities();
 5082                    let available_commands = server_capabilities
 5083                        .execute_command_provider
 5084                        .as_ref()
 5085                        .map(|options| options.commands.as_slice())
 5086                        .unwrap_or_default();
 5087                    if available_commands.contains(&command.command) {
 5088                        this.update(cx, |this, _| {
 5089                            this.as_local_mut()
 5090                                .unwrap()
 5091                                .last_workspace_edits_by_language_server
 5092                                .remove(&lang_server.server_id());
 5093                        })?;
 5094
 5095                        let _result = lang_server
 5096                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5097                                command: command.command.clone(),
 5098                                arguments: command.arguments.clone().unwrap_or_default(),
 5099                                ..lsp::ExecuteCommandParams::default()
 5100                            })
 5101                            .await.into_response()
 5102                            .context("execute command")?;
 5103
 5104                        return this.update(cx, |this, _| {
 5105                            this.as_local_mut()
 5106                                .unwrap()
 5107                                .last_workspace_edits_by_language_server
 5108                                .remove(&lang_server.server_id())
 5109                                .unwrap_or_default()
 5110                        });
 5111                    } else {
 5112                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5113                    }
 5114                }
 5115
 5116                Ok(ProjectTransaction::default())
 5117            })
 5118        } else {
 5119            Task::ready(Err(anyhow!("no upstream client and not local")))
 5120        }
 5121    }
 5122
 5123    pub fn apply_code_action_kind(
 5124        &mut self,
 5125        buffers: HashSet<Entity<Buffer>>,
 5126        kind: CodeActionKind,
 5127        push_to_history: bool,
 5128        cx: &mut Context<Self>,
 5129    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5130        if self.as_local().is_some() {
 5131            cx.spawn(async move |lsp_store, cx| {
 5132                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5133                let result = LocalLspStore::execute_code_action_kind_locally(
 5134                    lsp_store.clone(),
 5135                    buffers,
 5136                    kind,
 5137                    push_to_history,
 5138                    cx,
 5139                )
 5140                .await;
 5141                lsp_store.update(cx, |lsp_store, _| {
 5142                    lsp_store.update_last_formatting_failure(&result);
 5143                })?;
 5144                result
 5145            })
 5146        } else if let Some((client, project_id)) = self.upstream_client() {
 5147            let buffer_store = self.buffer_store();
 5148            cx.spawn(async move |lsp_store, cx| {
 5149                let result = client
 5150                    .request(proto::ApplyCodeActionKind {
 5151                        project_id,
 5152                        kind: kind.as_str().to_owned(),
 5153                        buffer_ids: buffers
 5154                            .iter()
 5155                            .map(|buffer| {
 5156                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5157                            })
 5158                            .collect::<Result<_>>()?,
 5159                    })
 5160                    .await
 5161                    .and_then(|result| result.transaction.context("missing transaction"));
 5162                lsp_store.update(cx, |lsp_store, _| {
 5163                    lsp_store.update_last_formatting_failure(&result);
 5164                })?;
 5165
 5166                let transaction_response = result?;
 5167                buffer_store
 5168                    .update(cx, |buffer_store, cx| {
 5169                        buffer_store.deserialize_project_transaction(
 5170                            transaction_response,
 5171                            push_to_history,
 5172                            cx,
 5173                        )
 5174                    })?
 5175                    .await
 5176            })
 5177        } else {
 5178            Task::ready(Ok(ProjectTransaction::default()))
 5179        }
 5180    }
 5181
 5182    pub fn resolved_hint(
 5183        &mut self,
 5184        buffer_id: BufferId,
 5185        id: InlayId,
 5186        cx: &mut Context<Self>,
 5187    ) -> Option<ResolvedHint> {
 5188        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5189
 5190        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5191        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5192        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5193        let (server_id, resolve_data) = match &hint.resolve_state {
 5194            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5195            ResolveState::Resolving => {
 5196                return Some(ResolvedHint::Resolving(
 5197                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5198                ));
 5199            }
 5200            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5201        };
 5202
 5203        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5204        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5205        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5206            id,
 5207            cx.spawn(async move |lsp_store, cx| {
 5208                let resolved_hint = resolve_task.await;
 5209                lsp_store
 5210                    .update(cx, |lsp_store, _| {
 5211                        if let Some(old_inlay_hint) = lsp_store
 5212                            .lsp_data
 5213                            .get_mut(&buffer_id)
 5214                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5215                        {
 5216                            match resolved_hint {
 5217                                Ok(resolved_hint) => {
 5218                                    *old_inlay_hint = resolved_hint;
 5219                                }
 5220                                Err(e) => {
 5221                                    old_inlay_hint.resolve_state =
 5222                                        ResolveState::CanResolve(server_id, resolve_data);
 5223                                    log::error!("Inlay hint resolve failed: {e:#}");
 5224                                }
 5225                            }
 5226                        }
 5227                    })
 5228                    .ok();
 5229            })
 5230            .shared(),
 5231        );
 5232        debug_assert!(
 5233            previous_task.is_none(),
 5234            "Did not change hint's resolve state after spawning its resolve"
 5235        );
 5236        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5237        None
 5238    }
 5239
 5240    fn resolve_inlay_hint(
 5241        &self,
 5242        mut hint: InlayHint,
 5243        buffer: Entity<Buffer>,
 5244        server_id: LanguageServerId,
 5245        cx: &mut Context<Self>,
 5246    ) -> Task<anyhow::Result<InlayHint>> {
 5247        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5248            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5249            {
 5250                hint.resolve_state = ResolveState::Resolved;
 5251                return Task::ready(Ok(hint));
 5252            }
 5253            let request = proto::ResolveInlayHint {
 5254                project_id,
 5255                buffer_id: buffer.read(cx).remote_id().into(),
 5256                language_server_id: server_id.0 as u64,
 5257                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5258            };
 5259            cx.background_spawn(async move {
 5260                let response = upstream_client
 5261                    .request(request)
 5262                    .await
 5263                    .context("inlay hints proto request")?;
 5264                match response.hint {
 5265                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5266                        .context("inlay hints proto resolve response conversion"),
 5267                    None => Ok(hint),
 5268                }
 5269            })
 5270        } else {
 5271            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5272                self.language_server_for_local_buffer(buffer, server_id, cx)
 5273                    .map(|(_, server)| server.clone())
 5274            }) else {
 5275                return Task::ready(Ok(hint));
 5276            };
 5277            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5278                return Task::ready(Ok(hint));
 5279            }
 5280            let buffer_snapshot = buffer.read(cx).snapshot();
 5281            cx.spawn(async move |_, cx| {
 5282                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5283                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5284                );
 5285                let resolved_hint = resolve_task
 5286                    .await
 5287                    .into_response()
 5288                    .context("inlay hint resolve LSP request")?;
 5289                let resolved_hint = InlayHints::lsp_to_project_hint(
 5290                    resolved_hint,
 5291                    &buffer,
 5292                    server_id,
 5293                    ResolveState::Resolved,
 5294                    false,
 5295                    cx,
 5296                )
 5297                .await?;
 5298                Ok(resolved_hint)
 5299            })
 5300        }
 5301    }
 5302
 5303    pub fn resolve_color_presentation(
 5304        &mut self,
 5305        mut color: DocumentColor,
 5306        buffer: Entity<Buffer>,
 5307        server_id: LanguageServerId,
 5308        cx: &mut Context<Self>,
 5309    ) -> Task<Result<DocumentColor>> {
 5310        if color.resolved {
 5311            return Task::ready(Ok(color));
 5312        }
 5313
 5314        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5315            let start = color.lsp_range.start;
 5316            let end = color.lsp_range.end;
 5317            let request = proto::GetColorPresentation {
 5318                project_id,
 5319                server_id: server_id.to_proto(),
 5320                buffer_id: buffer.read(cx).remote_id().into(),
 5321                color: Some(proto::ColorInformation {
 5322                    red: color.color.red,
 5323                    green: color.color.green,
 5324                    blue: color.color.blue,
 5325                    alpha: color.color.alpha,
 5326                    lsp_range_start: Some(proto::PointUtf16 {
 5327                        row: start.line,
 5328                        column: start.character,
 5329                    }),
 5330                    lsp_range_end: Some(proto::PointUtf16 {
 5331                        row: end.line,
 5332                        column: end.character,
 5333                    }),
 5334                }),
 5335            };
 5336            cx.background_spawn(async move {
 5337                let response = upstream_client
 5338                    .request(request)
 5339                    .await
 5340                    .context("color presentation proto request")?;
 5341                color.resolved = true;
 5342                color.color_presentations = response
 5343                    .presentations
 5344                    .into_iter()
 5345                    .map(|presentation| ColorPresentation {
 5346                        label: SharedString::from(presentation.label),
 5347                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5348                        additional_text_edits: presentation
 5349                            .additional_text_edits
 5350                            .into_iter()
 5351                            .filter_map(deserialize_lsp_edit)
 5352                            .collect(),
 5353                    })
 5354                    .collect();
 5355                Ok(color)
 5356            })
 5357        } else {
 5358            let path = match buffer
 5359                .update(cx, |buffer, cx| {
 5360                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5361                })
 5362                .context("buffer with the missing path")
 5363            {
 5364                Ok(path) => path,
 5365                Err(e) => return Task::ready(Err(e)),
 5366            };
 5367            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5368                self.language_server_for_local_buffer(buffer, server_id, cx)
 5369                    .map(|(_, server)| server.clone())
 5370            }) else {
 5371                return Task::ready(Ok(color));
 5372            };
 5373            cx.background_spawn(async move {
 5374                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5375                    lsp::ColorPresentationParams {
 5376                        text_document: make_text_document_identifier(&path)?,
 5377                        color: color.color,
 5378                        range: color.lsp_range,
 5379                        work_done_progress_params: Default::default(),
 5380                        partial_result_params: Default::default(),
 5381                    },
 5382                );
 5383                color.color_presentations = resolve_task
 5384                    .await
 5385                    .into_response()
 5386                    .context("color presentation resolve LSP request")?
 5387                    .into_iter()
 5388                    .map(|presentation| ColorPresentation {
 5389                        label: SharedString::from(presentation.label),
 5390                        text_edit: presentation.text_edit,
 5391                        additional_text_edits: presentation
 5392                            .additional_text_edits
 5393                            .unwrap_or_default(),
 5394                    })
 5395                    .collect();
 5396                color.resolved = true;
 5397                Ok(color)
 5398            })
 5399        }
 5400    }
 5401
 5402    pub(crate) fn linked_edits(
 5403        &mut self,
 5404        buffer: &Entity<Buffer>,
 5405        position: Anchor,
 5406        cx: &mut Context<Self>,
 5407    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5408        let snapshot = buffer.read(cx).snapshot();
 5409        let scope = snapshot.language_scope_at(position);
 5410        let Some(server_id) = self
 5411            .as_local()
 5412            .and_then(|local| {
 5413                buffer.update(cx, |buffer, cx| {
 5414                    local
 5415                        .language_servers_for_buffer(buffer, cx)
 5416                        .filter(|(_, server)| {
 5417                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5418                        })
 5419                        .filter(|(adapter, _)| {
 5420                            scope
 5421                                .as_ref()
 5422                                .map(|scope| scope.language_allowed(&adapter.name))
 5423                                .unwrap_or(true)
 5424                        })
 5425                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5426                        .next()
 5427                })
 5428            })
 5429            .or_else(|| {
 5430                self.upstream_client()
 5431                    .is_some()
 5432                    .then_some(LanguageServerToQuery::FirstCapable)
 5433            })
 5434            .filter(|_| {
 5435                maybe!({
 5436                    let language = buffer.read(cx).language_at(position)?;
 5437                    Some(
 5438                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5439                            .linked_edits,
 5440                    )
 5441                }) == Some(true)
 5442            })
 5443        else {
 5444            return Task::ready(Ok(Vec::new()));
 5445        };
 5446
 5447        self.request_lsp(
 5448            buffer.clone(),
 5449            server_id,
 5450            LinkedEditingRange { position },
 5451            cx,
 5452        )
 5453    }
 5454
 5455    fn apply_on_type_formatting(
 5456        &mut self,
 5457        buffer: Entity<Buffer>,
 5458        position: Anchor,
 5459        trigger: String,
 5460        cx: &mut Context<Self>,
 5461    ) -> Task<Result<Option<Transaction>>> {
 5462        if let Some((client, project_id)) = self.upstream_client() {
 5463            if !self.check_if_capable_for_proto_request(
 5464                &buffer,
 5465                |capabilities| {
 5466                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5467                },
 5468                cx,
 5469            ) {
 5470                return Task::ready(Ok(None));
 5471            }
 5472            let request = proto::OnTypeFormatting {
 5473                project_id,
 5474                buffer_id: buffer.read(cx).remote_id().into(),
 5475                position: Some(serialize_anchor(&position)),
 5476                trigger,
 5477                version: serialize_version(&buffer.read(cx).version()),
 5478            };
 5479            cx.background_spawn(async move {
 5480                client
 5481                    .request(request)
 5482                    .await?
 5483                    .transaction
 5484                    .map(language::proto::deserialize_transaction)
 5485                    .transpose()
 5486            })
 5487        } else if let Some(local) = self.as_local_mut() {
 5488            let buffer_id = buffer.read(cx).remote_id();
 5489            local.buffers_being_formatted.insert(buffer_id);
 5490            cx.spawn(async move |this, cx| {
 5491                let _cleanup = defer({
 5492                    let this = this.clone();
 5493                    let mut cx = cx.clone();
 5494                    move || {
 5495                        this.update(&mut cx, |this, _| {
 5496                            if let Some(local) = this.as_local_mut() {
 5497                                local.buffers_being_formatted.remove(&buffer_id);
 5498                            }
 5499                        })
 5500                        .ok();
 5501                    }
 5502                });
 5503
 5504                buffer
 5505                    .update(cx, |buffer, _| {
 5506                        buffer.wait_for_edits(Some(position.timestamp))
 5507                    })?
 5508                    .await?;
 5509                this.update(cx, |this, cx| {
 5510                    let position = position.to_point_utf16(buffer.read(cx));
 5511                    this.on_type_format(buffer, position, trigger, false, cx)
 5512                })?
 5513                .await
 5514            })
 5515        } else {
 5516            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5517        }
 5518    }
 5519
 5520    pub fn on_type_format<T: ToPointUtf16>(
 5521        &mut self,
 5522        buffer: Entity<Buffer>,
 5523        position: T,
 5524        trigger: String,
 5525        push_to_history: bool,
 5526        cx: &mut Context<Self>,
 5527    ) -> Task<Result<Option<Transaction>>> {
 5528        let position = position.to_point_utf16(buffer.read(cx));
 5529        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5530    }
 5531
 5532    fn on_type_format_impl(
 5533        &mut self,
 5534        buffer: Entity<Buffer>,
 5535        position: PointUtf16,
 5536        trigger: String,
 5537        push_to_history: bool,
 5538        cx: &mut Context<Self>,
 5539    ) -> Task<Result<Option<Transaction>>> {
 5540        let options = buffer.update(cx, |buffer, cx| {
 5541            lsp_command::lsp_formatting_options(
 5542                language_settings(
 5543                    buffer.language_at(position).map(|l| l.name()),
 5544                    buffer.file(),
 5545                    cx,
 5546                )
 5547                .as_ref(),
 5548            )
 5549        });
 5550
 5551        cx.spawn(async move |this, cx| {
 5552            if let Some(waiter) =
 5553                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5554            {
 5555                waiter.await?;
 5556            }
 5557            cx.update(|cx| {
 5558                this.update(cx, |this, cx| {
 5559                    this.request_lsp(
 5560                        buffer.clone(),
 5561                        LanguageServerToQuery::FirstCapable,
 5562                        OnTypeFormatting {
 5563                            position,
 5564                            trigger,
 5565                            options,
 5566                            push_to_history,
 5567                        },
 5568                        cx,
 5569                    )
 5570                })
 5571            })??
 5572            .await
 5573        })
 5574    }
 5575
 5576    pub fn definitions(
 5577        &mut self,
 5578        buffer: &Entity<Buffer>,
 5579        position: PointUtf16,
 5580        cx: &mut Context<Self>,
 5581    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5582        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5583            let request = GetDefinitions { position };
 5584            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5585                return Task::ready(Ok(None));
 5586            }
 5587            let request_task = upstream_client.request_lsp(
 5588                project_id,
 5589                None,
 5590                LSP_REQUEST_TIMEOUT,
 5591                cx.background_executor().clone(),
 5592                request.to_proto(project_id, buffer.read(cx)),
 5593            );
 5594            let buffer = buffer.clone();
 5595            cx.spawn(async move |weak_lsp_store, cx| {
 5596                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5597                    return Ok(None);
 5598                };
 5599                let Some(responses) = request_task.await? else {
 5600                    return Ok(None);
 5601                };
 5602                let actions = join_all(responses.payload.into_iter().map(|response| {
 5603                    GetDefinitions { position }.response_from_proto(
 5604                        response.response,
 5605                        lsp_store.clone(),
 5606                        buffer.clone(),
 5607                        cx.clone(),
 5608                    )
 5609                }))
 5610                .await;
 5611
 5612                Ok(Some(
 5613                    actions
 5614                        .into_iter()
 5615                        .collect::<Result<Vec<Vec<_>>>>()?
 5616                        .into_iter()
 5617                        .flatten()
 5618                        .dedup()
 5619                        .collect(),
 5620                ))
 5621            })
 5622        } else {
 5623            let definitions_task = self.request_multiple_lsp_locally(
 5624                buffer,
 5625                Some(position),
 5626                GetDefinitions { position },
 5627                cx,
 5628            );
 5629            cx.background_spawn(async move {
 5630                Ok(Some(
 5631                    definitions_task
 5632                        .await
 5633                        .into_iter()
 5634                        .flat_map(|(_, definitions)| definitions)
 5635                        .dedup()
 5636                        .collect(),
 5637                ))
 5638            })
 5639        }
 5640    }
 5641
 5642    pub fn declarations(
 5643        &mut self,
 5644        buffer: &Entity<Buffer>,
 5645        position: PointUtf16,
 5646        cx: &mut Context<Self>,
 5647    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5648        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5649            let request = GetDeclarations { position };
 5650            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5651                return Task::ready(Ok(None));
 5652            }
 5653            let request_task = upstream_client.request_lsp(
 5654                project_id,
 5655                None,
 5656                LSP_REQUEST_TIMEOUT,
 5657                cx.background_executor().clone(),
 5658                request.to_proto(project_id, buffer.read(cx)),
 5659            );
 5660            let buffer = buffer.clone();
 5661            cx.spawn(async move |weak_lsp_store, cx| {
 5662                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5663                    return Ok(None);
 5664                };
 5665                let Some(responses) = request_task.await? else {
 5666                    return Ok(None);
 5667                };
 5668                let actions = join_all(responses.payload.into_iter().map(|response| {
 5669                    GetDeclarations { position }.response_from_proto(
 5670                        response.response,
 5671                        lsp_store.clone(),
 5672                        buffer.clone(),
 5673                        cx.clone(),
 5674                    )
 5675                }))
 5676                .await;
 5677
 5678                Ok(Some(
 5679                    actions
 5680                        .into_iter()
 5681                        .collect::<Result<Vec<Vec<_>>>>()?
 5682                        .into_iter()
 5683                        .flatten()
 5684                        .dedup()
 5685                        .collect(),
 5686                ))
 5687            })
 5688        } else {
 5689            let declarations_task = self.request_multiple_lsp_locally(
 5690                buffer,
 5691                Some(position),
 5692                GetDeclarations { position },
 5693                cx,
 5694            );
 5695            cx.background_spawn(async move {
 5696                Ok(Some(
 5697                    declarations_task
 5698                        .await
 5699                        .into_iter()
 5700                        .flat_map(|(_, declarations)| declarations)
 5701                        .dedup()
 5702                        .collect(),
 5703                ))
 5704            })
 5705        }
 5706    }
 5707
 5708    pub fn type_definitions(
 5709        &mut self,
 5710        buffer: &Entity<Buffer>,
 5711        position: PointUtf16,
 5712        cx: &mut Context<Self>,
 5713    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5714        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5715            let request = GetTypeDefinitions { position };
 5716            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5717                return Task::ready(Ok(None));
 5718            }
 5719            let request_task = upstream_client.request_lsp(
 5720                project_id,
 5721                None,
 5722                LSP_REQUEST_TIMEOUT,
 5723                cx.background_executor().clone(),
 5724                request.to_proto(project_id, buffer.read(cx)),
 5725            );
 5726            let buffer = buffer.clone();
 5727            cx.spawn(async move |weak_lsp_store, cx| {
 5728                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5729                    return Ok(None);
 5730                };
 5731                let Some(responses) = request_task.await? else {
 5732                    return Ok(None);
 5733                };
 5734                let actions = join_all(responses.payload.into_iter().map(|response| {
 5735                    GetTypeDefinitions { position }.response_from_proto(
 5736                        response.response,
 5737                        lsp_store.clone(),
 5738                        buffer.clone(),
 5739                        cx.clone(),
 5740                    )
 5741                }))
 5742                .await;
 5743
 5744                Ok(Some(
 5745                    actions
 5746                        .into_iter()
 5747                        .collect::<Result<Vec<Vec<_>>>>()?
 5748                        .into_iter()
 5749                        .flatten()
 5750                        .dedup()
 5751                        .collect(),
 5752                ))
 5753            })
 5754        } else {
 5755            let type_definitions_task = self.request_multiple_lsp_locally(
 5756                buffer,
 5757                Some(position),
 5758                GetTypeDefinitions { position },
 5759                cx,
 5760            );
 5761            cx.background_spawn(async move {
 5762                Ok(Some(
 5763                    type_definitions_task
 5764                        .await
 5765                        .into_iter()
 5766                        .flat_map(|(_, type_definitions)| type_definitions)
 5767                        .dedup()
 5768                        .collect(),
 5769                ))
 5770            })
 5771        }
 5772    }
 5773
 5774    pub fn implementations(
 5775        &mut self,
 5776        buffer: &Entity<Buffer>,
 5777        position: PointUtf16,
 5778        cx: &mut Context<Self>,
 5779    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5780        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5781            let request = GetImplementations { position };
 5782            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5783                return Task::ready(Ok(None));
 5784            }
 5785            let request_task = upstream_client.request_lsp(
 5786                project_id,
 5787                None,
 5788                LSP_REQUEST_TIMEOUT,
 5789                cx.background_executor().clone(),
 5790                request.to_proto(project_id, buffer.read(cx)),
 5791            );
 5792            let buffer = buffer.clone();
 5793            cx.spawn(async move |weak_lsp_store, cx| {
 5794                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5795                    return Ok(None);
 5796                };
 5797                let Some(responses) = request_task.await? else {
 5798                    return Ok(None);
 5799                };
 5800                let actions = join_all(responses.payload.into_iter().map(|response| {
 5801                    GetImplementations { position }.response_from_proto(
 5802                        response.response,
 5803                        lsp_store.clone(),
 5804                        buffer.clone(),
 5805                        cx.clone(),
 5806                    )
 5807                }))
 5808                .await;
 5809
 5810                Ok(Some(
 5811                    actions
 5812                        .into_iter()
 5813                        .collect::<Result<Vec<Vec<_>>>>()?
 5814                        .into_iter()
 5815                        .flatten()
 5816                        .dedup()
 5817                        .collect(),
 5818                ))
 5819            })
 5820        } else {
 5821            let implementations_task = self.request_multiple_lsp_locally(
 5822                buffer,
 5823                Some(position),
 5824                GetImplementations { position },
 5825                cx,
 5826            );
 5827            cx.background_spawn(async move {
 5828                Ok(Some(
 5829                    implementations_task
 5830                        .await
 5831                        .into_iter()
 5832                        .flat_map(|(_, implementations)| implementations)
 5833                        .dedup()
 5834                        .collect(),
 5835                ))
 5836            })
 5837        }
 5838    }
 5839
 5840    pub fn references(
 5841        &mut self,
 5842        buffer: &Entity<Buffer>,
 5843        position: PointUtf16,
 5844        cx: &mut Context<Self>,
 5845    ) -> Task<Result<Option<Vec<Location>>>> {
 5846        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5847            let request = GetReferences { position };
 5848            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5849                return Task::ready(Ok(None));
 5850            }
 5851
 5852            let request_task = upstream_client.request_lsp(
 5853                project_id,
 5854                None,
 5855                LSP_REQUEST_TIMEOUT,
 5856                cx.background_executor().clone(),
 5857                request.to_proto(project_id, buffer.read(cx)),
 5858            );
 5859            let buffer = buffer.clone();
 5860            cx.spawn(async move |weak_lsp_store, cx| {
 5861                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5862                    return Ok(None);
 5863                };
 5864                let Some(responses) = request_task.await? else {
 5865                    return Ok(None);
 5866                };
 5867
 5868                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5869                    GetReferences { position }.response_from_proto(
 5870                        lsp_response.response,
 5871                        lsp_store.clone(),
 5872                        buffer.clone(),
 5873                        cx.clone(),
 5874                    )
 5875                }))
 5876                .await
 5877                .into_iter()
 5878                .collect::<Result<Vec<Vec<_>>>>()?
 5879                .into_iter()
 5880                .flatten()
 5881                .dedup()
 5882                .collect();
 5883                Ok(Some(locations))
 5884            })
 5885        } else {
 5886            let references_task = self.request_multiple_lsp_locally(
 5887                buffer,
 5888                Some(position),
 5889                GetReferences { position },
 5890                cx,
 5891            );
 5892            cx.background_spawn(async move {
 5893                Ok(Some(
 5894                    references_task
 5895                        .await
 5896                        .into_iter()
 5897                        .flat_map(|(_, references)| references)
 5898                        .dedup()
 5899                        .collect(),
 5900                ))
 5901            })
 5902        }
 5903    }
 5904
 5905    pub fn code_actions(
 5906        &mut self,
 5907        buffer: &Entity<Buffer>,
 5908        range: Range<Anchor>,
 5909        kinds: Option<Vec<CodeActionKind>>,
 5910        cx: &mut Context<Self>,
 5911    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5912        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5913            let request = GetCodeActions {
 5914                range: range.clone(),
 5915                kinds: kinds.clone(),
 5916            };
 5917            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5918                return Task::ready(Ok(None));
 5919            }
 5920            let request_task = upstream_client.request_lsp(
 5921                project_id,
 5922                None,
 5923                LSP_REQUEST_TIMEOUT,
 5924                cx.background_executor().clone(),
 5925                request.to_proto(project_id, buffer.read(cx)),
 5926            );
 5927            let buffer = buffer.clone();
 5928            cx.spawn(async move |weak_lsp_store, cx| {
 5929                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5930                    return Ok(None);
 5931                };
 5932                let Some(responses) = request_task.await? else {
 5933                    return Ok(None);
 5934                };
 5935                let actions = join_all(responses.payload.into_iter().map(|response| {
 5936                    GetCodeActions {
 5937                        range: range.clone(),
 5938                        kinds: kinds.clone(),
 5939                    }
 5940                    .response_from_proto(
 5941                        response.response,
 5942                        lsp_store.clone(),
 5943                        buffer.clone(),
 5944                        cx.clone(),
 5945                    )
 5946                }))
 5947                .await;
 5948
 5949                Ok(Some(
 5950                    actions
 5951                        .into_iter()
 5952                        .collect::<Result<Vec<Vec<_>>>>()?
 5953                        .into_iter()
 5954                        .flatten()
 5955                        .collect(),
 5956                ))
 5957            })
 5958        } else {
 5959            let all_actions_task = self.request_multiple_lsp_locally(
 5960                buffer,
 5961                Some(range.start),
 5962                GetCodeActions { range, kinds },
 5963                cx,
 5964            );
 5965            cx.background_spawn(async move {
 5966                Ok(Some(
 5967                    all_actions_task
 5968                        .await
 5969                        .into_iter()
 5970                        .flat_map(|(_, actions)| actions)
 5971                        .collect(),
 5972                ))
 5973            })
 5974        }
 5975    }
 5976
 5977    pub fn code_lens_actions(
 5978        &mut self,
 5979        buffer: &Entity<Buffer>,
 5980        cx: &mut Context<Self>,
 5981    ) -> CodeLensTask {
 5982        let version_queried_for = buffer.read(cx).version();
 5983        let buffer_id = buffer.read(cx).remote_id();
 5984        let existing_servers = self.as_local().map(|local| {
 5985            local
 5986                .buffers_opened_in_servers
 5987                .get(&buffer_id)
 5988                .cloned()
 5989                .unwrap_or_default()
 5990        });
 5991
 5992        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 5993            if let Some(cached_lens) = &lsp_data.code_lens {
 5994                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 5995                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 5996                        existing_servers != cached_lens.lens.keys().copied().collect()
 5997                    });
 5998                    if !has_different_servers {
 5999                        return Task::ready(Ok(Some(
 6000                            cached_lens.lens.values().flatten().cloned().collect(),
 6001                        )))
 6002                        .shared();
 6003                    }
 6004                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 6005                    if !version_queried_for.changed_since(updating_for) {
 6006                        return running_update.clone();
 6007                    }
 6008                }
 6009            }
 6010        }
 6011
 6012        let lens_lsp_data = self
 6013            .latest_lsp_data(buffer, cx)
 6014            .code_lens
 6015            .get_or_insert_default();
 6016        let buffer = buffer.clone();
 6017        let query_version_queried_for = version_queried_for.clone();
 6018        let new_task = cx
 6019            .spawn(async move |lsp_store, cx| {
 6020                cx.background_executor()
 6021                    .timer(Duration::from_millis(30))
 6022                    .await;
 6023                let fetched_lens = lsp_store
 6024                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 6025                    .map_err(Arc::new)?
 6026                    .await
 6027                    .context("fetching code lens")
 6028                    .map_err(Arc::new);
 6029                let fetched_lens = match fetched_lens {
 6030                    Ok(fetched_lens) => fetched_lens,
 6031                    Err(e) => {
 6032                        lsp_store
 6033                            .update(cx, |lsp_store, _| {
 6034                                if let Some(lens_lsp_data) = lsp_store
 6035                                    .lsp_data
 6036                                    .get_mut(&buffer_id)
 6037                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 6038                                {
 6039                                    lens_lsp_data.update = None;
 6040                                }
 6041                            })
 6042                            .ok();
 6043                        return Err(e);
 6044                    }
 6045                };
 6046
 6047                lsp_store
 6048                    .update(cx, |lsp_store, _| {
 6049                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 6050                        let code_lens = lsp_data.code_lens.as_mut()?;
 6051                        if let Some(fetched_lens) = fetched_lens {
 6052                            if lsp_data.buffer_version == query_version_queried_for {
 6053                                code_lens.lens.extend(fetched_lens);
 6054                            } else if !lsp_data
 6055                                .buffer_version
 6056                                .changed_since(&query_version_queried_for)
 6057                            {
 6058                                lsp_data.buffer_version = query_version_queried_for;
 6059                                code_lens.lens = fetched_lens;
 6060                            }
 6061                        }
 6062                        code_lens.update = None;
 6063                        Some(code_lens.lens.values().flatten().cloned().collect())
 6064                    })
 6065                    .map_err(Arc::new)
 6066            })
 6067            .shared();
 6068        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 6069        new_task
 6070    }
 6071
 6072    fn fetch_code_lens(
 6073        &mut self,
 6074        buffer: &Entity<Buffer>,
 6075        cx: &mut Context<Self>,
 6076    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 6077        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6078            let request = GetCodeLens;
 6079            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6080                return Task::ready(Ok(None));
 6081            }
 6082            let request_task = upstream_client.request_lsp(
 6083                project_id,
 6084                None,
 6085                LSP_REQUEST_TIMEOUT,
 6086                cx.background_executor().clone(),
 6087                request.to_proto(project_id, buffer.read(cx)),
 6088            );
 6089            let buffer = buffer.clone();
 6090            cx.spawn(async move |weak_lsp_store, cx| {
 6091                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6092                    return Ok(None);
 6093                };
 6094                let Some(responses) = request_task.await? else {
 6095                    return Ok(None);
 6096                };
 6097
 6098                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 6099                    let lsp_store = lsp_store.clone();
 6100                    let buffer = buffer.clone();
 6101                    let cx = cx.clone();
 6102                    async move {
 6103                        (
 6104                            LanguageServerId::from_proto(response.server_id),
 6105                            GetCodeLens
 6106                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6107                                .await,
 6108                        )
 6109                    }
 6110                }))
 6111                .await;
 6112
 6113                let mut has_errors = false;
 6114                let code_lens_actions = code_lens_actions
 6115                    .into_iter()
 6116                    .filter_map(|(server_id, code_lens)| match code_lens {
 6117                        Ok(code_lens) => Some((server_id, code_lens)),
 6118                        Err(e) => {
 6119                            has_errors = true;
 6120                            log::error!("{e:#}");
 6121                            None
 6122                        }
 6123                    })
 6124                    .collect::<HashMap<_, _>>();
 6125                anyhow::ensure!(
 6126                    !has_errors || !code_lens_actions.is_empty(),
 6127                    "Failed to fetch code lens"
 6128                );
 6129                Ok(Some(code_lens_actions))
 6130            })
 6131        } else {
 6132            let code_lens_actions_task =
 6133                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 6134            cx.background_spawn(async move {
 6135                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 6136            })
 6137        }
 6138    }
 6139
 6140    #[inline(never)]
 6141    pub fn completions(
 6142        &self,
 6143        buffer: &Entity<Buffer>,
 6144        position: PointUtf16,
 6145        context: CompletionContext,
 6146        cx: &mut Context<Self>,
 6147    ) -> Task<Result<Vec<CompletionResponse>>> {
 6148        let language_registry = self.languages.clone();
 6149
 6150        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6151            let snapshot = buffer.read(cx).snapshot();
 6152            let offset = position.to_offset(&snapshot);
 6153            let scope = snapshot.language_scope_at(offset);
 6154            let capable_lsps = self.all_capable_for_proto_request(
 6155                buffer,
 6156                |server_name, capabilities| {
 6157                    capabilities.completion_provider.is_some()
 6158                        && scope
 6159                            .as_ref()
 6160                            .map(|scope| scope.language_allowed(server_name))
 6161                            .unwrap_or(true)
 6162                },
 6163                cx,
 6164            );
 6165            if capable_lsps.is_empty() {
 6166                return Task::ready(Ok(Vec::new()));
 6167            }
 6168
 6169            let language = buffer.read(cx).language().cloned();
 6170
 6171            // In the future, we should provide project guests with the names of LSP adapters,
 6172            // so that they can use the correct LSP adapter when computing labels. For now,
 6173            // guests just use the first LSP adapter associated with the buffer's language.
 6174            let lsp_adapter = language.as_ref().and_then(|language| {
 6175                language_registry
 6176                    .lsp_adapters(&language.name())
 6177                    .first()
 6178                    .cloned()
 6179            });
 6180
 6181            let buffer = buffer.clone();
 6182
 6183            cx.spawn(async move |this, cx| {
 6184                let requests = join_all(
 6185                    capable_lsps
 6186                        .into_iter()
 6187                        .map(|id| {
 6188                            let request = GetCompletions {
 6189                                position,
 6190                                context: context.clone(),
 6191                                server_id: Some(id),
 6192                            };
 6193                            let buffer = buffer.clone();
 6194                            let language = language.clone();
 6195                            let lsp_adapter = lsp_adapter.clone();
 6196                            let upstream_client = upstream_client.clone();
 6197                            let response = this
 6198                                .update(cx, |this, cx| {
 6199                                    this.send_lsp_proto_request(
 6200                                        buffer,
 6201                                        upstream_client,
 6202                                        project_id,
 6203                                        request,
 6204                                        cx,
 6205                                    )
 6206                                })
 6207                                .log_err();
 6208                            async move {
 6209                                let response = response?.await.log_err()?;
 6210
 6211                                let completions = populate_labels_for_completions(
 6212                                    response.completions,
 6213                                    language,
 6214                                    lsp_adapter,
 6215                                )
 6216                                .await;
 6217
 6218                                Some(CompletionResponse {
 6219                                    completions,
 6220                                    display_options: CompletionDisplayOptions::default(),
 6221                                    is_incomplete: response.is_incomplete,
 6222                                })
 6223                            }
 6224                        })
 6225                        .collect::<Vec<_>>(),
 6226                );
 6227                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6228            })
 6229        } else if let Some(local) = self.as_local() {
 6230            let snapshot = buffer.read(cx).snapshot();
 6231            let offset = position.to_offset(&snapshot);
 6232            let scope = snapshot.language_scope_at(offset);
 6233            let language = snapshot.language().cloned();
 6234            let completion_settings = language_settings(
 6235                language.as_ref().map(|language| language.name()),
 6236                buffer.read(cx).file(),
 6237                cx,
 6238            )
 6239            .completions
 6240            .clone();
 6241            if !completion_settings.lsp {
 6242                return Task::ready(Ok(Vec::new()));
 6243            }
 6244
 6245            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6246                local
 6247                    .language_servers_for_buffer(buffer, cx)
 6248                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6249                    .filter(|(adapter, _)| {
 6250                        scope
 6251                            .as_ref()
 6252                            .map(|scope| scope.language_allowed(&adapter.name))
 6253                            .unwrap_or(true)
 6254                    })
 6255                    .map(|(_, server)| server.server_id())
 6256                    .collect()
 6257            });
 6258
 6259            let buffer = buffer.clone();
 6260            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6261            let lsp_timeout = if lsp_timeout > 0 {
 6262                Some(Duration::from_millis(lsp_timeout))
 6263            } else {
 6264                None
 6265            };
 6266            cx.spawn(async move |this,  cx| {
 6267                let mut tasks = Vec::with_capacity(server_ids.len());
 6268                this.update(cx, |lsp_store, cx| {
 6269                    for server_id in server_ids {
 6270                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6271                        let lsp_timeout = lsp_timeout
 6272                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6273                        let mut timeout = cx.background_spawn(async move {
 6274                            match lsp_timeout {
 6275                                Some(lsp_timeout) => {
 6276                                    lsp_timeout.await;
 6277                                    true
 6278                                },
 6279                                None => false,
 6280                            }
 6281                        }).fuse();
 6282                        let mut lsp_request = lsp_store.request_lsp(
 6283                            buffer.clone(),
 6284                            LanguageServerToQuery::Other(server_id),
 6285                            GetCompletions {
 6286                                position,
 6287                                context: context.clone(),
 6288                                server_id: Some(server_id),
 6289                            },
 6290                            cx,
 6291                        ).fuse();
 6292                        let new_task = cx.background_spawn(async move {
 6293                            select_biased! {
 6294                                response = lsp_request => anyhow::Ok(Some(response?)),
 6295                                timeout_happened = timeout => {
 6296                                    if timeout_happened {
 6297                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6298                                        Ok(None)
 6299                                    } else {
 6300                                        let completions = lsp_request.await?;
 6301                                        Ok(Some(completions))
 6302                                    }
 6303                                },
 6304                            }
 6305                        });
 6306                        tasks.push((lsp_adapter, new_task));
 6307                    }
 6308                })?;
 6309
 6310                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6311                    let completion_response = task.await.ok()??;
 6312                    let completions = populate_labels_for_completions(
 6313                            completion_response.completions,
 6314                            language.clone(),
 6315                            lsp_adapter,
 6316                        )
 6317                        .await;
 6318                    Some(CompletionResponse {
 6319                        completions,
 6320                        display_options: CompletionDisplayOptions::default(),
 6321                        is_incomplete: completion_response.is_incomplete,
 6322                    })
 6323                });
 6324
 6325                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6326
 6327                Ok(responses.into_iter().flatten().collect())
 6328            })
 6329        } else {
 6330            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6331        }
 6332    }
 6333
 6334    pub fn resolve_completions(
 6335        &self,
 6336        buffer: Entity<Buffer>,
 6337        completion_indices: Vec<usize>,
 6338        completions: Rc<RefCell<Box<[Completion]>>>,
 6339        cx: &mut Context<Self>,
 6340    ) -> Task<Result<bool>> {
 6341        let client = self.upstream_client();
 6342        let buffer_id = buffer.read(cx).remote_id();
 6343        let buffer_snapshot = buffer.read(cx).snapshot();
 6344
 6345        if !self.check_if_capable_for_proto_request(
 6346            &buffer,
 6347            GetCompletions::can_resolve_completions,
 6348            cx,
 6349        ) {
 6350            return Task::ready(Ok(false));
 6351        }
 6352        cx.spawn(async move |lsp_store, cx| {
 6353            let mut did_resolve = false;
 6354            if let Some((client, project_id)) = client {
 6355                for completion_index in completion_indices {
 6356                    let server_id = {
 6357                        let completion = &completions.borrow()[completion_index];
 6358                        completion.source.server_id()
 6359                    };
 6360                    if let Some(server_id) = server_id {
 6361                        if Self::resolve_completion_remote(
 6362                            project_id,
 6363                            server_id,
 6364                            buffer_id,
 6365                            completions.clone(),
 6366                            completion_index,
 6367                            client.clone(),
 6368                        )
 6369                        .await
 6370                        .log_err()
 6371                        .is_some()
 6372                        {
 6373                            did_resolve = true;
 6374                        }
 6375                    } else {
 6376                        resolve_word_completion(
 6377                            &buffer_snapshot,
 6378                            &mut completions.borrow_mut()[completion_index],
 6379                        );
 6380                    }
 6381                }
 6382            } else {
 6383                for completion_index in completion_indices {
 6384                    let server_id = {
 6385                        let completion = &completions.borrow()[completion_index];
 6386                        completion.source.server_id()
 6387                    };
 6388                    if let Some(server_id) = server_id {
 6389                        let server_and_adapter = lsp_store
 6390                            .read_with(cx, |lsp_store, _| {
 6391                                let server = lsp_store.language_server_for_id(server_id)?;
 6392                                let adapter =
 6393                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6394                                Some((server, adapter))
 6395                            })
 6396                            .ok()
 6397                            .flatten();
 6398                        let Some((server, adapter)) = server_and_adapter else {
 6399                            continue;
 6400                        };
 6401
 6402                        let resolved = Self::resolve_completion_local(
 6403                            server,
 6404                            completions.clone(),
 6405                            completion_index,
 6406                        )
 6407                        .await
 6408                        .log_err()
 6409                        .is_some();
 6410                        if resolved {
 6411                            Self::regenerate_completion_labels(
 6412                                adapter,
 6413                                &buffer_snapshot,
 6414                                completions.clone(),
 6415                                completion_index,
 6416                            )
 6417                            .await
 6418                            .log_err();
 6419                            did_resolve = true;
 6420                        }
 6421                    } else {
 6422                        resolve_word_completion(
 6423                            &buffer_snapshot,
 6424                            &mut completions.borrow_mut()[completion_index],
 6425                        );
 6426                    }
 6427                }
 6428            }
 6429
 6430            Ok(did_resolve)
 6431        })
 6432    }
 6433
 6434    async fn resolve_completion_local(
 6435        server: Arc<lsp::LanguageServer>,
 6436        completions: Rc<RefCell<Box<[Completion]>>>,
 6437        completion_index: usize,
 6438    ) -> Result<()> {
 6439        let server_id = server.server_id();
 6440        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6441            return Ok(());
 6442        }
 6443
 6444        let request = {
 6445            let completion = &completions.borrow()[completion_index];
 6446            match &completion.source {
 6447                CompletionSource::Lsp {
 6448                    lsp_completion,
 6449                    resolved,
 6450                    server_id: completion_server_id,
 6451                    ..
 6452                } => {
 6453                    if *resolved {
 6454                        return Ok(());
 6455                    }
 6456                    anyhow::ensure!(
 6457                        server_id == *completion_server_id,
 6458                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6459                    );
 6460                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6461                }
 6462                CompletionSource::BufferWord { .. }
 6463                | CompletionSource::Dap { .. }
 6464                | CompletionSource::Custom => {
 6465                    return Ok(());
 6466                }
 6467            }
 6468        };
 6469        let resolved_completion = request
 6470            .await
 6471            .into_response()
 6472            .context("resolve completion")?;
 6473
 6474        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6475        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6476
 6477        let mut completions = completions.borrow_mut();
 6478        let completion = &mut completions[completion_index];
 6479        if let CompletionSource::Lsp {
 6480            lsp_completion,
 6481            resolved,
 6482            server_id: completion_server_id,
 6483            ..
 6484        } = &mut completion.source
 6485        {
 6486            if *resolved {
 6487                return Ok(());
 6488            }
 6489            anyhow::ensure!(
 6490                server_id == *completion_server_id,
 6491                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6492            );
 6493            **lsp_completion = resolved_completion;
 6494            *resolved = true;
 6495        }
 6496        Ok(())
 6497    }
 6498
 6499    async fn regenerate_completion_labels(
 6500        adapter: Arc<CachedLspAdapter>,
 6501        snapshot: &BufferSnapshot,
 6502        completions: Rc<RefCell<Box<[Completion]>>>,
 6503        completion_index: usize,
 6504    ) -> Result<()> {
 6505        let completion_item = completions.borrow()[completion_index]
 6506            .source
 6507            .lsp_completion(true)
 6508            .map(Cow::into_owned);
 6509        if let Some(lsp_documentation) = completion_item
 6510            .as_ref()
 6511            .and_then(|completion_item| completion_item.documentation.clone())
 6512        {
 6513            let mut completions = completions.borrow_mut();
 6514            let completion = &mut completions[completion_index];
 6515            completion.documentation = Some(lsp_documentation.into());
 6516        } else {
 6517            let mut completions = completions.borrow_mut();
 6518            let completion = &mut completions[completion_index];
 6519            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6520        }
 6521
 6522        let mut new_label = match completion_item {
 6523            Some(completion_item) => {
 6524                // 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
 6525                // So we have to update the label here anyway...
 6526                let language = snapshot.language();
 6527                match language {
 6528                    Some(language) => {
 6529                        adapter
 6530                            .labels_for_completions(
 6531                                std::slice::from_ref(&completion_item),
 6532                                language,
 6533                            )
 6534                            .await?
 6535                    }
 6536                    None => Vec::new(),
 6537                }
 6538                .pop()
 6539                .flatten()
 6540                .unwrap_or_else(|| {
 6541                    CodeLabel::fallback_for_completion(
 6542                        &completion_item,
 6543                        language.map(|language| language.as_ref()),
 6544                    )
 6545                })
 6546            }
 6547            None => CodeLabel::plain(
 6548                completions.borrow()[completion_index].new_text.clone(),
 6549                None,
 6550            ),
 6551        };
 6552        ensure_uniform_list_compatible_label(&mut new_label);
 6553
 6554        let mut completions = completions.borrow_mut();
 6555        let completion = &mut completions[completion_index];
 6556        if completion.label.filter_text() == new_label.filter_text() {
 6557            completion.label = new_label;
 6558        } else {
 6559            log::error!(
 6560                "Resolved completion changed display label from {} to {}. \
 6561                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6562                completion.label.text(),
 6563                new_label.text(),
 6564                completion.label.filter_text(),
 6565                new_label.filter_text()
 6566            );
 6567        }
 6568
 6569        Ok(())
 6570    }
 6571
 6572    async fn resolve_completion_remote(
 6573        project_id: u64,
 6574        server_id: LanguageServerId,
 6575        buffer_id: BufferId,
 6576        completions: Rc<RefCell<Box<[Completion]>>>,
 6577        completion_index: usize,
 6578        client: AnyProtoClient,
 6579    ) -> Result<()> {
 6580        let lsp_completion = {
 6581            let completion = &completions.borrow()[completion_index];
 6582            match &completion.source {
 6583                CompletionSource::Lsp {
 6584                    lsp_completion,
 6585                    resolved,
 6586                    server_id: completion_server_id,
 6587                    ..
 6588                } => {
 6589                    anyhow::ensure!(
 6590                        server_id == *completion_server_id,
 6591                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6592                    );
 6593                    if *resolved {
 6594                        return Ok(());
 6595                    }
 6596                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6597                }
 6598                CompletionSource::Custom
 6599                | CompletionSource::Dap { .. }
 6600                | CompletionSource::BufferWord { .. } => {
 6601                    return Ok(());
 6602                }
 6603            }
 6604        };
 6605        let request = proto::ResolveCompletionDocumentation {
 6606            project_id,
 6607            language_server_id: server_id.0 as u64,
 6608            lsp_completion,
 6609            buffer_id: buffer_id.into(),
 6610        };
 6611
 6612        let response = client
 6613            .request(request)
 6614            .await
 6615            .context("completion documentation resolve proto request")?;
 6616        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6617
 6618        let documentation = if response.documentation.is_empty() {
 6619            CompletionDocumentation::Undocumented
 6620        } else if response.documentation_is_markdown {
 6621            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6622        } else if response.documentation.lines().count() <= 1 {
 6623            CompletionDocumentation::SingleLine(response.documentation.into())
 6624        } else {
 6625            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6626        };
 6627
 6628        let mut completions = completions.borrow_mut();
 6629        let completion = &mut completions[completion_index];
 6630        completion.documentation = Some(documentation);
 6631        if let CompletionSource::Lsp {
 6632            insert_range,
 6633            lsp_completion,
 6634            resolved,
 6635            server_id: completion_server_id,
 6636            lsp_defaults: _,
 6637        } = &mut completion.source
 6638        {
 6639            let completion_insert_range = response
 6640                .old_insert_start
 6641                .and_then(deserialize_anchor)
 6642                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6643            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6644
 6645            if *resolved {
 6646                return Ok(());
 6647            }
 6648            anyhow::ensure!(
 6649                server_id == *completion_server_id,
 6650                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6651            );
 6652            **lsp_completion = resolved_lsp_completion;
 6653            *resolved = true;
 6654        }
 6655
 6656        let replace_range = response
 6657            .old_replace_start
 6658            .and_then(deserialize_anchor)
 6659            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6660        if let Some((old_replace_start, old_replace_end)) = replace_range
 6661            && !response.new_text.is_empty()
 6662        {
 6663            completion.new_text = response.new_text;
 6664            completion.replace_range = old_replace_start..old_replace_end;
 6665        }
 6666
 6667        Ok(())
 6668    }
 6669
 6670    pub fn apply_additional_edits_for_completion(
 6671        &self,
 6672        buffer_handle: Entity<Buffer>,
 6673        completions: Rc<RefCell<Box<[Completion]>>>,
 6674        completion_index: usize,
 6675        push_to_history: bool,
 6676        cx: &mut Context<Self>,
 6677    ) -> Task<Result<Option<Transaction>>> {
 6678        if let Some((client, project_id)) = self.upstream_client() {
 6679            let buffer = buffer_handle.read(cx);
 6680            let buffer_id = buffer.remote_id();
 6681            cx.spawn(async move |_, cx| {
 6682                let request = {
 6683                    let completion = completions.borrow()[completion_index].clone();
 6684                    proto::ApplyCompletionAdditionalEdits {
 6685                        project_id,
 6686                        buffer_id: buffer_id.into(),
 6687                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6688                            replace_range: completion.replace_range,
 6689                            new_text: completion.new_text,
 6690                            source: completion.source,
 6691                        })),
 6692                    }
 6693                };
 6694
 6695                if let Some(transaction) = client.request(request).await?.transaction {
 6696                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6697                    buffer_handle
 6698                        .update(cx, |buffer, _| {
 6699                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6700                        })?
 6701                        .await?;
 6702                    if push_to_history {
 6703                        buffer_handle.update(cx, |buffer, _| {
 6704                            buffer.push_transaction(transaction.clone(), Instant::now());
 6705                            buffer.finalize_last_transaction();
 6706                        })?;
 6707                    }
 6708                    Ok(Some(transaction))
 6709                } else {
 6710                    Ok(None)
 6711                }
 6712            })
 6713        } else {
 6714            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6715                let completion = &completions.borrow()[completion_index];
 6716                let server_id = completion.source.server_id()?;
 6717                Some(
 6718                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6719                        .1
 6720                        .clone(),
 6721                )
 6722            }) else {
 6723                return Task::ready(Ok(None));
 6724            };
 6725
 6726            cx.spawn(async move |this, cx| {
 6727                Self::resolve_completion_local(
 6728                    server.clone(),
 6729                    completions.clone(),
 6730                    completion_index,
 6731                )
 6732                .await
 6733                .context("resolving completion")?;
 6734                let completion = completions.borrow()[completion_index].clone();
 6735                let additional_text_edits = completion
 6736                    .source
 6737                    .lsp_completion(true)
 6738                    .as_ref()
 6739                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6740                if let Some(edits) = additional_text_edits {
 6741                    let edits = this
 6742                        .update(cx, |this, cx| {
 6743                            this.as_local_mut().unwrap().edits_from_lsp(
 6744                                &buffer_handle,
 6745                                edits,
 6746                                server.server_id(),
 6747                                None,
 6748                                cx,
 6749                            )
 6750                        })?
 6751                        .await?;
 6752
 6753                    buffer_handle.update(cx, |buffer, cx| {
 6754                        buffer.finalize_last_transaction();
 6755                        buffer.start_transaction();
 6756
 6757                        for (range, text) in edits {
 6758                            let primary = &completion.replace_range;
 6759
 6760                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6761                            // and the primary completion is just an insertion (empty range), then this is likely
 6762                            // an auto-import scenario and should not be considered overlapping
 6763                            // https://github.com/zed-industries/zed/issues/26136
 6764                            let is_file_start_auto_import = {
 6765                                let snapshot = buffer.snapshot();
 6766                                let primary_start_point = primary.start.to_point(&snapshot);
 6767                                let range_start_point = range.start.to_point(&snapshot);
 6768
 6769                                let result = primary_start_point.row == 0
 6770                                    && primary_start_point.column == 0
 6771                                    && range_start_point.row == 0
 6772                                    && range_start_point.column == 0;
 6773
 6774                                result
 6775                            };
 6776
 6777                            let has_overlap = if is_file_start_auto_import {
 6778                                false
 6779                            } else {
 6780                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6781                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6782                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6783                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6784                                let result = start_within || end_within;
 6785                                result
 6786                            };
 6787
 6788                            //Skip additional edits which overlap with the primary completion edit
 6789                            //https://github.com/zed-industries/zed/pull/1871
 6790                            if !has_overlap {
 6791                                buffer.edit([(range, text)], None, cx);
 6792                            }
 6793                        }
 6794
 6795                        let transaction = if buffer.end_transaction(cx).is_some() {
 6796                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6797                            if !push_to_history {
 6798                                buffer.forget_transaction(transaction.id);
 6799                            }
 6800                            Some(transaction)
 6801                        } else {
 6802                            None
 6803                        };
 6804                        Ok(transaction)
 6805                    })?
 6806                } else {
 6807                    Ok(None)
 6808                }
 6809            })
 6810        }
 6811    }
 6812
 6813    pub fn pull_diagnostics(
 6814        &mut self,
 6815        buffer: Entity<Buffer>,
 6816        cx: &mut Context<Self>,
 6817    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6818        let buffer_id = buffer.read(cx).remote_id();
 6819
 6820        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6821            let mut suitable_capabilities = None;
 6822            // Are we capable for proto request?
 6823            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6824                &buffer,
 6825                |capabilities| {
 6826                    if let Some(caps) = &capabilities.diagnostic_provider {
 6827                        suitable_capabilities = Some(caps.clone());
 6828                        true
 6829                    } else {
 6830                        false
 6831                    }
 6832                },
 6833                cx,
 6834            );
 6835            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6836            let Some(dynamic_caps) = suitable_capabilities else {
 6837                return Task::ready(Ok(None));
 6838            };
 6839            assert!(any_server_has_diagnostics_provider);
 6840
 6841            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6842            let request = GetDocumentDiagnostics {
 6843                previous_result_id: None,
 6844                identifier,
 6845                registration_id: None,
 6846            };
 6847            let request_task = client.request_lsp(
 6848                upstream_project_id,
 6849                None,
 6850                LSP_REQUEST_TIMEOUT,
 6851                cx.background_executor().clone(),
 6852                request.to_proto(upstream_project_id, buffer.read(cx)),
 6853            );
 6854            cx.background_spawn(async move {
 6855                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6856                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6857                // Do not attempt to further process the dummy responses here.
 6858                let _response = request_task.await?;
 6859                Ok(None)
 6860            })
 6861        } else {
 6862            let servers = buffer.update(cx, |buffer, cx| {
 6863                self.running_language_servers_for_local_buffer(buffer, cx)
 6864                    .map(|(_, server)| server.clone())
 6865                    .collect::<Vec<_>>()
 6866            });
 6867
 6868            let pull_diagnostics = servers
 6869                .into_iter()
 6870                .flat_map(|server| {
 6871                    let result = maybe!({
 6872                        let local = self.as_local()?;
 6873                        let server_id = server.server_id();
 6874                        let providers_with_identifiers = local
 6875                            .language_server_dynamic_registrations
 6876                            .get(&server_id)
 6877                            .into_iter()
 6878                            .flat_map(|registrations| registrations.diagnostics.clone())
 6879                            .collect::<Vec<_>>();
 6880                        Some(
 6881                            providers_with_identifiers
 6882                                .into_iter()
 6883                                .map(|(registration_id, dynamic_caps)| {
 6884                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6885                                    let registration_id = registration_id.map(SharedString::from);
 6886                                    let result_id = self.result_id_for_buffer_pull(
 6887                                        server_id,
 6888                                        buffer_id,
 6889                                        &registration_id,
 6890                                        cx,
 6891                                    );
 6892                                    self.request_lsp(
 6893                                        buffer.clone(),
 6894                                        LanguageServerToQuery::Other(server_id),
 6895                                        GetDocumentDiagnostics {
 6896                                            previous_result_id: result_id,
 6897                                            registration_id,
 6898                                            identifier,
 6899                                        },
 6900                                        cx,
 6901                                    )
 6902                                })
 6903                                .collect::<Vec<_>>(),
 6904                        )
 6905                    });
 6906
 6907                    result.unwrap_or_default()
 6908                })
 6909                .collect::<Vec<_>>();
 6910
 6911            cx.background_spawn(async move {
 6912                let mut responses = Vec::new();
 6913                for diagnostics in join_all(pull_diagnostics).await {
 6914                    responses.extend(diagnostics?);
 6915                }
 6916                Ok(Some(responses))
 6917            })
 6918        }
 6919    }
 6920
 6921    pub fn applicable_inlay_chunks(
 6922        &mut self,
 6923        buffer: &Entity<Buffer>,
 6924        ranges: &[Range<text::Anchor>],
 6925        cx: &mut Context<Self>,
 6926    ) -> Vec<Range<BufferRow>> {
 6927        let buffer_snapshot = buffer.read(cx).snapshot();
 6928        let ranges = ranges
 6929            .iter()
 6930            .map(|range| range.to_point(&buffer_snapshot))
 6931            .collect::<Vec<_>>();
 6932
 6933        self.latest_lsp_data(buffer, cx)
 6934            .inlay_hints
 6935            .applicable_chunks(ranges.as_slice())
 6936            .map(|chunk| chunk.row_range())
 6937            .collect()
 6938    }
 6939
 6940    pub fn invalidate_inlay_hints<'a>(
 6941        &'a mut self,
 6942        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6943    ) {
 6944        for buffer_id in for_buffers {
 6945            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6946                lsp_data.inlay_hints.clear();
 6947            }
 6948        }
 6949    }
 6950
 6951    pub fn inlay_hints(
 6952        &mut self,
 6953        invalidate: InvalidationStrategy,
 6954        buffer: Entity<Buffer>,
 6955        ranges: Vec<Range<text::Anchor>>,
 6956        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6957        cx: &mut Context<Self>,
 6958    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6959        let next_hint_id = self.next_hint_id.clone();
 6960        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6961        let query_version = lsp_data.buffer_version.clone();
 6962        let mut lsp_refresh_requested = false;
 6963        let for_server = if let InvalidationStrategy::RefreshRequested {
 6964            server_id,
 6965            request_id,
 6966        } = invalidate
 6967        {
 6968            let invalidated = lsp_data
 6969                .inlay_hints
 6970                .invalidate_for_server_refresh(server_id, request_id);
 6971            lsp_refresh_requested = invalidated;
 6972            Some(server_id)
 6973        } else {
 6974            None
 6975        };
 6976        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6977        let known_chunks = known_chunks
 6978            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6979            .map(|(_, known_chunks)| known_chunks)
 6980            .unwrap_or_default();
 6981
 6982        let buffer_snapshot = buffer.read(cx).snapshot();
 6983        let ranges = ranges
 6984            .iter()
 6985            .map(|range| range.to_point(&buffer_snapshot))
 6986            .collect::<Vec<_>>();
 6987
 6988        let mut hint_fetch_tasks = Vec::new();
 6989        let mut cached_inlay_hints = None;
 6990        let mut ranges_to_query = None;
 6991        let applicable_chunks = existing_inlay_hints
 6992            .applicable_chunks(ranges.as_slice())
 6993            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 6994            .collect::<Vec<_>>();
 6995        if applicable_chunks.is_empty() {
 6996            return HashMap::default();
 6997        }
 6998
 6999        for row_chunk in applicable_chunks {
 7000            match (
 7001                existing_inlay_hints
 7002                    .cached_hints(&row_chunk)
 7003                    .filter(|_| !lsp_refresh_requested)
 7004                    .cloned(),
 7005                existing_inlay_hints
 7006                    .fetched_hints(&row_chunk)
 7007                    .as_ref()
 7008                    .filter(|_| !lsp_refresh_requested)
 7009                    .cloned(),
 7010            ) {
 7011                (None, None) => {
 7012                    let chunk_range = row_chunk.anchor_range();
 7013                    ranges_to_query
 7014                        .get_or_insert_with(Vec::new)
 7015                        .push((row_chunk, chunk_range));
 7016                }
 7017                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7018                (Some(cached_hints), None) => {
 7019                    for (server_id, cached_hints) in cached_hints {
 7020                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7021                            cached_inlay_hints
 7022                                .get_or_insert_with(HashMap::default)
 7023                                .entry(row_chunk.row_range())
 7024                                .or_insert_with(HashMap::default)
 7025                                .entry(server_id)
 7026                                .or_insert_with(Vec::new)
 7027                                .extend(cached_hints);
 7028                        }
 7029                    }
 7030                }
 7031                (Some(cached_hints), Some(fetched_hints)) => {
 7032                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7033                    for (server_id, cached_hints) in cached_hints {
 7034                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7035                            cached_inlay_hints
 7036                                .get_or_insert_with(HashMap::default)
 7037                                .entry(row_chunk.row_range())
 7038                                .or_insert_with(HashMap::default)
 7039                                .entry(server_id)
 7040                                .or_insert_with(Vec::new)
 7041                                .extend(cached_hints);
 7042                        }
 7043                    }
 7044                }
 7045            }
 7046        }
 7047
 7048        if hint_fetch_tasks.is_empty()
 7049            && ranges_to_query
 7050                .as_ref()
 7051                .is_none_or(|ranges| ranges.is_empty())
 7052            && let Some(cached_inlay_hints) = cached_inlay_hints
 7053        {
 7054            cached_inlay_hints
 7055                .into_iter()
 7056                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7057                .collect()
 7058        } else {
 7059            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7060                let next_hint_id = next_hint_id.clone();
 7061                let buffer = buffer.clone();
 7062                let query_version = query_version.clone();
 7063                let new_inlay_hints = cx
 7064                    .spawn(async move |lsp_store, cx| {
 7065                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7066                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7067                        })?;
 7068                        new_fetch_task
 7069                            .await
 7070                            .and_then(|new_hints_by_server| {
 7071                                lsp_store.update(cx, |lsp_store, cx| {
 7072                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7073                                    let update_cache = lsp_data.buffer_version == query_version;
 7074                                    if new_hints_by_server.is_empty() {
 7075                                        if update_cache {
 7076                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7077                                        }
 7078                                        HashMap::default()
 7079                                    } else {
 7080                                        new_hints_by_server
 7081                                            .into_iter()
 7082                                            .map(|(server_id, new_hints)| {
 7083                                                let new_hints = new_hints
 7084                                                    .into_iter()
 7085                                                    .map(|new_hint| {
 7086                                                        (
 7087                                                            InlayId::Hint(next_hint_id.fetch_add(
 7088                                                                1,
 7089                                                                atomic::Ordering::AcqRel,
 7090                                                            )),
 7091                                                            new_hint,
 7092                                                        )
 7093                                                    })
 7094                                                    .collect::<Vec<_>>();
 7095                                                if update_cache {
 7096                                                    lsp_data.inlay_hints.insert_new_hints(
 7097                                                        chunk,
 7098                                                        server_id,
 7099                                                        new_hints.clone(),
 7100                                                    );
 7101                                                }
 7102                                                (server_id, new_hints)
 7103                                            })
 7104                                            .collect()
 7105                                    }
 7106                                })
 7107                            })
 7108                            .map_err(Arc::new)
 7109                    })
 7110                    .shared();
 7111
 7112                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7113                *fetch_task = Some(new_inlay_hints.clone());
 7114                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7115            }
 7116
 7117            cached_inlay_hints
 7118                .unwrap_or_default()
 7119                .into_iter()
 7120                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7121                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7122                    (
 7123                        chunk.row_range(),
 7124                        cx.spawn(async move |_, _| {
 7125                            hints_fetch.await.map_err(|e| {
 7126                                if e.error_code() != ErrorCode::Internal {
 7127                                    anyhow!(e.error_code())
 7128                                } else {
 7129                                    anyhow!("{e:#}")
 7130                                }
 7131                            })
 7132                        }),
 7133                    )
 7134                }))
 7135                .collect()
 7136        }
 7137    }
 7138
 7139    fn fetch_inlay_hints(
 7140        &mut self,
 7141        for_server: Option<LanguageServerId>,
 7142        buffer: &Entity<Buffer>,
 7143        range: Range<Anchor>,
 7144        cx: &mut Context<Self>,
 7145    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7146        let request = InlayHints {
 7147            range: range.clone(),
 7148        };
 7149        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7150            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7151                return Task::ready(Ok(HashMap::default()));
 7152            }
 7153            let request_task = upstream_client.request_lsp(
 7154                project_id,
 7155                for_server.map(|id| id.to_proto()),
 7156                LSP_REQUEST_TIMEOUT,
 7157                cx.background_executor().clone(),
 7158                request.to_proto(project_id, buffer.read(cx)),
 7159            );
 7160            let buffer = buffer.clone();
 7161            cx.spawn(async move |weak_lsp_store, cx| {
 7162                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7163                    return Ok(HashMap::default());
 7164                };
 7165                let Some(responses) = request_task.await? else {
 7166                    return Ok(HashMap::default());
 7167                };
 7168
 7169                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7170                    let lsp_store = lsp_store.clone();
 7171                    let buffer = buffer.clone();
 7172                    let cx = cx.clone();
 7173                    let request = request.clone();
 7174                    async move {
 7175                        (
 7176                            LanguageServerId::from_proto(response.server_id),
 7177                            request
 7178                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7179                                .await,
 7180                        )
 7181                    }
 7182                }))
 7183                .await;
 7184
 7185                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot())?;
 7186                let mut has_errors = false;
 7187                let inlay_hints = inlay_hints
 7188                    .into_iter()
 7189                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7190                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7191                        Err(e) => {
 7192                            has_errors = true;
 7193                            log::error!("{e:#}");
 7194                            None
 7195                        }
 7196                    })
 7197                    .map(|(server_id, mut new_hints)| {
 7198                        new_hints.retain(|hint| {
 7199                            hint.position.is_valid(&buffer_snapshot)
 7200                                && range.start.is_valid(&buffer_snapshot)
 7201                                && range.end.is_valid(&buffer_snapshot)
 7202                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7203                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7204                        });
 7205                        (server_id, new_hints)
 7206                    })
 7207                    .collect::<HashMap<_, _>>();
 7208                anyhow::ensure!(
 7209                    !has_errors || !inlay_hints.is_empty(),
 7210                    "Failed to fetch inlay hints"
 7211                );
 7212                Ok(inlay_hints)
 7213            })
 7214        } else {
 7215            let inlay_hints_task = match for_server {
 7216                Some(server_id) => {
 7217                    let server_task = self.request_lsp(
 7218                        buffer.clone(),
 7219                        LanguageServerToQuery::Other(server_id),
 7220                        request,
 7221                        cx,
 7222                    );
 7223                    cx.background_spawn(async move {
 7224                        let mut responses = Vec::new();
 7225                        match server_task.await {
 7226                            Ok(response) => responses.push((server_id, response)),
 7227                            // rust-analyzer likes to error with this when its still loading up
 7228                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7229                            Err(e) => log::error!(
 7230                                "Error handling response for inlay hints request: {e:#}"
 7231                            ),
 7232                        }
 7233                        responses
 7234                    })
 7235                }
 7236                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7237            };
 7238            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7239            cx.background_spawn(async move {
 7240                Ok(inlay_hints_task
 7241                    .await
 7242                    .into_iter()
 7243                    .map(|(server_id, mut new_hints)| {
 7244                        new_hints.retain(|hint| {
 7245                            hint.position.is_valid(&buffer_snapshot)
 7246                                && range.start.is_valid(&buffer_snapshot)
 7247                                && range.end.is_valid(&buffer_snapshot)
 7248                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7249                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7250                        });
 7251                        (server_id, new_hints)
 7252                    })
 7253                    .collect())
 7254            })
 7255        }
 7256    }
 7257
 7258    pub fn pull_diagnostics_for_buffer(
 7259        &mut self,
 7260        buffer: Entity<Buffer>,
 7261        cx: &mut Context<Self>,
 7262    ) -> Task<anyhow::Result<()>> {
 7263        let diagnostics = self.pull_diagnostics(buffer, cx);
 7264        cx.spawn(async move |lsp_store, cx| {
 7265            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7266                return Ok(());
 7267            };
 7268            lsp_store.update(cx, |lsp_store, cx| {
 7269                if lsp_store.as_local().is_none() {
 7270                    return;
 7271                }
 7272
 7273                let mut unchanged_buffers = HashMap::default();
 7274                let server_diagnostics_updates = diagnostics
 7275                    .into_iter()
 7276                    .filter_map(|diagnostics_set| match diagnostics_set {
 7277                        LspPullDiagnostics::Response {
 7278                            server_id,
 7279                            uri,
 7280                            diagnostics,
 7281                            registration_id,
 7282                        } => Some((server_id, uri, diagnostics, registration_id)),
 7283                        LspPullDiagnostics::Default => None,
 7284                    })
 7285                    .fold(
 7286                        HashMap::default(),
 7287                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7288                            let (result_id, diagnostics) = match diagnostics {
 7289                                PulledDiagnostics::Unchanged { result_id } => {
 7290                                    unchanged_buffers
 7291                                        .entry(new_registration_id.clone())
 7292                                        .or_insert_with(HashSet::default)
 7293                                        .insert(uri.clone());
 7294                                    (Some(result_id), Vec::new())
 7295                                }
 7296                                PulledDiagnostics::Changed {
 7297                                    result_id,
 7298                                    diagnostics,
 7299                                } => (result_id, diagnostics),
 7300                            };
 7301                            let disk_based_sources = Cow::Owned(
 7302                                lsp_store
 7303                                    .language_server_adapter_for_id(server_id)
 7304                                    .as_ref()
 7305                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7306                                    .unwrap_or(&[])
 7307                                    .to_vec(),
 7308                            );
 7309                            acc.entry(server_id)
 7310                                .or_insert_with(HashMap::default)
 7311                                .entry(new_registration_id.clone())
 7312                                .or_insert_with(Vec::new)
 7313                                .push(DocumentDiagnosticsUpdate {
 7314                                    server_id,
 7315                                    diagnostics: lsp::PublishDiagnosticsParams {
 7316                                        uri,
 7317                                        diagnostics,
 7318                                        version: None,
 7319                                    },
 7320                                    result_id,
 7321                                    disk_based_sources,
 7322                                    registration_id: new_registration_id,
 7323                                });
 7324                            acc
 7325                        },
 7326                    );
 7327
 7328                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7329                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7330                        lsp_store
 7331                            .merge_lsp_diagnostics(
 7332                                DiagnosticSourceKind::Pulled,
 7333                                diagnostic_updates,
 7334                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7335                                    DiagnosticSourceKind::Pulled => {
 7336                                        old_diagnostic.registration_id != registration_id
 7337                                            || unchanged_buffers
 7338                                                .get(&old_diagnostic.registration_id)
 7339                                                .is_some_and(|unchanged_buffers| {
 7340                                                    unchanged_buffers.contains(&document_uri)
 7341                                                })
 7342                                    }
 7343                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7344                                        true
 7345                                    }
 7346                                },
 7347                                cx,
 7348                            )
 7349                            .log_err();
 7350                    }
 7351                }
 7352            })
 7353        })
 7354    }
 7355
 7356    pub fn document_colors(
 7357        &mut self,
 7358        known_cache_version: Option<usize>,
 7359        buffer: Entity<Buffer>,
 7360        cx: &mut Context<Self>,
 7361    ) -> Option<DocumentColorTask> {
 7362        let version_queried_for = buffer.read(cx).version();
 7363        let buffer_id = buffer.read(cx).remote_id();
 7364
 7365        let current_language_servers = self.as_local().map(|local| {
 7366            local
 7367                .buffers_opened_in_servers
 7368                .get(&buffer_id)
 7369                .cloned()
 7370                .unwrap_or_default()
 7371        });
 7372
 7373        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7374            if let Some(cached_colors) = &lsp_data.document_colors {
 7375                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7376                    let has_different_servers =
 7377                        current_language_servers.is_some_and(|current_language_servers| {
 7378                            current_language_servers
 7379                                != cached_colors.colors.keys().copied().collect()
 7380                        });
 7381                    if !has_different_servers {
 7382                        let cache_version = cached_colors.cache_version;
 7383                        if Some(cache_version) == known_cache_version {
 7384                            return None;
 7385                        } else {
 7386                            return Some(
 7387                                Task::ready(Ok(DocumentColors {
 7388                                    colors: cached_colors
 7389                                        .colors
 7390                                        .values()
 7391                                        .flatten()
 7392                                        .cloned()
 7393                                        .collect(),
 7394                                    cache_version: Some(cache_version),
 7395                                }))
 7396                                .shared(),
 7397                            );
 7398                        }
 7399                    }
 7400                }
 7401            }
 7402        }
 7403
 7404        let color_lsp_data = self
 7405            .latest_lsp_data(&buffer, cx)
 7406            .document_colors
 7407            .get_or_insert_default();
 7408        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7409            && !version_queried_for.changed_since(updating_for)
 7410        {
 7411            return Some(running_update.clone());
 7412        }
 7413        let buffer_version_queried_for = version_queried_for.clone();
 7414        let new_task = cx
 7415            .spawn(async move |lsp_store, cx| {
 7416                cx.background_executor()
 7417                    .timer(Duration::from_millis(30))
 7418                    .await;
 7419                let fetched_colors = lsp_store
 7420                    .update(cx, |lsp_store, cx| {
 7421                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7422                    })?
 7423                    .await
 7424                    .context("fetching document colors")
 7425                    .map_err(Arc::new);
 7426                let fetched_colors = match fetched_colors {
 7427                    Ok(fetched_colors) => {
 7428                        if Some(true)
 7429                            == buffer
 7430                                .update(cx, |buffer, _| {
 7431                                    buffer.version() != buffer_version_queried_for
 7432                                })
 7433                                .ok()
 7434                        {
 7435                            return Ok(DocumentColors::default());
 7436                        }
 7437                        fetched_colors
 7438                    }
 7439                    Err(e) => {
 7440                        lsp_store
 7441                            .update(cx, |lsp_store, _| {
 7442                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7443                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7444                                        document_colors.colors_update = None;
 7445                                    }
 7446                                }
 7447                            })
 7448                            .ok();
 7449                        return Err(e);
 7450                    }
 7451                };
 7452
 7453                lsp_store
 7454                    .update(cx, |lsp_store, cx| {
 7455                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7456                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7457
 7458                        if let Some(fetched_colors) = fetched_colors {
 7459                            if lsp_data.buffer_version == buffer_version_queried_for {
 7460                                lsp_colors.colors.extend(fetched_colors);
 7461                                lsp_colors.cache_version += 1;
 7462                            } else if !lsp_data
 7463                                .buffer_version
 7464                                .changed_since(&buffer_version_queried_for)
 7465                            {
 7466                                lsp_data.buffer_version = buffer_version_queried_for;
 7467                                lsp_colors.colors = fetched_colors;
 7468                                lsp_colors.cache_version += 1;
 7469                            }
 7470                        }
 7471                        lsp_colors.colors_update = None;
 7472                        let colors = lsp_colors
 7473                            .colors
 7474                            .values()
 7475                            .flatten()
 7476                            .cloned()
 7477                            .collect::<HashSet<_>>();
 7478                        DocumentColors {
 7479                            colors,
 7480                            cache_version: Some(lsp_colors.cache_version),
 7481                        }
 7482                    })
 7483                    .map_err(Arc::new)
 7484            })
 7485            .shared();
 7486        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7487        Some(new_task)
 7488    }
 7489
 7490    fn fetch_document_colors_for_buffer(
 7491        &mut self,
 7492        buffer: &Entity<Buffer>,
 7493        cx: &mut Context<Self>,
 7494    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7495        if let Some((client, project_id)) = self.upstream_client() {
 7496            let request = GetDocumentColor {};
 7497            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7498                return Task::ready(Ok(None));
 7499            }
 7500
 7501            let request_task = client.request_lsp(
 7502                project_id,
 7503                None,
 7504                LSP_REQUEST_TIMEOUT,
 7505                cx.background_executor().clone(),
 7506                request.to_proto(project_id, buffer.read(cx)),
 7507            );
 7508            let buffer = buffer.clone();
 7509            cx.spawn(async move |lsp_store, cx| {
 7510                let Some(lsp_store) = lsp_store.upgrade() else {
 7511                    return Ok(None);
 7512                };
 7513                let colors = join_all(
 7514                    request_task
 7515                        .await
 7516                        .log_err()
 7517                        .flatten()
 7518                        .map(|response| response.payload)
 7519                        .unwrap_or_default()
 7520                        .into_iter()
 7521                        .map(|color_response| {
 7522                            let response = request.response_from_proto(
 7523                                color_response.response,
 7524                                lsp_store.clone(),
 7525                                buffer.clone(),
 7526                                cx.clone(),
 7527                            );
 7528                            async move {
 7529                                (
 7530                                    LanguageServerId::from_proto(color_response.server_id),
 7531                                    response.await.log_err().unwrap_or_default(),
 7532                                )
 7533                            }
 7534                        }),
 7535                )
 7536                .await
 7537                .into_iter()
 7538                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7539                    acc.entry(server_id)
 7540                        .or_insert_with(HashSet::default)
 7541                        .extend(colors);
 7542                    acc
 7543                });
 7544                Ok(Some(colors))
 7545            })
 7546        } else {
 7547            let document_colors_task =
 7548                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7549            cx.background_spawn(async move {
 7550                Ok(Some(
 7551                    document_colors_task
 7552                        .await
 7553                        .into_iter()
 7554                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7555                            acc.entry(server_id)
 7556                                .or_insert_with(HashSet::default)
 7557                                .extend(colors);
 7558                            acc
 7559                        })
 7560                        .into_iter()
 7561                        .collect(),
 7562                ))
 7563            })
 7564        }
 7565    }
 7566
 7567    pub fn signature_help<T: ToPointUtf16>(
 7568        &mut self,
 7569        buffer: &Entity<Buffer>,
 7570        position: T,
 7571        cx: &mut Context<Self>,
 7572    ) -> Task<Option<Vec<SignatureHelp>>> {
 7573        let position = position.to_point_utf16(buffer.read(cx));
 7574
 7575        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7576            let request = GetSignatureHelp { position };
 7577            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7578                return Task::ready(None);
 7579            }
 7580            let request_task = client.request_lsp(
 7581                upstream_project_id,
 7582                None,
 7583                LSP_REQUEST_TIMEOUT,
 7584                cx.background_executor().clone(),
 7585                request.to_proto(upstream_project_id, buffer.read(cx)),
 7586            );
 7587            let buffer = buffer.clone();
 7588            cx.spawn(async move |weak_lsp_store, cx| {
 7589                let lsp_store = weak_lsp_store.upgrade()?;
 7590                let signatures = join_all(
 7591                    request_task
 7592                        .await
 7593                        .log_err()
 7594                        .flatten()
 7595                        .map(|response| response.payload)
 7596                        .unwrap_or_default()
 7597                        .into_iter()
 7598                        .map(|response| {
 7599                            let response = GetSignatureHelp { position }.response_from_proto(
 7600                                response.response,
 7601                                lsp_store.clone(),
 7602                                buffer.clone(),
 7603                                cx.clone(),
 7604                            );
 7605                            async move { response.await.log_err().flatten() }
 7606                        }),
 7607                )
 7608                .await
 7609                .into_iter()
 7610                .flatten()
 7611                .collect();
 7612                Some(signatures)
 7613            })
 7614        } else {
 7615            let all_actions_task = self.request_multiple_lsp_locally(
 7616                buffer,
 7617                Some(position),
 7618                GetSignatureHelp { position },
 7619                cx,
 7620            );
 7621            cx.background_spawn(async move {
 7622                Some(
 7623                    all_actions_task
 7624                        .await
 7625                        .into_iter()
 7626                        .flat_map(|(_, actions)| actions)
 7627                        .collect::<Vec<_>>(),
 7628                )
 7629            })
 7630        }
 7631    }
 7632
 7633    pub fn hover(
 7634        &mut self,
 7635        buffer: &Entity<Buffer>,
 7636        position: PointUtf16,
 7637        cx: &mut Context<Self>,
 7638    ) -> Task<Option<Vec<Hover>>> {
 7639        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7640            let request = GetHover { position };
 7641            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7642                return Task::ready(None);
 7643            }
 7644            let request_task = client.request_lsp(
 7645                upstream_project_id,
 7646                None,
 7647                LSP_REQUEST_TIMEOUT,
 7648                cx.background_executor().clone(),
 7649                request.to_proto(upstream_project_id, buffer.read(cx)),
 7650            );
 7651            let buffer = buffer.clone();
 7652            cx.spawn(async move |weak_lsp_store, cx| {
 7653                let lsp_store = weak_lsp_store.upgrade()?;
 7654                let hovers = join_all(
 7655                    request_task
 7656                        .await
 7657                        .log_err()
 7658                        .flatten()
 7659                        .map(|response| response.payload)
 7660                        .unwrap_or_default()
 7661                        .into_iter()
 7662                        .map(|response| {
 7663                            let response = GetHover { position }.response_from_proto(
 7664                                response.response,
 7665                                lsp_store.clone(),
 7666                                buffer.clone(),
 7667                                cx.clone(),
 7668                            );
 7669                            async move {
 7670                                response
 7671                                    .await
 7672                                    .log_err()
 7673                                    .flatten()
 7674                                    .and_then(remove_empty_hover_blocks)
 7675                            }
 7676                        }),
 7677                )
 7678                .await
 7679                .into_iter()
 7680                .flatten()
 7681                .collect();
 7682                Some(hovers)
 7683            })
 7684        } else {
 7685            let all_actions_task = self.request_multiple_lsp_locally(
 7686                buffer,
 7687                Some(position),
 7688                GetHover { position },
 7689                cx,
 7690            );
 7691            cx.background_spawn(async move {
 7692                Some(
 7693                    all_actions_task
 7694                        .await
 7695                        .into_iter()
 7696                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7697                        .collect::<Vec<Hover>>(),
 7698                )
 7699            })
 7700        }
 7701    }
 7702
 7703    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7704        let language_registry = self.languages.clone();
 7705
 7706        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7707            let request = upstream_client.request(proto::GetProjectSymbols {
 7708                project_id: *project_id,
 7709                query: query.to_string(),
 7710            });
 7711            cx.foreground_executor().spawn(async move {
 7712                let response = request.await?;
 7713                let mut symbols = Vec::new();
 7714                let core_symbols = response
 7715                    .symbols
 7716                    .into_iter()
 7717                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7718                    .collect::<Vec<_>>();
 7719                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7720                    .await;
 7721                Ok(symbols)
 7722            })
 7723        } else if let Some(local) = self.as_local() {
 7724            struct WorkspaceSymbolsResult {
 7725                server_id: LanguageServerId,
 7726                lsp_adapter: Arc<CachedLspAdapter>,
 7727                worktree: WeakEntity<Worktree>,
 7728                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7729            }
 7730
 7731            let mut requests = Vec::new();
 7732            let mut requested_servers = BTreeSet::new();
 7733            for (seed, state) in local.language_server_ids.iter() {
 7734                let Some(worktree_handle) = self
 7735                    .worktree_store
 7736                    .read(cx)
 7737                    .worktree_for_id(seed.worktree_id, cx)
 7738                else {
 7739                    continue;
 7740                };
 7741                let worktree = worktree_handle.read(cx);
 7742                if !worktree.is_visible() {
 7743                    continue;
 7744                }
 7745
 7746                if !requested_servers.insert(state.id) {
 7747                    continue;
 7748                }
 7749
 7750                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7751                    Some(LanguageServerState::Running {
 7752                        adapter, server, ..
 7753                    }) => (adapter.clone(), server),
 7754
 7755                    _ => continue,
 7756                };
 7757                let supports_workspace_symbol_request =
 7758                    match server.capabilities().workspace_symbol_provider {
 7759                        Some(OneOf::Left(supported)) => supported,
 7760                        Some(OneOf::Right(_)) => true,
 7761                        None => false,
 7762                    };
 7763                if !supports_workspace_symbol_request {
 7764                    continue;
 7765                }
 7766                let worktree_handle = worktree_handle.clone();
 7767                let server_id = server.server_id();
 7768                requests.push(
 7769                        server
 7770                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7771                                lsp::WorkspaceSymbolParams {
 7772                                    query: query.to_string(),
 7773                                    ..Default::default()
 7774                                },
 7775                            )
 7776                            .map(move |response| {
 7777                                let lsp_symbols = response.into_response()
 7778                                    .context("workspace symbols request")
 7779                                    .log_err()
 7780                                    .flatten()
 7781                                    .map(|symbol_response| match symbol_response {
 7782                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7783                                            flat_responses.into_iter().map(|lsp_symbol| {
 7784                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7785                                            }).collect::<Vec<_>>()
 7786                                        }
 7787                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7788                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7789                                                let location = match lsp_symbol.location {
 7790                                                    OneOf::Left(location) => location,
 7791                                                    OneOf::Right(_) => {
 7792                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7793                                                        return None
 7794                                                    }
 7795                                                };
 7796                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7797                                            }).collect::<Vec<_>>()
 7798                                        }
 7799                                    }).unwrap_or_default();
 7800
 7801                                WorkspaceSymbolsResult {
 7802                                    server_id,
 7803                                    lsp_adapter,
 7804                                    worktree: worktree_handle.downgrade(),
 7805                                    lsp_symbols,
 7806                                }
 7807                            }),
 7808                    );
 7809            }
 7810
 7811            cx.spawn(async move |this, cx| {
 7812                let responses = futures::future::join_all(requests).await;
 7813                let this = match this.upgrade() {
 7814                    Some(this) => this,
 7815                    None => return Ok(Vec::new()),
 7816                };
 7817
 7818                let mut symbols = Vec::new();
 7819                for result in responses {
 7820                    let core_symbols = this.update(cx, |this, cx| {
 7821                        result
 7822                            .lsp_symbols
 7823                            .into_iter()
 7824                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7825                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7826                                let source_worktree = result.worktree.upgrade()?;
 7827                                let source_worktree_id = source_worktree.read(cx).id();
 7828
 7829                                let path = if let Some((tree, rel_path)) =
 7830                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7831                                {
 7832                                    let worktree_id = tree.read(cx).id();
 7833                                    SymbolLocation::InProject(ProjectPath {
 7834                                        worktree_id,
 7835                                        path: rel_path,
 7836                                    })
 7837                                } else {
 7838                                    SymbolLocation::OutsideProject {
 7839                                        signature: this.symbol_signature(&abs_path),
 7840                                        abs_path: abs_path.into(),
 7841                                    }
 7842                                };
 7843
 7844                                Some(CoreSymbol {
 7845                                    source_language_server_id: result.server_id,
 7846                                    language_server_name: result.lsp_adapter.name.clone(),
 7847                                    source_worktree_id,
 7848                                    path,
 7849                                    kind: symbol_kind,
 7850                                    name: symbol_name,
 7851                                    range: range_from_lsp(symbol_location.range),
 7852                                })
 7853                            })
 7854                            .collect()
 7855                    })?;
 7856
 7857                    populate_labels_for_symbols(
 7858                        core_symbols,
 7859                        &language_registry,
 7860                        Some(result.lsp_adapter),
 7861                        &mut symbols,
 7862                    )
 7863                    .await;
 7864                }
 7865
 7866                Ok(symbols)
 7867            })
 7868        } else {
 7869            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7870        }
 7871    }
 7872
 7873    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7874        let mut summary = DiagnosticSummary::default();
 7875        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7876            summary.error_count += path_summary.error_count;
 7877            summary.warning_count += path_summary.warning_count;
 7878        }
 7879        summary
 7880    }
 7881
 7882    /// Returns the diagnostic summary for a specific project path.
 7883    pub fn diagnostic_summary_for_path(
 7884        &self,
 7885        project_path: &ProjectPath,
 7886        _: &App,
 7887    ) -> DiagnosticSummary {
 7888        if let Some(summaries) = self
 7889            .diagnostic_summaries
 7890            .get(&project_path.worktree_id)
 7891            .and_then(|map| map.get(&project_path.path))
 7892        {
 7893            let (error_count, warning_count) = summaries.iter().fold(
 7894                (0, 0),
 7895                |(error_count, warning_count), (_language_server_id, summary)| {
 7896                    (
 7897                        error_count + summary.error_count,
 7898                        warning_count + summary.warning_count,
 7899                    )
 7900                },
 7901            );
 7902
 7903            DiagnosticSummary {
 7904                error_count,
 7905                warning_count,
 7906            }
 7907        } else {
 7908            DiagnosticSummary::default()
 7909        }
 7910    }
 7911
 7912    pub fn diagnostic_summaries<'a>(
 7913        &'a self,
 7914        include_ignored: bool,
 7915        cx: &'a App,
 7916    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7917        self.worktree_store
 7918            .read(cx)
 7919            .visible_worktrees(cx)
 7920            .filter_map(|worktree| {
 7921                let worktree = worktree.read(cx);
 7922                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7923            })
 7924            .flat_map(move |(worktree, summaries)| {
 7925                let worktree_id = worktree.id();
 7926                summaries
 7927                    .iter()
 7928                    .filter(move |(path, _)| {
 7929                        include_ignored
 7930                            || worktree
 7931                                .entry_for_path(path.as_ref())
 7932                                .is_some_and(|entry| !entry.is_ignored)
 7933                    })
 7934                    .flat_map(move |(path, summaries)| {
 7935                        summaries.iter().map(move |(server_id, summary)| {
 7936                            (
 7937                                ProjectPath {
 7938                                    worktree_id,
 7939                                    path: path.clone(),
 7940                                },
 7941                                *server_id,
 7942                                *summary,
 7943                            )
 7944                        })
 7945                    })
 7946            })
 7947    }
 7948
 7949    pub fn on_buffer_edited(
 7950        &mut self,
 7951        buffer: Entity<Buffer>,
 7952        cx: &mut Context<Self>,
 7953    ) -> Option<()> {
 7954        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7955            Some(
 7956                self.as_local()?
 7957                    .language_servers_for_buffer(buffer, cx)
 7958                    .map(|i| i.1.clone())
 7959                    .collect(),
 7960            )
 7961        })?;
 7962
 7963        let buffer = buffer.read(cx);
 7964        let file = File::from_dyn(buffer.file())?;
 7965        let abs_path = file.as_local()?.abs_path(cx);
 7966        let uri = lsp::Uri::from_file_path(&abs_path)
 7967            .ok()
 7968            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7969            .log_err()?;
 7970        let next_snapshot = buffer.text_snapshot();
 7971        for language_server in language_servers {
 7972            let language_server = language_server.clone();
 7973
 7974            let buffer_snapshots = self
 7975                .as_local_mut()?
 7976                .buffer_snapshots
 7977                .get_mut(&buffer.remote_id())
 7978                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7979            let previous_snapshot = buffer_snapshots.last()?;
 7980
 7981            let build_incremental_change = || {
 7982                buffer
 7983                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7984                        previous_snapshot.snapshot.version(),
 7985                    )
 7986                    .map(|edit| {
 7987                        let edit_start = edit.new.start.0;
 7988                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7989                        let new_text = next_snapshot
 7990                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7991                            .collect();
 7992                        lsp::TextDocumentContentChangeEvent {
 7993                            range: Some(lsp::Range::new(
 7994                                point_to_lsp(edit_start),
 7995                                point_to_lsp(edit_end),
 7996                            )),
 7997                            range_length: None,
 7998                            text: new_text,
 7999                        }
 8000                    })
 8001                    .collect()
 8002            };
 8003
 8004            let document_sync_kind = language_server
 8005                .capabilities()
 8006                .text_document_sync
 8007                .as_ref()
 8008                .and_then(|sync| match sync {
 8009                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 8010                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 8011                });
 8012
 8013            let content_changes: Vec<_> = match document_sync_kind {
 8014                Some(lsp::TextDocumentSyncKind::FULL) => {
 8015                    vec![lsp::TextDocumentContentChangeEvent {
 8016                        range: None,
 8017                        range_length: None,
 8018                        text: next_snapshot.text(),
 8019                    }]
 8020                }
 8021                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8022                _ => {
 8023                    #[cfg(any(test, feature = "test-support"))]
 8024                    {
 8025                        build_incremental_change()
 8026                    }
 8027
 8028                    #[cfg(not(any(test, feature = "test-support")))]
 8029                    {
 8030                        continue;
 8031                    }
 8032                }
 8033            };
 8034
 8035            let next_version = previous_snapshot.version + 1;
 8036            buffer_snapshots.push(LspBufferSnapshot {
 8037                version: next_version,
 8038                snapshot: next_snapshot.clone(),
 8039            });
 8040
 8041            language_server
 8042                .notify::<lsp::notification::DidChangeTextDocument>(
 8043                    lsp::DidChangeTextDocumentParams {
 8044                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8045                            uri.clone(),
 8046                            next_version,
 8047                        ),
 8048                        content_changes,
 8049                    },
 8050                )
 8051                .ok();
 8052            self.pull_workspace_diagnostics(language_server.server_id());
 8053        }
 8054
 8055        None
 8056    }
 8057
 8058    pub fn on_buffer_saved(
 8059        &mut self,
 8060        buffer: Entity<Buffer>,
 8061        cx: &mut Context<Self>,
 8062    ) -> Option<()> {
 8063        let file = File::from_dyn(buffer.read(cx).file())?;
 8064        let worktree_id = file.worktree_id(cx);
 8065        let abs_path = file.as_local()?.abs_path(cx);
 8066        let text_document = lsp::TextDocumentIdentifier {
 8067            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8068        };
 8069        let local = self.as_local()?;
 8070
 8071        for server in local.language_servers_for_worktree(worktree_id) {
 8072            if let Some(include_text) = include_text(server.as_ref()) {
 8073                let text = if include_text {
 8074                    Some(buffer.read(cx).text())
 8075                } else {
 8076                    None
 8077                };
 8078                server
 8079                    .notify::<lsp::notification::DidSaveTextDocument>(
 8080                        lsp::DidSaveTextDocumentParams {
 8081                            text_document: text_document.clone(),
 8082                            text,
 8083                        },
 8084                    )
 8085                    .ok();
 8086            }
 8087        }
 8088
 8089        let language_servers = buffer.update(cx, |buffer, cx| {
 8090            local.language_server_ids_for_buffer(buffer, cx)
 8091        });
 8092        for language_server_id in language_servers {
 8093            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8094        }
 8095
 8096        None
 8097    }
 8098
 8099    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8100        maybe!(async move {
 8101            let mut refreshed_servers = HashSet::default();
 8102            let servers = lsp_store
 8103                .update(cx, |lsp_store, cx| {
 8104                    let local = lsp_store.as_local()?;
 8105
 8106                    let servers = local
 8107                        .language_server_ids
 8108                        .iter()
 8109                        .filter_map(|(seed, state)| {
 8110                            let worktree = lsp_store
 8111                                .worktree_store
 8112                                .read(cx)
 8113                                .worktree_for_id(seed.worktree_id, cx);
 8114                            let delegate: Arc<dyn LspAdapterDelegate> =
 8115                                worktree.map(|worktree| {
 8116                                    LocalLspAdapterDelegate::new(
 8117                                        local.languages.clone(),
 8118                                        &local.environment,
 8119                                        cx.weak_entity(),
 8120                                        &worktree,
 8121                                        local.http_client.clone(),
 8122                                        local.fs.clone(),
 8123                                        cx,
 8124                                    )
 8125                                })?;
 8126                            let server_id = state.id;
 8127
 8128                            let states = local.language_servers.get(&server_id)?;
 8129
 8130                            match states {
 8131                                LanguageServerState::Starting { .. } => None,
 8132                                LanguageServerState::Running {
 8133                                    adapter, server, ..
 8134                                } => {
 8135                                    let adapter = adapter.clone();
 8136                                    let server = server.clone();
 8137                                    refreshed_servers.insert(server.name());
 8138                                    let toolchain = seed.toolchain.clone();
 8139                                    Some(cx.spawn(async move |_, cx| {
 8140                                        let settings =
 8141                                            LocalLspStore::workspace_configuration_for_adapter(
 8142                                                adapter.adapter.clone(),
 8143                                                &delegate,
 8144                                                toolchain,
 8145                                                None,
 8146                                                cx,
 8147                                            )
 8148                                            .await
 8149                                            .ok()?;
 8150                                        server
 8151                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8152                                                lsp::DidChangeConfigurationParams { settings },
 8153                                            )
 8154                                            .ok()?;
 8155                                        Some(())
 8156                                    }))
 8157                                }
 8158                            }
 8159                        })
 8160                        .collect::<Vec<_>>();
 8161
 8162                    Some(servers)
 8163                })
 8164                .ok()
 8165                .flatten()?;
 8166
 8167            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8168            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8169            // to stop and unregister its language server wrapper.
 8170            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8171            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8172            let _: Vec<Option<()>> = join_all(servers).await;
 8173
 8174            Some(())
 8175        })
 8176        .await;
 8177    }
 8178
 8179    fn maintain_workspace_config(
 8180        external_refresh_requests: watch::Receiver<()>,
 8181        cx: &mut Context<Self>,
 8182    ) -> Task<Result<()>> {
 8183        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8184        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8185
 8186        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8187            *settings_changed_tx.borrow_mut() = ();
 8188        });
 8189
 8190        let mut joint_future =
 8191            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8192        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8193        // - 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).
 8194        // - 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.
 8195        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8196        // - 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,
 8197        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8198        cx.spawn(async move |this, cx| {
 8199            while let Some(()) = joint_future.next().await {
 8200                this.update(cx, |this, cx| {
 8201                    this.refresh_server_tree(cx);
 8202                })
 8203                .ok();
 8204
 8205                Self::refresh_workspace_configurations(&this, cx).await;
 8206            }
 8207
 8208            drop(settings_observation);
 8209            anyhow::Ok(())
 8210        })
 8211    }
 8212
 8213    pub fn running_language_servers_for_local_buffer<'a>(
 8214        &'a self,
 8215        buffer: &Buffer,
 8216        cx: &mut App,
 8217    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8218        let local = self.as_local();
 8219        let language_server_ids = local
 8220            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8221            .unwrap_or_default();
 8222
 8223        language_server_ids
 8224            .into_iter()
 8225            .filter_map(
 8226                move |server_id| match local?.language_servers.get(&server_id)? {
 8227                    LanguageServerState::Running {
 8228                        adapter, server, ..
 8229                    } => Some((adapter, server)),
 8230                    _ => None,
 8231                },
 8232            )
 8233    }
 8234
 8235    pub fn language_servers_for_local_buffer(
 8236        &self,
 8237        buffer: &Buffer,
 8238        cx: &mut App,
 8239    ) -> Vec<LanguageServerId> {
 8240        let local = self.as_local();
 8241        local
 8242            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8243            .unwrap_or_default()
 8244    }
 8245
 8246    pub fn language_server_for_local_buffer<'a>(
 8247        &'a self,
 8248        buffer: &'a Buffer,
 8249        server_id: LanguageServerId,
 8250        cx: &'a mut App,
 8251    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8252        self.as_local()?
 8253            .language_servers_for_buffer(buffer, cx)
 8254            .find(|(_, s)| s.server_id() == server_id)
 8255    }
 8256
 8257    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8258        self.diagnostic_summaries.remove(&id_to_remove);
 8259        if let Some(local) = self.as_local_mut() {
 8260            let to_remove = local.remove_worktree(id_to_remove, cx);
 8261            for server in to_remove {
 8262                self.language_server_statuses.remove(&server);
 8263            }
 8264        }
 8265    }
 8266
 8267    pub fn shared(
 8268        &mut self,
 8269        project_id: u64,
 8270        downstream_client: AnyProtoClient,
 8271        _: &mut Context<Self>,
 8272    ) {
 8273        self.downstream_client = Some((downstream_client.clone(), project_id));
 8274
 8275        for (server_id, status) in &self.language_server_statuses {
 8276            if let Some(server) = self.language_server_for_id(*server_id) {
 8277                downstream_client
 8278                    .send(proto::StartLanguageServer {
 8279                        project_id,
 8280                        server: Some(proto::LanguageServer {
 8281                            id: server_id.to_proto(),
 8282                            name: status.name.to_string(),
 8283                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8284                        }),
 8285                        capabilities: serde_json::to_string(&server.capabilities())
 8286                            .expect("serializing server LSP capabilities"),
 8287                    })
 8288                    .log_err();
 8289            }
 8290        }
 8291    }
 8292
 8293    pub fn disconnected_from_host(&mut self) {
 8294        self.downstream_client.take();
 8295    }
 8296
 8297    pub fn disconnected_from_ssh_remote(&mut self) {
 8298        if let LspStoreMode::Remote(RemoteLspStore {
 8299            upstream_client, ..
 8300        }) = &mut self.mode
 8301        {
 8302            upstream_client.take();
 8303        }
 8304    }
 8305
 8306    pub(crate) fn set_language_server_statuses_from_proto(
 8307        &mut self,
 8308        project: WeakEntity<Project>,
 8309        language_servers: Vec<proto::LanguageServer>,
 8310        server_capabilities: Vec<String>,
 8311        cx: &mut Context<Self>,
 8312    ) {
 8313        let lsp_logs = cx
 8314            .try_global::<GlobalLogStore>()
 8315            .map(|lsp_store| lsp_store.0.clone());
 8316
 8317        self.language_server_statuses = language_servers
 8318            .into_iter()
 8319            .zip(server_capabilities)
 8320            .map(|(server, server_capabilities)| {
 8321                let server_id = LanguageServerId(server.id as usize);
 8322                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8323                    self.lsp_server_capabilities
 8324                        .insert(server_id, server_capabilities);
 8325                }
 8326
 8327                let name = LanguageServerName::from_proto(server.name);
 8328                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8329
 8330                if let Some(lsp_logs) = &lsp_logs {
 8331                    lsp_logs.update(cx, |lsp_logs, cx| {
 8332                        lsp_logs.add_language_server(
 8333                            // Only remote clients get their language servers set from proto
 8334                            LanguageServerKind::Remote {
 8335                                project: project.clone(),
 8336                            },
 8337                            server_id,
 8338                            Some(name.clone()),
 8339                            worktree,
 8340                            None,
 8341                            cx,
 8342                        );
 8343                    });
 8344                }
 8345
 8346                (
 8347                    server_id,
 8348                    LanguageServerStatus {
 8349                        name,
 8350                        pending_work: Default::default(),
 8351                        has_pending_diagnostic_updates: false,
 8352                        progress_tokens: Default::default(),
 8353                        worktree,
 8354                        binary: None,
 8355                        configuration: None,
 8356                        workspace_folders: BTreeSet::new(),
 8357                    },
 8358                )
 8359            })
 8360            .collect();
 8361    }
 8362
 8363    #[cfg(test)]
 8364    pub fn update_diagnostic_entries(
 8365        &mut self,
 8366        server_id: LanguageServerId,
 8367        abs_path: PathBuf,
 8368        result_id: Option<SharedString>,
 8369        version: Option<i32>,
 8370        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8371        cx: &mut Context<Self>,
 8372    ) -> anyhow::Result<()> {
 8373        self.merge_diagnostic_entries(
 8374            vec![DocumentDiagnosticsUpdate {
 8375                diagnostics: DocumentDiagnostics {
 8376                    diagnostics,
 8377                    document_abs_path: abs_path,
 8378                    version,
 8379                },
 8380                result_id,
 8381                server_id,
 8382                disk_based_sources: Cow::Borrowed(&[]),
 8383                registration_id: None,
 8384            }],
 8385            |_, _, _| false,
 8386            cx,
 8387        )?;
 8388        Ok(())
 8389    }
 8390
 8391    pub fn merge_diagnostic_entries<'a>(
 8392        &mut self,
 8393        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8394        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8395        cx: &mut Context<Self>,
 8396    ) -> anyhow::Result<()> {
 8397        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8398        let mut updated_diagnostics_paths = HashMap::default();
 8399        for mut update in diagnostic_updates {
 8400            let abs_path = &update.diagnostics.document_abs_path;
 8401            let server_id = update.server_id;
 8402            let Some((worktree, relative_path)) =
 8403                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8404            else {
 8405                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8406                return Ok(());
 8407            };
 8408
 8409            let worktree_id = worktree.read(cx).id();
 8410            let project_path = ProjectPath {
 8411                worktree_id,
 8412                path: relative_path,
 8413            };
 8414
 8415            let document_uri = lsp::Uri::from_file_path(abs_path)
 8416                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8417            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8418                let snapshot = buffer_handle.read(cx).snapshot();
 8419                let buffer = buffer_handle.read(cx);
 8420                let reused_diagnostics = buffer
 8421                    .buffer_diagnostics(Some(server_id))
 8422                    .iter()
 8423                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8424                    .map(|v| {
 8425                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8426                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8427                        DiagnosticEntry {
 8428                            range: start..end,
 8429                            diagnostic: v.diagnostic.clone(),
 8430                        }
 8431                    })
 8432                    .collect::<Vec<_>>();
 8433
 8434                self.as_local_mut()
 8435                    .context("cannot merge diagnostics on a remote LspStore")?
 8436                    .update_buffer_diagnostics(
 8437                        &buffer_handle,
 8438                        server_id,
 8439                        Some(update.registration_id),
 8440                        update.result_id,
 8441                        update.diagnostics.version,
 8442                        update.diagnostics.diagnostics.clone(),
 8443                        reused_diagnostics.clone(),
 8444                        cx,
 8445                    )?;
 8446
 8447                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8448            } else if let Some(local) = self.as_local() {
 8449                let reused_diagnostics = local
 8450                    .diagnostics
 8451                    .get(&worktree_id)
 8452                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8453                    .and_then(|diagnostics_by_server_id| {
 8454                        diagnostics_by_server_id
 8455                            .binary_search_by_key(&server_id, |e| e.0)
 8456                            .ok()
 8457                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8458                    })
 8459                    .into_iter()
 8460                    .flatten()
 8461                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8462
 8463                update
 8464                    .diagnostics
 8465                    .diagnostics
 8466                    .extend(reused_diagnostics.cloned());
 8467            }
 8468
 8469            let updated = worktree.update(cx, |worktree, cx| {
 8470                self.update_worktree_diagnostics(
 8471                    worktree.id(),
 8472                    server_id,
 8473                    project_path.path.clone(),
 8474                    update.diagnostics.diagnostics,
 8475                    cx,
 8476                )
 8477            })?;
 8478            match updated {
 8479                ControlFlow::Continue(new_summary) => {
 8480                    if let Some((project_id, new_summary)) = new_summary {
 8481                        match &mut diagnostics_summary {
 8482                            Some(diagnostics_summary) => {
 8483                                diagnostics_summary
 8484                                    .more_summaries
 8485                                    .push(proto::DiagnosticSummary {
 8486                                        path: project_path.path.as_ref().to_proto(),
 8487                                        language_server_id: server_id.0 as u64,
 8488                                        error_count: new_summary.error_count,
 8489                                        warning_count: new_summary.warning_count,
 8490                                    })
 8491                            }
 8492                            None => {
 8493                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8494                                    project_id,
 8495                                    worktree_id: worktree_id.to_proto(),
 8496                                    summary: Some(proto::DiagnosticSummary {
 8497                                        path: project_path.path.as_ref().to_proto(),
 8498                                        language_server_id: server_id.0 as u64,
 8499                                        error_count: new_summary.error_count,
 8500                                        warning_count: new_summary.warning_count,
 8501                                    }),
 8502                                    more_summaries: Vec::new(),
 8503                                })
 8504                            }
 8505                        }
 8506                    }
 8507                    updated_diagnostics_paths
 8508                        .entry(server_id)
 8509                        .or_insert_with(Vec::new)
 8510                        .push(project_path);
 8511                }
 8512                ControlFlow::Break(()) => {}
 8513            }
 8514        }
 8515
 8516        if let Some((diagnostics_summary, (downstream_client, _))) =
 8517            diagnostics_summary.zip(self.downstream_client.as_ref())
 8518        {
 8519            downstream_client.send(diagnostics_summary).log_err();
 8520        }
 8521        for (server_id, paths) in updated_diagnostics_paths {
 8522            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8523        }
 8524        Ok(())
 8525    }
 8526
 8527    fn update_worktree_diagnostics(
 8528        &mut self,
 8529        worktree_id: WorktreeId,
 8530        server_id: LanguageServerId,
 8531        path_in_worktree: Arc<RelPath>,
 8532        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8533        _: &mut Context<Worktree>,
 8534    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8535        let local = match &mut self.mode {
 8536            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8537            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8538        };
 8539
 8540        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8541        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8542        let summaries_by_server_id = summaries_for_tree
 8543            .entry(path_in_worktree.clone())
 8544            .or_default();
 8545
 8546        let old_summary = summaries_by_server_id
 8547            .remove(&server_id)
 8548            .unwrap_or_default();
 8549
 8550        let new_summary = DiagnosticSummary::new(&diagnostics);
 8551        if diagnostics.is_empty() {
 8552            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8553            {
 8554                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8555                    diagnostics_by_server_id.remove(ix);
 8556                }
 8557                if diagnostics_by_server_id.is_empty() {
 8558                    diagnostics_for_tree.remove(&path_in_worktree);
 8559                }
 8560            }
 8561        } else {
 8562            summaries_by_server_id.insert(server_id, new_summary);
 8563            let diagnostics_by_server_id = diagnostics_for_tree
 8564                .entry(path_in_worktree.clone())
 8565                .or_default();
 8566            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8567                Ok(ix) => {
 8568                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8569                }
 8570                Err(ix) => {
 8571                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8572                }
 8573            }
 8574        }
 8575
 8576        if !old_summary.is_empty() || !new_summary.is_empty() {
 8577            if let Some((_, project_id)) = &self.downstream_client {
 8578                Ok(ControlFlow::Continue(Some((
 8579                    *project_id,
 8580                    proto::DiagnosticSummary {
 8581                        path: path_in_worktree.to_proto(),
 8582                        language_server_id: server_id.0 as u64,
 8583                        error_count: new_summary.error_count as u32,
 8584                        warning_count: new_summary.warning_count as u32,
 8585                    },
 8586                ))))
 8587            } else {
 8588                Ok(ControlFlow::Continue(None))
 8589            }
 8590        } else {
 8591            Ok(ControlFlow::Break(()))
 8592        }
 8593    }
 8594
 8595    pub fn open_buffer_for_symbol(
 8596        &mut self,
 8597        symbol: &Symbol,
 8598        cx: &mut Context<Self>,
 8599    ) -> Task<Result<Entity<Buffer>>> {
 8600        if let Some((client, project_id)) = self.upstream_client() {
 8601            let request = client.request(proto::OpenBufferForSymbol {
 8602                project_id,
 8603                symbol: Some(Self::serialize_symbol(symbol)),
 8604            });
 8605            cx.spawn(async move |this, cx| {
 8606                let response = request.await?;
 8607                let buffer_id = BufferId::new(response.buffer_id)?;
 8608                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8609                    .await
 8610            })
 8611        } else if let Some(local) = self.as_local() {
 8612            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8613                seed.worktree_id == symbol.source_worktree_id
 8614                    && state.id == symbol.source_language_server_id
 8615                    && symbol.language_server_name == seed.name
 8616            });
 8617            if !is_valid {
 8618                return Task::ready(Err(anyhow!(
 8619                    "language server for worktree and language not found"
 8620                )));
 8621            };
 8622
 8623            let symbol_abs_path = match &symbol.path {
 8624                SymbolLocation::InProject(project_path) => self
 8625                    .worktree_store
 8626                    .read(cx)
 8627                    .absolutize(&project_path, cx)
 8628                    .context("no such worktree"),
 8629                SymbolLocation::OutsideProject {
 8630                    abs_path,
 8631                    signature: _,
 8632                } => Ok(abs_path.to_path_buf()),
 8633            };
 8634            let symbol_abs_path = match symbol_abs_path {
 8635                Ok(abs_path) => abs_path,
 8636                Err(err) => return Task::ready(Err(err)),
 8637            };
 8638            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8639                uri
 8640            } else {
 8641                return Task::ready(Err(anyhow!("invalid symbol path")));
 8642            };
 8643
 8644            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8645        } else {
 8646            Task::ready(Err(anyhow!("no upstream client or local store")))
 8647        }
 8648    }
 8649
 8650    pub(crate) fn open_local_buffer_via_lsp(
 8651        &mut self,
 8652        abs_path: lsp::Uri,
 8653        language_server_id: LanguageServerId,
 8654        cx: &mut Context<Self>,
 8655    ) -> Task<Result<Entity<Buffer>>> {
 8656        cx.spawn(async move |lsp_store, cx| {
 8657            // Escape percent-encoded string.
 8658            let current_scheme = abs_path.scheme().to_owned();
 8659            // Uri is immutable, so we can't modify the scheme
 8660
 8661            let abs_path = abs_path
 8662                .to_file_path()
 8663                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8664            let p = abs_path.clone();
 8665            let yarn_worktree = lsp_store
 8666                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8667                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8668                        cx.spawn(async move |this, cx| {
 8669                            let t = this
 8670                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8671                                .ok()?;
 8672                            t.await
 8673                        })
 8674                    }),
 8675                    None => Task::ready(None),
 8676                })?
 8677                .await;
 8678            let (worktree_root_target, known_relative_path) =
 8679                if let Some((zip_root, relative_path)) = yarn_worktree {
 8680                    (zip_root, Some(relative_path))
 8681                } else {
 8682                    (Arc::<Path>::from(abs_path.as_path()), None)
 8683                };
 8684            let (worktree, relative_path) = if let Some(result) =
 8685                lsp_store.update(cx, |lsp_store, cx| {
 8686                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8687                        worktree_store.find_worktree(&worktree_root_target, cx)
 8688                    })
 8689                })? {
 8690                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8691                (result.0, relative_path)
 8692            } else {
 8693                let worktree = lsp_store
 8694                    .update(cx, |lsp_store, cx| {
 8695                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8696                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8697                        })
 8698                    })?
 8699                    .await?;
 8700                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8701                    lsp_store
 8702                        .update(cx, |lsp_store, cx| {
 8703                            if let Some(local) = lsp_store.as_local_mut() {
 8704                                local.register_language_server_for_invisible_worktree(
 8705                                    &worktree,
 8706                                    language_server_id,
 8707                                    cx,
 8708                                )
 8709                            }
 8710                        })
 8711                        .ok();
 8712                }
 8713                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8714                let relative_path = if let Some(known_path) = known_relative_path {
 8715                    known_path
 8716                } else {
 8717                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8718                        .into_arc()
 8719                };
 8720                (worktree, relative_path)
 8721            };
 8722            let project_path = ProjectPath {
 8723                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8724                path: relative_path,
 8725            };
 8726            lsp_store
 8727                .update(cx, |lsp_store, cx| {
 8728                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8729                        buffer_store.open_buffer(project_path, cx)
 8730                    })
 8731                })?
 8732                .await
 8733        })
 8734    }
 8735
 8736    fn request_multiple_lsp_locally<P, R>(
 8737        &mut self,
 8738        buffer: &Entity<Buffer>,
 8739        position: Option<P>,
 8740        request: R,
 8741        cx: &mut Context<Self>,
 8742    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8743    where
 8744        P: ToOffset,
 8745        R: LspCommand + Clone,
 8746        <R::LspRequest as lsp::request::Request>::Result: Send,
 8747        <R::LspRequest as lsp::request::Request>::Params: Send,
 8748    {
 8749        let Some(local) = self.as_local() else {
 8750            return Task::ready(Vec::new());
 8751        };
 8752
 8753        let snapshot = buffer.read(cx).snapshot();
 8754        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8755
 8756        let server_ids = buffer.update(cx, |buffer, cx| {
 8757            local
 8758                .language_servers_for_buffer(buffer, cx)
 8759                .filter(|(adapter, _)| {
 8760                    scope
 8761                        .as_ref()
 8762                        .map(|scope| scope.language_allowed(&adapter.name))
 8763                        .unwrap_or(true)
 8764                })
 8765                .map(|(_, server)| server.server_id())
 8766                .filter(|server_id| {
 8767                    self.as_local().is_none_or(|local| {
 8768                        local
 8769                            .buffers_opened_in_servers
 8770                            .get(&snapshot.remote_id())
 8771                            .is_some_and(|servers| servers.contains(server_id))
 8772                    })
 8773                })
 8774                .collect::<Vec<_>>()
 8775        });
 8776
 8777        let mut response_results = server_ids
 8778            .into_iter()
 8779            .map(|server_id| {
 8780                let task = self.request_lsp(
 8781                    buffer.clone(),
 8782                    LanguageServerToQuery::Other(server_id),
 8783                    request.clone(),
 8784                    cx,
 8785                );
 8786                async move { (server_id, task.await) }
 8787            })
 8788            .collect::<FuturesUnordered<_>>();
 8789
 8790        cx.background_spawn(async move {
 8791            let mut responses = Vec::with_capacity(response_results.len());
 8792            while let Some((server_id, response_result)) = response_results.next().await {
 8793                match response_result {
 8794                    Ok(response) => responses.push((server_id, response)),
 8795                    // rust-analyzer likes to error with this when its still loading up
 8796                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8797                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8798                }
 8799            }
 8800            responses
 8801        })
 8802    }
 8803
 8804    async fn handle_lsp_get_completions(
 8805        this: Entity<Self>,
 8806        envelope: TypedEnvelope<proto::GetCompletions>,
 8807        mut cx: AsyncApp,
 8808    ) -> Result<proto::GetCompletionsResponse> {
 8809        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8810
 8811        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8812        let buffer_handle = this.update(&mut cx, |this, cx| {
 8813            this.buffer_store.read(cx).get_existing(buffer_id)
 8814        })??;
 8815        let request = GetCompletions::from_proto(
 8816            envelope.payload,
 8817            this.clone(),
 8818            buffer_handle.clone(),
 8819            cx.clone(),
 8820        )
 8821        .await?;
 8822
 8823        let server_to_query = match request.server_id {
 8824            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8825            None => LanguageServerToQuery::FirstCapable,
 8826        };
 8827
 8828        let response = this
 8829            .update(&mut cx, |this, cx| {
 8830                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8831            })?
 8832            .await?;
 8833        this.update(&mut cx, |this, cx| {
 8834            Ok(GetCompletions::response_to_proto(
 8835                response,
 8836                this,
 8837                sender_id,
 8838                &buffer_handle.read(cx).version(),
 8839                cx,
 8840            ))
 8841        })?
 8842    }
 8843
 8844    async fn handle_lsp_command<T: LspCommand>(
 8845        this: Entity<Self>,
 8846        envelope: TypedEnvelope<T::ProtoRequest>,
 8847        mut cx: AsyncApp,
 8848    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8849    where
 8850        <T::LspRequest as lsp::request::Request>::Params: Send,
 8851        <T::LspRequest as lsp::request::Request>::Result: Send,
 8852    {
 8853        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8854        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8855        let buffer_handle = this.update(&mut cx, |this, cx| {
 8856            this.buffer_store.read(cx).get_existing(buffer_id)
 8857        })??;
 8858        let request = T::from_proto(
 8859            envelope.payload,
 8860            this.clone(),
 8861            buffer_handle.clone(),
 8862            cx.clone(),
 8863        )
 8864        .await?;
 8865        let response = this
 8866            .update(&mut cx, |this, cx| {
 8867                this.request_lsp(
 8868                    buffer_handle.clone(),
 8869                    LanguageServerToQuery::FirstCapable,
 8870                    request,
 8871                    cx,
 8872                )
 8873            })?
 8874            .await?;
 8875        this.update(&mut cx, |this, cx| {
 8876            Ok(T::response_to_proto(
 8877                response,
 8878                this,
 8879                sender_id,
 8880                &buffer_handle.read(cx).version(),
 8881                cx,
 8882            ))
 8883        })?
 8884    }
 8885
 8886    async fn handle_lsp_query(
 8887        lsp_store: Entity<Self>,
 8888        envelope: TypedEnvelope<proto::LspQuery>,
 8889        mut cx: AsyncApp,
 8890    ) -> Result<proto::Ack> {
 8891        use proto::lsp_query::Request;
 8892        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8893        let lsp_query = envelope.payload;
 8894        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8895        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8896        match lsp_query.request.context("invalid LSP query request")? {
 8897            Request::GetReferences(get_references) => {
 8898                let position = get_references.position.clone().and_then(deserialize_anchor);
 8899                Self::query_lsp_locally::<GetReferences>(
 8900                    lsp_store,
 8901                    server_id,
 8902                    sender_id,
 8903                    lsp_request_id,
 8904                    get_references,
 8905                    position,
 8906                    &mut cx,
 8907                )
 8908                .await?;
 8909            }
 8910            Request::GetDocumentColor(get_document_color) => {
 8911                Self::query_lsp_locally::<GetDocumentColor>(
 8912                    lsp_store,
 8913                    server_id,
 8914                    sender_id,
 8915                    lsp_request_id,
 8916                    get_document_color,
 8917                    None,
 8918                    &mut cx,
 8919                )
 8920                .await?;
 8921            }
 8922            Request::GetHover(get_hover) => {
 8923                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8924                Self::query_lsp_locally::<GetHover>(
 8925                    lsp_store,
 8926                    server_id,
 8927                    sender_id,
 8928                    lsp_request_id,
 8929                    get_hover,
 8930                    position,
 8931                    &mut cx,
 8932                )
 8933                .await?;
 8934            }
 8935            Request::GetCodeActions(get_code_actions) => {
 8936                Self::query_lsp_locally::<GetCodeActions>(
 8937                    lsp_store,
 8938                    server_id,
 8939                    sender_id,
 8940                    lsp_request_id,
 8941                    get_code_actions,
 8942                    None,
 8943                    &mut cx,
 8944                )
 8945                .await?;
 8946            }
 8947            Request::GetSignatureHelp(get_signature_help) => {
 8948                let position = get_signature_help
 8949                    .position
 8950                    .clone()
 8951                    .and_then(deserialize_anchor);
 8952                Self::query_lsp_locally::<GetSignatureHelp>(
 8953                    lsp_store,
 8954                    server_id,
 8955                    sender_id,
 8956                    lsp_request_id,
 8957                    get_signature_help,
 8958                    position,
 8959                    &mut cx,
 8960                )
 8961                .await?;
 8962            }
 8963            Request::GetCodeLens(get_code_lens) => {
 8964                Self::query_lsp_locally::<GetCodeLens>(
 8965                    lsp_store,
 8966                    server_id,
 8967                    sender_id,
 8968                    lsp_request_id,
 8969                    get_code_lens,
 8970                    None,
 8971                    &mut cx,
 8972                )
 8973                .await?;
 8974            }
 8975            Request::GetDefinition(get_definition) => {
 8976                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8977                Self::query_lsp_locally::<GetDefinitions>(
 8978                    lsp_store,
 8979                    server_id,
 8980                    sender_id,
 8981                    lsp_request_id,
 8982                    get_definition,
 8983                    position,
 8984                    &mut cx,
 8985                )
 8986                .await?;
 8987            }
 8988            Request::GetDeclaration(get_declaration) => {
 8989                let position = get_declaration
 8990                    .position
 8991                    .clone()
 8992                    .and_then(deserialize_anchor);
 8993                Self::query_lsp_locally::<GetDeclarations>(
 8994                    lsp_store,
 8995                    server_id,
 8996                    sender_id,
 8997                    lsp_request_id,
 8998                    get_declaration,
 8999                    position,
 9000                    &mut cx,
 9001                )
 9002                .await?;
 9003            }
 9004            Request::GetTypeDefinition(get_type_definition) => {
 9005                let position = get_type_definition
 9006                    .position
 9007                    .clone()
 9008                    .and_then(deserialize_anchor);
 9009                Self::query_lsp_locally::<GetTypeDefinitions>(
 9010                    lsp_store,
 9011                    server_id,
 9012                    sender_id,
 9013                    lsp_request_id,
 9014                    get_type_definition,
 9015                    position,
 9016                    &mut cx,
 9017                )
 9018                .await?;
 9019            }
 9020            Request::GetImplementation(get_implementation) => {
 9021                let position = get_implementation
 9022                    .position
 9023                    .clone()
 9024                    .and_then(deserialize_anchor);
 9025                Self::query_lsp_locally::<GetImplementations>(
 9026                    lsp_store,
 9027                    server_id,
 9028                    sender_id,
 9029                    lsp_request_id,
 9030                    get_implementation,
 9031                    position,
 9032                    &mut cx,
 9033                )
 9034                .await?;
 9035            }
 9036            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9037                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 9038                let version = deserialize_version(get_document_diagnostics.buffer_version());
 9039                let buffer = lsp_store.update(&mut cx, |this, cx| {
 9040                    this.buffer_store.read(cx).get_existing(buffer_id)
 9041                })??;
 9042                buffer
 9043                    .update(&mut cx, |buffer, _| {
 9044                        buffer.wait_for_version(version.clone())
 9045                    })?
 9046                    .await?;
 9047                lsp_store.update(&mut cx, |lsp_store, cx| {
 9048                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9049                    let key = LspKey {
 9050                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9051                        server_queried: server_id,
 9052                    };
 9053                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9054                    ) {
 9055                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9056                            lsp_requests.clear();
 9057                        };
 9058                    }
 9059
 9060                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 9061                    existing_queries.insert(
 9062                        lsp_request_id,
 9063                        cx.spawn(async move |lsp_store, cx| {
 9064                            let diagnostics_pull = lsp_store
 9065                                .update(cx, |lsp_store, cx| {
 9066                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9067                                })
 9068                                .ok();
 9069                            if let Some(diagnostics_pull) = diagnostics_pull {
 9070                                match diagnostics_pull.await {
 9071                                    Ok(()) => {}
 9072                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9073                                };
 9074                            }
 9075                        }),
 9076                    );
 9077                })?;
 9078            }
 9079            Request::InlayHints(inlay_hints) => {
 9080                let query_start = inlay_hints
 9081                    .start
 9082                    .clone()
 9083                    .and_then(deserialize_anchor)
 9084                    .context("invalid inlay hints range start")?;
 9085                let query_end = inlay_hints
 9086                    .end
 9087                    .clone()
 9088                    .and_then(deserialize_anchor)
 9089                    .context("invalid inlay hints range end")?;
 9090                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9091                    &lsp_store,
 9092                    server_id,
 9093                    lsp_request_id,
 9094                    &inlay_hints,
 9095                    query_start..query_end,
 9096                    &mut cx,
 9097                )
 9098                .await
 9099                .context("preparing inlay hints request")?;
 9100                Self::query_lsp_locally::<InlayHints>(
 9101                    lsp_store,
 9102                    server_id,
 9103                    sender_id,
 9104                    lsp_request_id,
 9105                    inlay_hints,
 9106                    None,
 9107                    &mut cx,
 9108                )
 9109                .await
 9110                .context("querying for inlay hints")?
 9111            }
 9112        }
 9113        Ok(proto::Ack {})
 9114    }
 9115
 9116    async fn handle_lsp_query_response(
 9117        lsp_store: Entity<Self>,
 9118        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9119        cx: AsyncApp,
 9120    ) -> Result<()> {
 9121        lsp_store.read_with(&cx, |lsp_store, _| {
 9122            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9123                upstream_client.handle_lsp_response(envelope.clone());
 9124            }
 9125        })?;
 9126        Ok(())
 9127    }
 9128
 9129    async fn handle_apply_code_action(
 9130        this: Entity<Self>,
 9131        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9132        mut cx: AsyncApp,
 9133    ) -> Result<proto::ApplyCodeActionResponse> {
 9134        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9135        let action =
 9136            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9137        let apply_code_action = this.update(&mut cx, |this, cx| {
 9138            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9139            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9140            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9141        })??;
 9142
 9143        let project_transaction = apply_code_action.await?;
 9144        let project_transaction = this.update(&mut cx, |this, cx| {
 9145            this.buffer_store.update(cx, |buffer_store, cx| {
 9146                buffer_store.serialize_project_transaction_for_peer(
 9147                    project_transaction,
 9148                    sender_id,
 9149                    cx,
 9150                )
 9151            })
 9152        })?;
 9153        Ok(proto::ApplyCodeActionResponse {
 9154            transaction: Some(project_transaction),
 9155        })
 9156    }
 9157
 9158    async fn handle_register_buffer_with_language_servers(
 9159        this: Entity<Self>,
 9160        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9161        mut cx: AsyncApp,
 9162    ) -> Result<proto::Ack> {
 9163        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9164        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9165        this.update(&mut cx, |this, cx| {
 9166            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9167                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9168                    project_id: upstream_project_id,
 9169                    buffer_id: buffer_id.to_proto(),
 9170                    only_servers: envelope.payload.only_servers,
 9171                });
 9172            }
 9173
 9174            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9175                anyhow::bail!("buffer is not open");
 9176            };
 9177
 9178            let handle = this.register_buffer_with_language_servers(
 9179                &buffer,
 9180                envelope
 9181                    .payload
 9182                    .only_servers
 9183                    .into_iter()
 9184                    .filter_map(|selector| {
 9185                        Some(match selector.selector? {
 9186                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9187                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9188                            }
 9189                            proto::language_server_selector::Selector::Name(name) => {
 9190                                LanguageServerSelector::Name(LanguageServerName(
 9191                                    SharedString::from(name),
 9192                                ))
 9193                            }
 9194                        })
 9195                    })
 9196                    .collect(),
 9197                false,
 9198                cx,
 9199            );
 9200            this.buffer_store().update(cx, |buffer_store, _| {
 9201                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9202            });
 9203
 9204            Ok(())
 9205        })??;
 9206        Ok(proto::Ack {})
 9207    }
 9208
 9209    async fn handle_rename_project_entry(
 9210        this: Entity<Self>,
 9211        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9212        mut cx: AsyncApp,
 9213    ) -> Result<proto::ProjectEntryResponse> {
 9214        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9215        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9216        let new_path =
 9217            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9218
 9219        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9220            .update(&mut cx, |this, cx| {
 9221                let (worktree, entry) = this
 9222                    .worktree_store
 9223                    .read(cx)
 9224                    .worktree_and_entry_for_id(entry_id, cx)?;
 9225                let new_worktree = this
 9226                    .worktree_store
 9227                    .read(cx)
 9228                    .worktree_for_id(new_worktree_id, cx)?;
 9229                Some((
 9230                    this.worktree_store.clone(),
 9231                    worktree,
 9232                    new_worktree,
 9233                    entry.clone(),
 9234                ))
 9235            })?
 9236            .context("worktree not found")?;
 9237        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9238            (worktree.absolutize(&old_entry.path), worktree.id())
 9239        })?;
 9240        let new_abs_path =
 9241            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 9242
 9243        let _transaction = Self::will_rename_entry(
 9244            this.downgrade(),
 9245            old_worktree_id,
 9246            &old_abs_path,
 9247            &new_abs_path,
 9248            old_entry.is_dir(),
 9249            cx.clone(),
 9250        )
 9251        .await;
 9252        let response = WorktreeStore::handle_rename_project_entry(
 9253            worktree_store,
 9254            envelope.payload,
 9255            cx.clone(),
 9256        )
 9257        .await;
 9258        this.read_with(&cx, |this, _| {
 9259            this.did_rename_entry(
 9260                old_worktree_id,
 9261                &old_abs_path,
 9262                &new_abs_path,
 9263                old_entry.is_dir(),
 9264            );
 9265        })
 9266        .ok();
 9267        response
 9268    }
 9269
 9270    async fn handle_update_diagnostic_summary(
 9271        this: Entity<Self>,
 9272        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9273        mut cx: AsyncApp,
 9274    ) -> Result<()> {
 9275        this.update(&mut cx, |lsp_store, cx| {
 9276            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9277            let mut updated_diagnostics_paths = HashMap::default();
 9278            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9279            for message_summary in envelope
 9280                .payload
 9281                .summary
 9282                .into_iter()
 9283                .chain(envelope.payload.more_summaries)
 9284            {
 9285                let project_path = ProjectPath {
 9286                    worktree_id,
 9287                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9288                };
 9289                let path = project_path.path.clone();
 9290                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9291                let summary = DiagnosticSummary {
 9292                    error_count: message_summary.error_count as usize,
 9293                    warning_count: message_summary.warning_count as usize,
 9294                };
 9295
 9296                if summary.is_empty() {
 9297                    if let Some(worktree_summaries) =
 9298                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9299                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9300                    {
 9301                        summaries.remove(&server_id);
 9302                        if summaries.is_empty() {
 9303                            worktree_summaries.remove(&path);
 9304                        }
 9305                    }
 9306                } else {
 9307                    lsp_store
 9308                        .diagnostic_summaries
 9309                        .entry(worktree_id)
 9310                        .or_default()
 9311                        .entry(path)
 9312                        .or_default()
 9313                        .insert(server_id, summary);
 9314                }
 9315
 9316                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9317                    match &mut diagnostics_summary {
 9318                        Some(diagnostics_summary) => {
 9319                            diagnostics_summary
 9320                                .more_summaries
 9321                                .push(proto::DiagnosticSummary {
 9322                                    path: project_path.path.as_ref().to_proto(),
 9323                                    language_server_id: server_id.0 as u64,
 9324                                    error_count: summary.error_count as u32,
 9325                                    warning_count: summary.warning_count as u32,
 9326                                })
 9327                        }
 9328                        None => {
 9329                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9330                                project_id: *project_id,
 9331                                worktree_id: worktree_id.to_proto(),
 9332                                summary: Some(proto::DiagnosticSummary {
 9333                                    path: project_path.path.as_ref().to_proto(),
 9334                                    language_server_id: server_id.0 as u64,
 9335                                    error_count: summary.error_count as u32,
 9336                                    warning_count: summary.warning_count as u32,
 9337                                }),
 9338                                more_summaries: Vec::new(),
 9339                            })
 9340                        }
 9341                    }
 9342                }
 9343                updated_diagnostics_paths
 9344                    .entry(server_id)
 9345                    .or_insert_with(Vec::new)
 9346                    .push(project_path);
 9347            }
 9348
 9349            if let Some((diagnostics_summary, (downstream_client, _))) =
 9350                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9351            {
 9352                downstream_client.send(diagnostics_summary).log_err();
 9353            }
 9354            for (server_id, paths) in updated_diagnostics_paths {
 9355                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9356            }
 9357            Ok(())
 9358        })?
 9359    }
 9360
 9361    async fn handle_start_language_server(
 9362        lsp_store: Entity<Self>,
 9363        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9364        mut cx: AsyncApp,
 9365    ) -> Result<()> {
 9366        let server = envelope.payload.server.context("invalid server")?;
 9367        let server_capabilities =
 9368            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9369                .with_context(|| {
 9370                    format!(
 9371                        "incorrect server capabilities {}",
 9372                        envelope.payload.capabilities
 9373                    )
 9374                })?;
 9375        lsp_store.update(&mut cx, |lsp_store, cx| {
 9376            let server_id = LanguageServerId(server.id as usize);
 9377            let server_name = LanguageServerName::from_proto(server.name.clone());
 9378            lsp_store
 9379                .lsp_server_capabilities
 9380                .insert(server_id, server_capabilities);
 9381            lsp_store.language_server_statuses.insert(
 9382                server_id,
 9383                LanguageServerStatus {
 9384                    name: server_name.clone(),
 9385                    pending_work: Default::default(),
 9386                    has_pending_diagnostic_updates: false,
 9387                    progress_tokens: Default::default(),
 9388                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9389                    binary: None,
 9390                    configuration: None,
 9391                    workspace_folders: BTreeSet::new(),
 9392                },
 9393            );
 9394            cx.emit(LspStoreEvent::LanguageServerAdded(
 9395                server_id,
 9396                server_name,
 9397                server.worktree_id.map(WorktreeId::from_proto),
 9398            ));
 9399            cx.notify();
 9400        })?;
 9401        Ok(())
 9402    }
 9403
 9404    async fn handle_update_language_server(
 9405        lsp_store: Entity<Self>,
 9406        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9407        mut cx: AsyncApp,
 9408    ) -> Result<()> {
 9409        lsp_store.update(&mut cx, |lsp_store, cx| {
 9410            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9411
 9412            match envelope.payload.variant.context("invalid variant")? {
 9413                proto::update_language_server::Variant::WorkStart(payload) => {
 9414                    lsp_store.on_lsp_work_start(
 9415                        language_server_id,
 9416                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9417                            .context("invalid progress token value")?,
 9418                        LanguageServerProgress {
 9419                            title: payload.title,
 9420                            is_disk_based_diagnostics_progress: false,
 9421                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9422                            message: payload.message,
 9423                            percentage: payload.percentage.map(|p| p as usize),
 9424                            last_update_at: cx.background_executor().now(),
 9425                        },
 9426                        cx,
 9427                    );
 9428                }
 9429                proto::update_language_server::Variant::WorkProgress(payload) => {
 9430                    lsp_store.on_lsp_work_progress(
 9431                        language_server_id,
 9432                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9433                            .context("invalid progress token value")?,
 9434                        LanguageServerProgress {
 9435                            title: None,
 9436                            is_disk_based_diagnostics_progress: false,
 9437                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9438                            message: payload.message,
 9439                            percentage: payload.percentage.map(|p| p as usize),
 9440                            last_update_at: cx.background_executor().now(),
 9441                        },
 9442                        cx,
 9443                    );
 9444                }
 9445
 9446                proto::update_language_server::Variant::WorkEnd(payload) => {
 9447                    lsp_store.on_lsp_work_end(
 9448                        language_server_id,
 9449                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9450                            .context("invalid progress token value")?,
 9451                        cx,
 9452                    );
 9453                }
 9454
 9455                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9456                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9457                }
 9458
 9459                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9460                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9461                }
 9462
 9463                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9464                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9465                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9466                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9467                        language_server_id,
 9468                        name: envelope
 9469                            .payload
 9470                            .server_name
 9471                            .map(SharedString::new)
 9472                            .map(LanguageServerName),
 9473                        message: non_lsp,
 9474                    });
 9475                }
 9476            }
 9477
 9478            Ok(())
 9479        })?
 9480    }
 9481
 9482    async fn handle_language_server_log(
 9483        this: Entity<Self>,
 9484        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9485        mut cx: AsyncApp,
 9486    ) -> Result<()> {
 9487        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9488        let log_type = envelope
 9489            .payload
 9490            .log_type
 9491            .map(LanguageServerLogType::from_proto)
 9492            .context("invalid language server log type")?;
 9493
 9494        let message = envelope.payload.message;
 9495
 9496        this.update(&mut cx, |_, cx| {
 9497            cx.emit(LspStoreEvent::LanguageServerLog(
 9498                language_server_id,
 9499                log_type,
 9500                message,
 9501            ));
 9502        })
 9503    }
 9504
 9505    async fn handle_lsp_ext_cancel_flycheck(
 9506        lsp_store: Entity<Self>,
 9507        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9508        cx: AsyncApp,
 9509    ) -> Result<proto::Ack> {
 9510        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9511        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9512            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9513                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9514            } else {
 9515                None
 9516            }
 9517        })?;
 9518        if let Some(task) = task {
 9519            task.context("handling lsp ext cancel flycheck")?;
 9520        }
 9521
 9522        Ok(proto::Ack {})
 9523    }
 9524
 9525    async fn handle_lsp_ext_run_flycheck(
 9526        lsp_store: Entity<Self>,
 9527        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9528        mut cx: AsyncApp,
 9529    ) -> Result<proto::Ack> {
 9530        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9531        lsp_store.update(&mut cx, |lsp_store, cx| {
 9532            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9533                let text_document = if envelope.payload.current_file_only {
 9534                    let buffer_id = envelope
 9535                        .payload
 9536                        .buffer_id
 9537                        .map(|id| BufferId::new(id))
 9538                        .transpose()?;
 9539                    buffer_id
 9540                        .and_then(|buffer_id| {
 9541                            lsp_store
 9542                                .buffer_store()
 9543                                .read(cx)
 9544                                .get(buffer_id)
 9545                                .and_then(|buffer| {
 9546                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9547                                })
 9548                                .map(|path| make_text_document_identifier(&path))
 9549                        })
 9550                        .transpose()?
 9551                } else {
 9552                    None
 9553                };
 9554                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9555                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9556                )?;
 9557            }
 9558            anyhow::Ok(())
 9559        })??;
 9560
 9561        Ok(proto::Ack {})
 9562    }
 9563
 9564    async fn handle_lsp_ext_clear_flycheck(
 9565        lsp_store: Entity<Self>,
 9566        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9567        cx: AsyncApp,
 9568    ) -> Result<proto::Ack> {
 9569        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9570        lsp_store
 9571            .read_with(&cx, |lsp_store, _| {
 9572                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9573                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9574                } else {
 9575                    None
 9576                }
 9577            })
 9578            .context("handling lsp ext clear flycheck")?;
 9579
 9580        Ok(proto::Ack {})
 9581    }
 9582
 9583    pub fn disk_based_diagnostics_started(
 9584        &mut self,
 9585        language_server_id: LanguageServerId,
 9586        cx: &mut Context<Self>,
 9587    ) {
 9588        if let Some(language_server_status) =
 9589            self.language_server_statuses.get_mut(&language_server_id)
 9590        {
 9591            language_server_status.has_pending_diagnostic_updates = true;
 9592        }
 9593
 9594        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9595        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9596            language_server_id,
 9597            name: self
 9598                .language_server_adapter_for_id(language_server_id)
 9599                .map(|adapter| adapter.name()),
 9600            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9601                Default::default(),
 9602            ),
 9603        })
 9604    }
 9605
 9606    pub fn disk_based_diagnostics_finished(
 9607        &mut self,
 9608        language_server_id: LanguageServerId,
 9609        cx: &mut Context<Self>,
 9610    ) {
 9611        if let Some(language_server_status) =
 9612            self.language_server_statuses.get_mut(&language_server_id)
 9613        {
 9614            language_server_status.has_pending_diagnostic_updates = false;
 9615        }
 9616
 9617        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9618        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9619            language_server_id,
 9620            name: self
 9621                .language_server_adapter_for_id(language_server_id)
 9622                .map(|adapter| adapter.name()),
 9623            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9624                Default::default(),
 9625            ),
 9626        })
 9627    }
 9628
 9629    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9630    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9631    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9632    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9633    // the language server might take some time to publish diagnostics.
 9634    fn simulate_disk_based_diagnostics_events_if_needed(
 9635        &mut self,
 9636        language_server_id: LanguageServerId,
 9637        cx: &mut Context<Self>,
 9638    ) {
 9639        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9640
 9641        let Some(LanguageServerState::Running {
 9642            simulate_disk_based_diagnostics_completion,
 9643            adapter,
 9644            ..
 9645        }) = self
 9646            .as_local_mut()
 9647            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9648        else {
 9649            return;
 9650        };
 9651
 9652        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9653            return;
 9654        }
 9655
 9656        let prev_task =
 9657            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9658                cx.background_executor()
 9659                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9660                    .await;
 9661
 9662                this.update(cx, |this, cx| {
 9663                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9664
 9665                    if let Some(LanguageServerState::Running {
 9666                        simulate_disk_based_diagnostics_completion,
 9667                        ..
 9668                    }) = this.as_local_mut().and_then(|local_store| {
 9669                        local_store.language_servers.get_mut(&language_server_id)
 9670                    }) {
 9671                        *simulate_disk_based_diagnostics_completion = None;
 9672                    }
 9673                })
 9674                .ok();
 9675            }));
 9676
 9677        if prev_task.is_none() {
 9678            self.disk_based_diagnostics_started(language_server_id, cx);
 9679        }
 9680    }
 9681
 9682    pub fn language_server_statuses(
 9683        &self,
 9684    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9685        self.language_server_statuses
 9686            .iter()
 9687            .map(|(key, value)| (*key, value))
 9688    }
 9689
 9690    pub(super) fn did_rename_entry(
 9691        &self,
 9692        worktree_id: WorktreeId,
 9693        old_path: &Path,
 9694        new_path: &Path,
 9695        is_dir: bool,
 9696    ) {
 9697        maybe!({
 9698            let local_store = self.as_local()?;
 9699
 9700            let old_uri = lsp::Uri::from_file_path(old_path)
 9701                .ok()
 9702                .map(|uri| uri.to_string())?;
 9703            let new_uri = lsp::Uri::from_file_path(new_path)
 9704                .ok()
 9705                .map(|uri| uri.to_string())?;
 9706
 9707            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9708                let Some(filter) = local_store
 9709                    .language_server_paths_watched_for_rename
 9710                    .get(&language_server.server_id())
 9711                else {
 9712                    continue;
 9713                };
 9714
 9715                if filter.should_send_did_rename(&old_uri, is_dir) {
 9716                    language_server
 9717                        .notify::<DidRenameFiles>(RenameFilesParams {
 9718                            files: vec![FileRename {
 9719                                old_uri: old_uri.clone(),
 9720                                new_uri: new_uri.clone(),
 9721                            }],
 9722                        })
 9723                        .ok();
 9724                }
 9725            }
 9726            Some(())
 9727        });
 9728    }
 9729
 9730    pub(super) fn will_rename_entry(
 9731        this: WeakEntity<Self>,
 9732        worktree_id: WorktreeId,
 9733        old_path: &Path,
 9734        new_path: &Path,
 9735        is_dir: bool,
 9736        cx: AsyncApp,
 9737    ) -> Task<ProjectTransaction> {
 9738        let old_uri = lsp::Uri::from_file_path(old_path)
 9739            .ok()
 9740            .map(|uri| uri.to_string());
 9741        let new_uri = lsp::Uri::from_file_path(new_path)
 9742            .ok()
 9743            .map(|uri| uri.to_string());
 9744        cx.spawn(async move |cx| {
 9745            let mut tasks = vec![];
 9746            this.update(cx, |this, cx| {
 9747                let local_store = this.as_local()?;
 9748                let old_uri = old_uri?;
 9749                let new_uri = new_uri?;
 9750                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9751                    let Some(filter) = local_store
 9752                        .language_server_paths_watched_for_rename
 9753                        .get(&language_server.server_id())
 9754                    else {
 9755                        continue;
 9756                    };
 9757
 9758                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9759                        let apply_edit = cx.spawn({
 9760                            let old_uri = old_uri.clone();
 9761                            let new_uri = new_uri.clone();
 9762                            let language_server = language_server.clone();
 9763                            async move |this, cx| {
 9764                                let edit = language_server
 9765                                    .request::<WillRenameFiles>(RenameFilesParams {
 9766                                        files: vec![FileRename { old_uri, new_uri }],
 9767                                    })
 9768                                    .await
 9769                                    .into_response()
 9770                                    .context("will rename files")
 9771                                    .log_err()
 9772                                    .flatten()?;
 9773
 9774                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9775                                    this.upgrade()?,
 9776                                    edit,
 9777                                    false,
 9778                                    language_server.clone(),
 9779                                    cx,
 9780                                )
 9781                                .await
 9782                                .ok()?;
 9783                                Some(transaction)
 9784                            }
 9785                        });
 9786                        tasks.push(apply_edit);
 9787                    }
 9788                }
 9789                Some(())
 9790            })
 9791            .ok()
 9792            .flatten();
 9793            let mut merged_transaction = ProjectTransaction::default();
 9794            for task in tasks {
 9795                // Await on tasks sequentially so that the order of application of edits is deterministic
 9796                // (at least with regards to the order of registration of language servers)
 9797                if let Some(transaction) = task.await {
 9798                    for (buffer, buffer_transaction) in transaction.0 {
 9799                        merged_transaction.0.insert(buffer, buffer_transaction);
 9800                    }
 9801                }
 9802            }
 9803            merged_transaction
 9804        })
 9805    }
 9806
 9807    fn lsp_notify_abs_paths_changed(
 9808        &mut self,
 9809        server_id: LanguageServerId,
 9810        changes: Vec<PathEvent>,
 9811    ) {
 9812        maybe!({
 9813            let server = self.language_server_for_id(server_id)?;
 9814            let changes = changes
 9815                .into_iter()
 9816                .filter_map(|event| {
 9817                    let typ = match event.kind? {
 9818                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9819                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9820                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9821                    };
 9822                    Some(lsp::FileEvent {
 9823                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9824                        typ,
 9825                    })
 9826                })
 9827                .collect::<Vec<_>>();
 9828            if !changes.is_empty() {
 9829                server
 9830                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9831                        lsp::DidChangeWatchedFilesParams { changes },
 9832                    )
 9833                    .ok();
 9834            }
 9835            Some(())
 9836        });
 9837    }
 9838
 9839    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9840        self.as_local()?.language_server_for_id(id)
 9841    }
 9842
 9843    fn on_lsp_progress(
 9844        &mut self,
 9845        progress_params: lsp::ProgressParams,
 9846        language_server_id: LanguageServerId,
 9847        disk_based_diagnostics_progress_token: Option<String>,
 9848        cx: &mut Context<Self>,
 9849    ) {
 9850        match progress_params.value {
 9851            lsp::ProgressParamsValue::WorkDone(progress) => {
 9852                self.handle_work_done_progress(
 9853                    progress,
 9854                    language_server_id,
 9855                    disk_based_diagnostics_progress_token,
 9856                    ProgressToken::from_lsp(progress_params.token),
 9857                    cx,
 9858                );
 9859            }
 9860            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9861                let registration_id = match progress_params.token {
 9862                    lsp::NumberOrString::Number(_) => None,
 9863                    lsp::NumberOrString::String(token) => token
 9864                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9865                        .map(|(_, id)| id.to_owned()),
 9866                };
 9867                if let Some(LanguageServerState::Running {
 9868                    workspace_diagnostics_refresh_tasks,
 9869                    ..
 9870                }) = self
 9871                    .as_local_mut()
 9872                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9873                    && let Some(workspace_diagnostics) =
 9874                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9875                {
 9876                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9877                    self.apply_workspace_diagnostic_report(
 9878                        language_server_id,
 9879                        report,
 9880                        registration_id.map(SharedString::from),
 9881                        cx,
 9882                    )
 9883                }
 9884            }
 9885        }
 9886    }
 9887
 9888    fn handle_work_done_progress(
 9889        &mut self,
 9890        progress: lsp::WorkDoneProgress,
 9891        language_server_id: LanguageServerId,
 9892        disk_based_diagnostics_progress_token: Option<String>,
 9893        token: ProgressToken,
 9894        cx: &mut Context<Self>,
 9895    ) {
 9896        let language_server_status =
 9897            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9898                status
 9899            } else {
 9900                return;
 9901            };
 9902
 9903        if !language_server_status.progress_tokens.contains(&token) {
 9904            return;
 9905        }
 9906
 9907        let is_disk_based_diagnostics_progress =
 9908            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9909                (&disk_based_diagnostics_progress_token, &token)
 9910            {
 9911                token.starts_with(disk_based_token)
 9912            } else {
 9913                false
 9914            };
 9915
 9916        match progress {
 9917            lsp::WorkDoneProgress::Begin(report) => {
 9918                if is_disk_based_diagnostics_progress {
 9919                    self.disk_based_diagnostics_started(language_server_id, cx);
 9920                }
 9921                self.on_lsp_work_start(
 9922                    language_server_id,
 9923                    token.clone(),
 9924                    LanguageServerProgress {
 9925                        title: Some(report.title),
 9926                        is_disk_based_diagnostics_progress,
 9927                        is_cancellable: report.cancellable.unwrap_or(false),
 9928                        message: report.message.clone(),
 9929                        percentage: report.percentage.map(|p| p as usize),
 9930                        last_update_at: cx.background_executor().now(),
 9931                    },
 9932                    cx,
 9933                );
 9934            }
 9935            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9936                language_server_id,
 9937                token,
 9938                LanguageServerProgress {
 9939                    title: None,
 9940                    is_disk_based_diagnostics_progress,
 9941                    is_cancellable: report.cancellable.unwrap_or(false),
 9942                    message: report.message,
 9943                    percentage: report.percentage.map(|p| p as usize),
 9944                    last_update_at: cx.background_executor().now(),
 9945                },
 9946                cx,
 9947            ),
 9948            lsp::WorkDoneProgress::End(_) => {
 9949                language_server_status.progress_tokens.remove(&token);
 9950                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9951                if is_disk_based_diagnostics_progress {
 9952                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9953                }
 9954            }
 9955        }
 9956    }
 9957
 9958    fn on_lsp_work_start(
 9959        &mut self,
 9960        language_server_id: LanguageServerId,
 9961        token: ProgressToken,
 9962        progress: LanguageServerProgress,
 9963        cx: &mut Context<Self>,
 9964    ) {
 9965        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9966            status.pending_work.insert(token.clone(), progress.clone());
 9967            cx.notify();
 9968        }
 9969        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9970            language_server_id,
 9971            name: self
 9972                .language_server_adapter_for_id(language_server_id)
 9973                .map(|adapter| adapter.name()),
 9974            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9975                token: Some(token.to_proto()),
 9976                title: progress.title,
 9977                message: progress.message,
 9978                percentage: progress.percentage.map(|p| p as u32),
 9979                is_cancellable: Some(progress.is_cancellable),
 9980            }),
 9981        })
 9982    }
 9983
 9984    fn on_lsp_work_progress(
 9985        &mut self,
 9986        language_server_id: LanguageServerId,
 9987        token: ProgressToken,
 9988        progress: LanguageServerProgress,
 9989        cx: &mut Context<Self>,
 9990    ) {
 9991        let mut did_update = false;
 9992        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9993            match status.pending_work.entry(token.clone()) {
 9994                btree_map::Entry::Vacant(entry) => {
 9995                    entry.insert(progress.clone());
 9996                    did_update = true;
 9997                }
 9998                btree_map::Entry::Occupied(mut entry) => {
 9999                    let entry = entry.get_mut();
10000                    if (progress.last_update_at - entry.last_update_at)
10001                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10002                    {
10003                        entry.last_update_at = progress.last_update_at;
10004                        if progress.message.is_some() {
10005                            entry.message = progress.message.clone();
10006                        }
10007                        if progress.percentage.is_some() {
10008                            entry.percentage = progress.percentage;
10009                        }
10010                        if progress.is_cancellable != entry.is_cancellable {
10011                            entry.is_cancellable = progress.is_cancellable;
10012                        }
10013                        did_update = true;
10014                    }
10015                }
10016            }
10017        }
10018
10019        if did_update {
10020            cx.emit(LspStoreEvent::LanguageServerUpdate {
10021                language_server_id,
10022                name: self
10023                    .language_server_adapter_for_id(language_server_id)
10024                    .map(|adapter| adapter.name()),
10025                message: proto::update_language_server::Variant::WorkProgress(
10026                    proto::LspWorkProgress {
10027                        token: Some(token.to_proto()),
10028                        message: progress.message,
10029                        percentage: progress.percentage.map(|p| p as u32),
10030                        is_cancellable: Some(progress.is_cancellable),
10031                    },
10032                ),
10033            })
10034        }
10035    }
10036
10037    fn on_lsp_work_end(
10038        &mut self,
10039        language_server_id: LanguageServerId,
10040        token: ProgressToken,
10041        cx: &mut Context<Self>,
10042    ) {
10043        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10044            if let Some(work) = status.pending_work.remove(&token)
10045                && !work.is_disk_based_diagnostics_progress
10046            {
10047                cx.emit(LspStoreEvent::RefreshInlayHints {
10048                    server_id: language_server_id,
10049                    request_id: None,
10050                });
10051            }
10052            cx.notify();
10053        }
10054
10055        cx.emit(LspStoreEvent::LanguageServerUpdate {
10056            language_server_id,
10057            name: self
10058                .language_server_adapter_for_id(language_server_id)
10059                .map(|adapter| adapter.name()),
10060            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10061                token: Some(token.to_proto()),
10062            }),
10063        })
10064    }
10065
10066    pub async fn handle_resolve_completion_documentation(
10067        this: Entity<Self>,
10068        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10069        mut cx: AsyncApp,
10070    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10071        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10072
10073        let completion = this
10074            .read_with(&cx, |this, cx| {
10075                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10076                let server = this
10077                    .language_server_for_id(id)
10078                    .with_context(|| format!("No language server {id}"))?;
10079
10080                anyhow::Ok(cx.background_spawn(async move {
10081                    let can_resolve = server
10082                        .capabilities()
10083                        .completion_provider
10084                        .as_ref()
10085                        .and_then(|options| options.resolve_provider)
10086                        .unwrap_or(false);
10087                    if can_resolve {
10088                        server
10089                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
10090                            .await
10091                            .into_response()
10092                            .context("resolve completion item")
10093                    } else {
10094                        anyhow::Ok(lsp_completion)
10095                    }
10096                }))
10097            })??
10098            .await?;
10099
10100        let mut documentation_is_markdown = false;
10101        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10102        let documentation = match completion.documentation {
10103            Some(lsp::Documentation::String(text)) => text,
10104
10105            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10106                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10107                value
10108            }
10109
10110            _ => String::new(),
10111        };
10112
10113        // If we have a new buffer_id, that means we're talking to a new client
10114        // and want to check for new text_edits in the completion too.
10115        let mut old_replace_start = None;
10116        let mut old_replace_end = None;
10117        let mut old_insert_start = None;
10118        let mut old_insert_end = None;
10119        let mut new_text = String::default();
10120        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10121            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10122                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10123                anyhow::Ok(buffer.read(cx).snapshot())
10124            })??;
10125
10126            if let Some(text_edit) = completion.text_edit.as_ref() {
10127                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10128
10129                if let Some(mut edit) = edit {
10130                    LineEnding::normalize(&mut edit.new_text);
10131
10132                    new_text = edit.new_text;
10133                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10134                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10135                    if let Some(insert_range) = edit.insert_range {
10136                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10137                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10138                    }
10139                }
10140            }
10141        }
10142
10143        Ok(proto::ResolveCompletionDocumentationResponse {
10144            documentation,
10145            documentation_is_markdown,
10146            old_replace_start,
10147            old_replace_end,
10148            new_text,
10149            lsp_completion,
10150            old_insert_start,
10151            old_insert_end,
10152        })
10153    }
10154
10155    async fn handle_on_type_formatting(
10156        this: Entity<Self>,
10157        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10158        mut cx: AsyncApp,
10159    ) -> Result<proto::OnTypeFormattingResponse> {
10160        let on_type_formatting = this.update(&mut cx, |this, cx| {
10161            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10162            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10163            let position = envelope
10164                .payload
10165                .position
10166                .and_then(deserialize_anchor)
10167                .context("invalid position")?;
10168            anyhow::Ok(this.apply_on_type_formatting(
10169                buffer,
10170                position,
10171                envelope.payload.trigger.clone(),
10172                cx,
10173            ))
10174        })??;
10175
10176        let transaction = on_type_formatting
10177            .await?
10178            .as_ref()
10179            .map(language::proto::serialize_transaction);
10180        Ok(proto::OnTypeFormattingResponse { transaction })
10181    }
10182
10183    async fn handle_refresh_inlay_hints(
10184        lsp_store: Entity<Self>,
10185        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10186        mut cx: AsyncApp,
10187    ) -> Result<proto::Ack> {
10188        lsp_store.update(&mut cx, |_, cx| {
10189            cx.emit(LspStoreEvent::RefreshInlayHints {
10190                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10191                request_id: envelope.payload.request_id.map(|id| id as usize),
10192            });
10193        })?;
10194        Ok(proto::Ack {})
10195    }
10196
10197    async fn handle_pull_workspace_diagnostics(
10198        lsp_store: Entity<Self>,
10199        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10200        mut cx: AsyncApp,
10201    ) -> Result<proto::Ack> {
10202        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10203        lsp_store.update(&mut cx, |lsp_store, _| {
10204            lsp_store.pull_workspace_diagnostics(server_id);
10205        })?;
10206        Ok(proto::Ack {})
10207    }
10208
10209    async fn handle_get_color_presentation(
10210        lsp_store: Entity<Self>,
10211        envelope: TypedEnvelope<proto::GetColorPresentation>,
10212        mut cx: AsyncApp,
10213    ) -> Result<proto::GetColorPresentationResponse> {
10214        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10215        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10216            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10217        })??;
10218
10219        let color = envelope
10220            .payload
10221            .color
10222            .context("invalid color resolve request")?;
10223        let start = color
10224            .lsp_range_start
10225            .context("invalid color resolve request")?;
10226        let end = color
10227            .lsp_range_end
10228            .context("invalid color resolve request")?;
10229
10230        let color = DocumentColor {
10231            lsp_range: lsp::Range {
10232                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10233                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10234            },
10235            color: lsp::Color {
10236                red: color.red,
10237                green: color.green,
10238                blue: color.blue,
10239                alpha: color.alpha,
10240            },
10241            resolved: false,
10242            color_presentations: Vec::new(),
10243        };
10244        let resolved_color = lsp_store
10245            .update(&mut cx, |lsp_store, cx| {
10246                lsp_store.resolve_color_presentation(
10247                    color,
10248                    buffer.clone(),
10249                    LanguageServerId(envelope.payload.server_id as usize),
10250                    cx,
10251                )
10252            })?
10253            .await
10254            .context("resolving color presentation")?;
10255
10256        Ok(proto::GetColorPresentationResponse {
10257            presentations: resolved_color
10258                .color_presentations
10259                .into_iter()
10260                .map(|presentation| proto::ColorPresentation {
10261                    label: presentation.label.to_string(),
10262                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10263                    additional_text_edits: presentation
10264                        .additional_text_edits
10265                        .into_iter()
10266                        .map(serialize_lsp_edit)
10267                        .collect(),
10268                })
10269                .collect(),
10270        })
10271    }
10272
10273    async fn handle_resolve_inlay_hint(
10274        lsp_store: Entity<Self>,
10275        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10276        mut cx: AsyncApp,
10277    ) -> Result<proto::ResolveInlayHintResponse> {
10278        let proto_hint = envelope
10279            .payload
10280            .hint
10281            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10282        let hint = InlayHints::proto_to_project_hint(proto_hint)
10283            .context("resolved proto inlay hint conversion")?;
10284        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10285            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10286            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10287        })??;
10288        let response_hint = lsp_store
10289            .update(&mut cx, |lsp_store, cx| {
10290                lsp_store.resolve_inlay_hint(
10291                    hint,
10292                    buffer,
10293                    LanguageServerId(envelope.payload.language_server_id as usize),
10294                    cx,
10295                )
10296            })?
10297            .await
10298            .context("inlay hints fetch")?;
10299        Ok(proto::ResolveInlayHintResponse {
10300            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10301        })
10302    }
10303
10304    async fn handle_refresh_code_lens(
10305        this: Entity<Self>,
10306        _: TypedEnvelope<proto::RefreshCodeLens>,
10307        mut cx: AsyncApp,
10308    ) -> Result<proto::Ack> {
10309        this.update(&mut cx, |_, cx| {
10310            cx.emit(LspStoreEvent::RefreshCodeLens);
10311        })?;
10312        Ok(proto::Ack {})
10313    }
10314
10315    async fn handle_open_buffer_for_symbol(
10316        this: Entity<Self>,
10317        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10318        mut cx: AsyncApp,
10319    ) -> Result<proto::OpenBufferForSymbolResponse> {
10320        let peer_id = envelope.original_sender_id().unwrap_or_default();
10321        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10322        let symbol = Self::deserialize_symbol(symbol)?;
10323        this.read_with(&cx, |this, _| {
10324            if let SymbolLocation::OutsideProject {
10325                abs_path,
10326                signature,
10327            } = &symbol.path
10328            {
10329                let new_signature = this.symbol_signature(&abs_path);
10330                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10331            }
10332            Ok(())
10333        })??;
10334        let buffer = this
10335            .update(&mut cx, |this, cx| {
10336                this.open_buffer_for_symbol(
10337                    &Symbol {
10338                        language_server_name: symbol.language_server_name,
10339                        source_worktree_id: symbol.source_worktree_id,
10340                        source_language_server_id: symbol.source_language_server_id,
10341                        path: symbol.path,
10342                        name: symbol.name,
10343                        kind: symbol.kind,
10344                        range: symbol.range,
10345                        label: CodeLabel::default(),
10346                    },
10347                    cx,
10348                )
10349            })?
10350            .await?;
10351
10352        this.update(&mut cx, |this, cx| {
10353            let is_private = buffer
10354                .read(cx)
10355                .file()
10356                .map(|f| f.is_private())
10357                .unwrap_or_default();
10358            if is_private {
10359                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10360            } else {
10361                this.buffer_store
10362                    .update(cx, |buffer_store, cx| {
10363                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10364                    })
10365                    .detach_and_log_err(cx);
10366                let buffer_id = buffer.read(cx).remote_id().to_proto();
10367                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10368            }
10369        })?
10370    }
10371
10372    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10373        let mut hasher = Sha256::new();
10374        hasher.update(abs_path.to_string_lossy().as_bytes());
10375        hasher.update(self.nonce.to_be_bytes());
10376        hasher.finalize().as_slice().try_into().unwrap()
10377    }
10378
10379    pub async fn handle_get_project_symbols(
10380        this: Entity<Self>,
10381        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10382        mut cx: AsyncApp,
10383    ) -> Result<proto::GetProjectSymbolsResponse> {
10384        let symbols = this
10385            .update(&mut cx, |this, cx| {
10386                this.symbols(&envelope.payload.query, cx)
10387            })?
10388            .await?;
10389
10390        Ok(proto::GetProjectSymbolsResponse {
10391            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10392        })
10393    }
10394
10395    pub async fn handle_restart_language_servers(
10396        this: Entity<Self>,
10397        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10398        mut cx: AsyncApp,
10399    ) -> Result<proto::Ack> {
10400        this.update(&mut cx, |lsp_store, cx| {
10401            let buffers =
10402                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10403            lsp_store.restart_language_servers_for_buffers(
10404                buffers,
10405                envelope
10406                    .payload
10407                    .only_servers
10408                    .into_iter()
10409                    .filter_map(|selector| {
10410                        Some(match selector.selector? {
10411                            proto::language_server_selector::Selector::ServerId(server_id) => {
10412                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10413                            }
10414                            proto::language_server_selector::Selector::Name(name) => {
10415                                LanguageServerSelector::Name(LanguageServerName(
10416                                    SharedString::from(name),
10417                                ))
10418                            }
10419                        })
10420                    })
10421                    .collect(),
10422                cx,
10423            );
10424        })?;
10425
10426        Ok(proto::Ack {})
10427    }
10428
10429    pub async fn handle_stop_language_servers(
10430        lsp_store: Entity<Self>,
10431        envelope: TypedEnvelope<proto::StopLanguageServers>,
10432        mut cx: AsyncApp,
10433    ) -> Result<proto::Ack> {
10434        lsp_store.update(&mut cx, |lsp_store, cx| {
10435            if envelope.payload.all
10436                && envelope.payload.also_servers.is_empty()
10437                && envelope.payload.buffer_ids.is_empty()
10438            {
10439                lsp_store.stop_all_language_servers(cx);
10440            } else {
10441                let buffers =
10442                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10443                lsp_store
10444                    .stop_language_servers_for_buffers(
10445                        buffers,
10446                        envelope
10447                            .payload
10448                            .also_servers
10449                            .into_iter()
10450                            .filter_map(|selector| {
10451                                Some(match selector.selector? {
10452                                    proto::language_server_selector::Selector::ServerId(
10453                                        server_id,
10454                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10455                                        server_id,
10456                                    )),
10457                                    proto::language_server_selector::Selector::Name(name) => {
10458                                        LanguageServerSelector::Name(LanguageServerName(
10459                                            SharedString::from(name),
10460                                        ))
10461                                    }
10462                                })
10463                            })
10464                            .collect(),
10465                        cx,
10466                    )
10467                    .detach_and_log_err(cx);
10468            }
10469        })?;
10470
10471        Ok(proto::Ack {})
10472    }
10473
10474    pub async fn handle_cancel_language_server_work(
10475        lsp_store: Entity<Self>,
10476        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10477        mut cx: AsyncApp,
10478    ) -> Result<proto::Ack> {
10479        lsp_store.update(&mut cx, |lsp_store, cx| {
10480            if let Some(work) = envelope.payload.work {
10481                match work {
10482                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10483                        let buffers =
10484                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10485                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10486                    }
10487                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10488                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10489                        let token = work
10490                            .token
10491                            .map(|token| {
10492                                ProgressToken::from_proto(token)
10493                                    .context("invalid work progress token")
10494                            })
10495                            .transpose()?;
10496                        lsp_store.cancel_language_server_work(server_id, token, cx);
10497                    }
10498                }
10499            }
10500            anyhow::Ok(())
10501        })??;
10502
10503        Ok(proto::Ack {})
10504    }
10505
10506    fn buffer_ids_to_buffers(
10507        &mut self,
10508        buffer_ids: impl Iterator<Item = u64>,
10509        cx: &mut Context<Self>,
10510    ) -> Vec<Entity<Buffer>> {
10511        buffer_ids
10512            .into_iter()
10513            .flat_map(|buffer_id| {
10514                self.buffer_store
10515                    .read(cx)
10516                    .get(BufferId::new(buffer_id).log_err()?)
10517            })
10518            .collect::<Vec<_>>()
10519    }
10520
10521    async fn handle_apply_additional_edits_for_completion(
10522        this: Entity<Self>,
10523        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10524        mut cx: AsyncApp,
10525    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10526        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10527            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10528            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10529            let completion = Self::deserialize_completion(
10530                envelope.payload.completion.context("invalid completion")?,
10531            )?;
10532            anyhow::Ok((buffer, completion))
10533        })??;
10534
10535        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10536            this.apply_additional_edits_for_completion(
10537                buffer,
10538                Rc::new(RefCell::new(Box::new([Completion {
10539                    replace_range: completion.replace_range,
10540                    new_text: completion.new_text,
10541                    source: completion.source,
10542                    documentation: None,
10543                    label: CodeLabel::default(),
10544                    match_start: None,
10545                    snippet_deduplication_key: None,
10546                    insert_text_mode: None,
10547                    icon_path: None,
10548                    confirm: None,
10549                }]))),
10550                0,
10551                false,
10552                cx,
10553            )
10554        })?;
10555
10556        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10557            transaction: apply_additional_edits
10558                .await?
10559                .as_ref()
10560                .map(language::proto::serialize_transaction),
10561        })
10562    }
10563
10564    pub fn last_formatting_failure(&self) -> Option<&str> {
10565        self.last_formatting_failure.as_deref()
10566    }
10567
10568    pub fn reset_last_formatting_failure(&mut self) {
10569        self.last_formatting_failure = None;
10570    }
10571
10572    pub fn environment_for_buffer(
10573        &self,
10574        buffer: &Entity<Buffer>,
10575        cx: &mut Context<Self>,
10576    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10577        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10578            environment.update(cx, |env, cx| {
10579                env.buffer_environment(buffer, &self.worktree_store, cx)
10580            })
10581        } else {
10582            Task::ready(None).shared()
10583        }
10584    }
10585
10586    pub fn format(
10587        &mut self,
10588        buffers: HashSet<Entity<Buffer>>,
10589        target: LspFormatTarget,
10590        push_to_history: bool,
10591        trigger: FormatTrigger,
10592        cx: &mut Context<Self>,
10593    ) -> Task<anyhow::Result<ProjectTransaction>> {
10594        let logger = zlog::scoped!("format");
10595        if self.as_local().is_some() {
10596            zlog::trace!(logger => "Formatting locally");
10597            let logger = zlog::scoped!(logger => "local");
10598            let buffers = buffers
10599                .into_iter()
10600                .map(|buffer_handle| {
10601                    let buffer = buffer_handle.read(cx);
10602                    let buffer_abs_path = File::from_dyn(buffer.file())
10603                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10604
10605                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10606                })
10607                .collect::<Vec<_>>();
10608
10609            cx.spawn(async move |lsp_store, cx| {
10610                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10611
10612                for (handle, abs_path, id) in buffers {
10613                    let env = lsp_store
10614                        .update(cx, |lsp_store, cx| {
10615                            lsp_store.environment_for_buffer(&handle, cx)
10616                        })?
10617                        .await;
10618
10619                    let ranges = match &target {
10620                        LspFormatTarget::Buffers => None,
10621                        LspFormatTarget::Ranges(ranges) => {
10622                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10623                        }
10624                    };
10625
10626                    formattable_buffers.push(FormattableBuffer {
10627                        handle,
10628                        abs_path,
10629                        env,
10630                        ranges,
10631                    });
10632                }
10633                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10634
10635                let format_timer = zlog::time!(logger => "Formatting buffers");
10636                let result = LocalLspStore::format_locally(
10637                    lsp_store.clone(),
10638                    formattable_buffers,
10639                    push_to_history,
10640                    trigger,
10641                    logger,
10642                    cx,
10643                )
10644                .await;
10645                format_timer.end();
10646
10647                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10648
10649                lsp_store.update(cx, |lsp_store, _| {
10650                    lsp_store.update_last_formatting_failure(&result);
10651                })?;
10652
10653                result
10654            })
10655        } else if let Some((client, project_id)) = self.upstream_client() {
10656            zlog::trace!(logger => "Formatting remotely");
10657            let logger = zlog::scoped!(logger => "remote");
10658            // Don't support formatting ranges via remote
10659            match target {
10660                LspFormatTarget::Buffers => {}
10661                LspFormatTarget::Ranges(_) => {
10662                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10663                    return Task::ready(Ok(ProjectTransaction::default()));
10664                }
10665            }
10666
10667            let buffer_store = self.buffer_store();
10668            cx.spawn(async move |lsp_store, cx| {
10669                zlog::trace!(logger => "Sending remote format request");
10670                let request_timer = zlog::time!(logger => "remote format request");
10671                let result = client
10672                    .request(proto::FormatBuffers {
10673                        project_id,
10674                        trigger: trigger as i32,
10675                        buffer_ids: buffers
10676                            .iter()
10677                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10678                            .collect::<Result<_>>()?,
10679                    })
10680                    .await
10681                    .and_then(|result| result.transaction.context("missing transaction"));
10682                request_timer.end();
10683
10684                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10685
10686                lsp_store.update(cx, |lsp_store, _| {
10687                    lsp_store.update_last_formatting_failure(&result);
10688                })?;
10689
10690                let transaction_response = result?;
10691                let _timer = zlog::time!(logger => "deserializing project transaction");
10692                buffer_store
10693                    .update(cx, |buffer_store, cx| {
10694                        buffer_store.deserialize_project_transaction(
10695                            transaction_response,
10696                            push_to_history,
10697                            cx,
10698                        )
10699                    })?
10700                    .await
10701            })
10702        } else {
10703            zlog::trace!(logger => "Not formatting");
10704            Task::ready(Ok(ProjectTransaction::default()))
10705        }
10706    }
10707
10708    async fn handle_format_buffers(
10709        this: Entity<Self>,
10710        envelope: TypedEnvelope<proto::FormatBuffers>,
10711        mut cx: AsyncApp,
10712    ) -> Result<proto::FormatBuffersResponse> {
10713        let sender_id = envelope.original_sender_id().unwrap_or_default();
10714        let format = this.update(&mut cx, |this, cx| {
10715            let mut buffers = HashSet::default();
10716            for buffer_id in &envelope.payload.buffer_ids {
10717                let buffer_id = BufferId::new(*buffer_id)?;
10718                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10719            }
10720            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10721            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10722        })??;
10723
10724        let project_transaction = format.await?;
10725        let project_transaction = this.update(&mut cx, |this, cx| {
10726            this.buffer_store.update(cx, |buffer_store, cx| {
10727                buffer_store.serialize_project_transaction_for_peer(
10728                    project_transaction,
10729                    sender_id,
10730                    cx,
10731                )
10732            })
10733        })?;
10734        Ok(proto::FormatBuffersResponse {
10735            transaction: Some(project_transaction),
10736        })
10737    }
10738
10739    async fn handle_apply_code_action_kind(
10740        this: Entity<Self>,
10741        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10742        mut cx: AsyncApp,
10743    ) -> Result<proto::ApplyCodeActionKindResponse> {
10744        let sender_id = envelope.original_sender_id().unwrap_or_default();
10745        let format = this.update(&mut cx, |this, cx| {
10746            let mut buffers = HashSet::default();
10747            for buffer_id in &envelope.payload.buffer_ids {
10748                let buffer_id = BufferId::new(*buffer_id)?;
10749                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10750            }
10751            let kind = match envelope.payload.kind.as_str() {
10752                "" => CodeActionKind::EMPTY,
10753                "quickfix" => CodeActionKind::QUICKFIX,
10754                "refactor" => CodeActionKind::REFACTOR,
10755                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10756                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10757                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10758                "source" => CodeActionKind::SOURCE,
10759                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10760                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10761                _ => anyhow::bail!(
10762                    "Invalid code action kind {}",
10763                    envelope.payload.kind.as_str()
10764                ),
10765            };
10766            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10767        })??;
10768
10769        let project_transaction = format.await?;
10770        let project_transaction = this.update(&mut cx, |this, cx| {
10771            this.buffer_store.update(cx, |buffer_store, cx| {
10772                buffer_store.serialize_project_transaction_for_peer(
10773                    project_transaction,
10774                    sender_id,
10775                    cx,
10776                )
10777            })
10778        })?;
10779        Ok(proto::ApplyCodeActionKindResponse {
10780            transaction: Some(project_transaction),
10781        })
10782    }
10783
10784    async fn shutdown_language_server(
10785        server_state: Option<LanguageServerState>,
10786        name: LanguageServerName,
10787        cx: &mut AsyncApp,
10788    ) {
10789        let server = match server_state {
10790            Some(LanguageServerState::Starting { startup, .. }) => {
10791                let mut timer = cx
10792                    .background_executor()
10793                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10794                    .fuse();
10795
10796                select! {
10797                    server = startup.fuse() => server,
10798                    () = timer => {
10799                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10800                        None
10801                    },
10802                }
10803            }
10804
10805            Some(LanguageServerState::Running { server, .. }) => Some(server),
10806
10807            None => None,
10808        };
10809
10810        if let Some(server) = server
10811            && let Some(shutdown) = server.shutdown()
10812        {
10813            shutdown.await;
10814        }
10815    }
10816
10817    // Returns a list of all of the worktrees which no longer have a language server and the root path
10818    // for the stopped server
10819    fn stop_local_language_server(
10820        &mut self,
10821        server_id: LanguageServerId,
10822        cx: &mut Context<Self>,
10823    ) -> Task<()> {
10824        let local = match &mut self.mode {
10825            LspStoreMode::Local(local) => local,
10826            _ => {
10827                return Task::ready(());
10828            }
10829        };
10830
10831        // Remove this server ID from all entries in the given worktree.
10832        local
10833            .language_server_ids
10834            .retain(|_, state| state.id != server_id);
10835        self.buffer_store.update(cx, |buffer_store, cx| {
10836            for buffer in buffer_store.buffers() {
10837                buffer.update(cx, |buffer, cx| {
10838                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10839                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10840                });
10841            }
10842        });
10843
10844        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10845            summaries.retain(|path, summaries_by_server_id| {
10846                if summaries_by_server_id.remove(&server_id).is_some() {
10847                    if let Some((client, project_id)) = self.downstream_client.clone() {
10848                        client
10849                            .send(proto::UpdateDiagnosticSummary {
10850                                project_id,
10851                                worktree_id: worktree_id.to_proto(),
10852                                summary: Some(proto::DiagnosticSummary {
10853                                    path: path.as_ref().to_proto(),
10854                                    language_server_id: server_id.0 as u64,
10855                                    error_count: 0,
10856                                    warning_count: 0,
10857                                }),
10858                                more_summaries: Vec::new(),
10859                            })
10860                            .log_err();
10861                    }
10862                    !summaries_by_server_id.is_empty()
10863                } else {
10864                    true
10865                }
10866            });
10867        }
10868
10869        let local = self.as_local_mut().unwrap();
10870        for diagnostics in local.diagnostics.values_mut() {
10871            diagnostics.retain(|_, diagnostics_by_server_id| {
10872                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10873                    diagnostics_by_server_id.remove(ix);
10874                    !diagnostics_by_server_id.is_empty()
10875                } else {
10876                    true
10877                }
10878            });
10879        }
10880        local.language_server_watched_paths.remove(&server_id);
10881
10882        let server_state = local.language_servers.remove(&server_id);
10883        self.cleanup_lsp_data(server_id);
10884        let name = self
10885            .language_server_statuses
10886            .remove(&server_id)
10887            .map(|status| status.name)
10888            .or_else(|| {
10889                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10890                    Some(adapter.name())
10891                } else {
10892                    None
10893                }
10894            });
10895
10896        if let Some(name) = name {
10897            log::info!("stopping language server {name}");
10898            self.languages
10899                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10900            cx.notify();
10901
10902            return cx.spawn(async move |lsp_store, cx| {
10903                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10904                lsp_store
10905                    .update(cx, |lsp_store, cx| {
10906                        lsp_store
10907                            .languages
10908                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10909                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10910                        cx.notify();
10911                    })
10912                    .ok();
10913            });
10914        }
10915
10916        if server_state.is_some() {
10917            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10918        }
10919        Task::ready(())
10920    }
10921
10922    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10923        if let Some((client, project_id)) = self.upstream_client() {
10924            let request = client.request(proto::StopLanguageServers {
10925                project_id,
10926                buffer_ids: Vec::new(),
10927                also_servers: Vec::new(),
10928                all: true,
10929            });
10930            cx.background_spawn(request).detach_and_log_err(cx);
10931        } else {
10932            let Some(local) = self.as_local_mut() else {
10933                return;
10934            };
10935            let language_servers_to_stop = local
10936                .language_server_ids
10937                .values()
10938                .map(|state| state.id)
10939                .collect();
10940            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10941            let tasks = language_servers_to_stop
10942                .into_iter()
10943                .map(|server| self.stop_local_language_server(server, cx))
10944                .collect::<Vec<_>>();
10945            cx.background_spawn(async move {
10946                futures::future::join_all(tasks).await;
10947            })
10948            .detach();
10949        }
10950    }
10951
10952    pub fn restart_language_servers_for_buffers(
10953        &mut self,
10954        buffers: Vec<Entity<Buffer>>,
10955        only_restart_servers: HashSet<LanguageServerSelector>,
10956        cx: &mut Context<Self>,
10957    ) {
10958        if let Some((client, project_id)) = self.upstream_client() {
10959            let request = client.request(proto::RestartLanguageServers {
10960                project_id,
10961                buffer_ids: buffers
10962                    .into_iter()
10963                    .map(|b| b.read(cx).remote_id().to_proto())
10964                    .collect(),
10965                only_servers: only_restart_servers
10966                    .into_iter()
10967                    .map(|selector| {
10968                        let selector = match selector {
10969                            LanguageServerSelector::Id(language_server_id) => {
10970                                proto::language_server_selector::Selector::ServerId(
10971                                    language_server_id.to_proto(),
10972                                )
10973                            }
10974                            LanguageServerSelector::Name(language_server_name) => {
10975                                proto::language_server_selector::Selector::Name(
10976                                    language_server_name.to_string(),
10977                                )
10978                            }
10979                        };
10980                        proto::LanguageServerSelector {
10981                            selector: Some(selector),
10982                        }
10983                    })
10984                    .collect(),
10985                all: false,
10986            });
10987            cx.background_spawn(request).detach_and_log_err(cx);
10988        } else {
10989            let stop_task = if only_restart_servers.is_empty() {
10990                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10991            } else {
10992                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10993            };
10994            cx.spawn(async move |lsp_store, cx| {
10995                stop_task.await;
10996                lsp_store
10997                    .update(cx, |lsp_store, cx| {
10998                        for buffer in buffers {
10999                            lsp_store.register_buffer_with_language_servers(
11000                                &buffer,
11001                                only_restart_servers.clone(),
11002                                true,
11003                                cx,
11004                            );
11005                        }
11006                    })
11007                    .ok()
11008            })
11009            .detach();
11010        }
11011    }
11012
11013    pub fn stop_language_servers_for_buffers(
11014        &mut self,
11015        buffers: Vec<Entity<Buffer>>,
11016        also_stop_servers: HashSet<LanguageServerSelector>,
11017        cx: &mut Context<Self>,
11018    ) -> Task<Result<()>> {
11019        if let Some((client, project_id)) = self.upstream_client() {
11020            let request = client.request(proto::StopLanguageServers {
11021                project_id,
11022                buffer_ids: buffers
11023                    .into_iter()
11024                    .map(|b| b.read(cx).remote_id().to_proto())
11025                    .collect(),
11026                also_servers: also_stop_servers
11027                    .into_iter()
11028                    .map(|selector| {
11029                        let selector = match selector {
11030                            LanguageServerSelector::Id(language_server_id) => {
11031                                proto::language_server_selector::Selector::ServerId(
11032                                    language_server_id.to_proto(),
11033                                )
11034                            }
11035                            LanguageServerSelector::Name(language_server_name) => {
11036                                proto::language_server_selector::Selector::Name(
11037                                    language_server_name.to_string(),
11038                                )
11039                            }
11040                        };
11041                        proto::LanguageServerSelector {
11042                            selector: Some(selector),
11043                        }
11044                    })
11045                    .collect(),
11046                all: false,
11047            });
11048            cx.background_spawn(async move {
11049                let _ = request.await?;
11050                Ok(())
11051            })
11052        } else {
11053            let task =
11054                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11055            cx.background_spawn(async move {
11056                task.await;
11057                Ok(())
11058            })
11059        }
11060    }
11061
11062    fn stop_local_language_servers_for_buffers(
11063        &mut self,
11064        buffers: &[Entity<Buffer>],
11065        also_stop_servers: HashSet<LanguageServerSelector>,
11066        cx: &mut Context<Self>,
11067    ) -> Task<()> {
11068        let Some(local) = self.as_local_mut() else {
11069            return Task::ready(());
11070        };
11071        let mut language_server_names_to_stop = BTreeSet::default();
11072        let mut language_servers_to_stop = also_stop_servers
11073            .into_iter()
11074            .flat_map(|selector| match selector {
11075                LanguageServerSelector::Id(id) => Some(id),
11076                LanguageServerSelector::Name(name) => {
11077                    language_server_names_to_stop.insert(name);
11078                    None
11079                }
11080            })
11081            .collect::<BTreeSet<_>>();
11082
11083        let mut covered_worktrees = HashSet::default();
11084        for buffer in buffers {
11085            buffer.update(cx, |buffer, cx| {
11086                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11087                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11088                    && covered_worktrees.insert(worktree_id)
11089                {
11090                    language_server_names_to_stop.retain(|name| {
11091                        let old_ids_count = language_servers_to_stop.len();
11092                        let all_language_servers_with_this_name = local
11093                            .language_server_ids
11094                            .iter()
11095                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11096                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11097                        old_ids_count == language_servers_to_stop.len()
11098                    });
11099                }
11100            });
11101        }
11102        for name in language_server_names_to_stop {
11103            language_servers_to_stop.extend(
11104                local
11105                    .language_server_ids
11106                    .iter()
11107                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11108            );
11109        }
11110
11111        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11112        let tasks = language_servers_to_stop
11113            .into_iter()
11114            .map(|server| self.stop_local_language_server(server, cx))
11115            .collect::<Vec<_>>();
11116
11117        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11118    }
11119
11120    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11121        let (worktree, relative_path) =
11122            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11123
11124        let project_path = ProjectPath {
11125            worktree_id: worktree.read(cx).id(),
11126            path: relative_path,
11127        };
11128
11129        Some(
11130            self.buffer_store()
11131                .read(cx)
11132                .get_by_path(&project_path)?
11133                .read(cx),
11134        )
11135    }
11136
11137    #[cfg(any(test, feature = "test-support"))]
11138    pub fn update_diagnostics(
11139        &mut self,
11140        server_id: LanguageServerId,
11141        diagnostics: lsp::PublishDiagnosticsParams,
11142        result_id: Option<SharedString>,
11143        source_kind: DiagnosticSourceKind,
11144        disk_based_sources: &[String],
11145        cx: &mut Context<Self>,
11146    ) -> Result<()> {
11147        self.merge_lsp_diagnostics(
11148            source_kind,
11149            vec![DocumentDiagnosticsUpdate {
11150                diagnostics,
11151                result_id,
11152                server_id,
11153                disk_based_sources: Cow::Borrowed(disk_based_sources),
11154                registration_id: None,
11155            }],
11156            |_, _, _| false,
11157            cx,
11158        )
11159    }
11160
11161    pub fn merge_lsp_diagnostics(
11162        &mut self,
11163        source_kind: DiagnosticSourceKind,
11164        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11165        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11166        cx: &mut Context<Self>,
11167    ) -> Result<()> {
11168        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11169        let updates = lsp_diagnostics
11170            .into_iter()
11171            .filter_map(|update| {
11172                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11173                Some(DocumentDiagnosticsUpdate {
11174                    diagnostics: self.lsp_to_document_diagnostics(
11175                        abs_path,
11176                        source_kind,
11177                        update.server_id,
11178                        update.diagnostics,
11179                        &update.disk_based_sources,
11180                        update.registration_id.clone(),
11181                    ),
11182                    result_id: update.result_id,
11183                    server_id: update.server_id,
11184                    disk_based_sources: update.disk_based_sources,
11185                    registration_id: update.registration_id,
11186                })
11187            })
11188            .collect();
11189        self.merge_diagnostic_entries(updates, merge, cx)?;
11190        Ok(())
11191    }
11192
11193    fn lsp_to_document_diagnostics(
11194        &mut self,
11195        document_abs_path: PathBuf,
11196        source_kind: DiagnosticSourceKind,
11197        server_id: LanguageServerId,
11198        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11199        disk_based_sources: &[String],
11200        registration_id: Option<SharedString>,
11201    ) -> DocumentDiagnostics {
11202        let mut diagnostics = Vec::default();
11203        let mut primary_diagnostic_group_ids = HashMap::default();
11204        let mut sources_by_group_id = HashMap::default();
11205        let mut supporting_diagnostics = HashMap::default();
11206
11207        let adapter = self.language_server_adapter_for_id(server_id);
11208
11209        // Ensure that primary diagnostics are always the most severe
11210        lsp_diagnostics
11211            .diagnostics
11212            .sort_by_key(|item| item.severity);
11213
11214        for diagnostic in &lsp_diagnostics.diagnostics {
11215            let source = diagnostic.source.as_ref();
11216            let range = range_from_lsp(diagnostic.range);
11217            let is_supporting = diagnostic
11218                .related_information
11219                .as_ref()
11220                .is_some_and(|infos| {
11221                    infos.iter().any(|info| {
11222                        primary_diagnostic_group_ids.contains_key(&(
11223                            source,
11224                            diagnostic.code.clone(),
11225                            range_from_lsp(info.location.range),
11226                        ))
11227                    })
11228                });
11229
11230            let is_unnecessary = diagnostic
11231                .tags
11232                .as_ref()
11233                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11234
11235            let underline = self
11236                .language_server_adapter_for_id(server_id)
11237                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11238
11239            if is_supporting {
11240                supporting_diagnostics.insert(
11241                    (source, diagnostic.code.clone(), range),
11242                    (diagnostic.severity, is_unnecessary),
11243                );
11244            } else {
11245                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11246                let is_disk_based =
11247                    source.is_some_and(|source| disk_based_sources.contains(source));
11248
11249                sources_by_group_id.insert(group_id, source);
11250                primary_diagnostic_group_ids
11251                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11252
11253                diagnostics.push(DiagnosticEntry {
11254                    range,
11255                    diagnostic: Diagnostic {
11256                        source: diagnostic.source.clone(),
11257                        source_kind,
11258                        code: diagnostic.code.clone(),
11259                        code_description: diagnostic
11260                            .code_description
11261                            .as_ref()
11262                            .and_then(|d| d.href.clone()),
11263                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11264                        markdown: adapter.as_ref().and_then(|adapter| {
11265                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11266                        }),
11267                        message: diagnostic.message.trim().to_string(),
11268                        group_id,
11269                        is_primary: true,
11270                        is_disk_based,
11271                        is_unnecessary,
11272                        underline,
11273                        data: diagnostic.data.clone(),
11274                        registration_id: registration_id.clone(),
11275                    },
11276                });
11277                if let Some(infos) = &diagnostic.related_information {
11278                    for info in infos {
11279                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11280                            let range = range_from_lsp(info.location.range);
11281                            diagnostics.push(DiagnosticEntry {
11282                                range,
11283                                diagnostic: Diagnostic {
11284                                    source: diagnostic.source.clone(),
11285                                    source_kind,
11286                                    code: diagnostic.code.clone(),
11287                                    code_description: diagnostic
11288                                        .code_description
11289                                        .as_ref()
11290                                        .and_then(|d| d.href.clone()),
11291                                    severity: DiagnosticSeverity::INFORMATION,
11292                                    markdown: adapter.as_ref().and_then(|adapter| {
11293                                        adapter.diagnostic_message_to_markdown(&info.message)
11294                                    }),
11295                                    message: info.message.trim().to_string(),
11296                                    group_id,
11297                                    is_primary: false,
11298                                    is_disk_based,
11299                                    is_unnecessary: false,
11300                                    underline,
11301                                    data: diagnostic.data.clone(),
11302                                    registration_id: registration_id.clone(),
11303                                },
11304                            });
11305                        }
11306                    }
11307                }
11308            }
11309        }
11310
11311        for entry in &mut diagnostics {
11312            let diagnostic = &mut entry.diagnostic;
11313            if !diagnostic.is_primary {
11314                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11315                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11316                    source,
11317                    diagnostic.code.clone(),
11318                    entry.range.clone(),
11319                )) {
11320                    if let Some(severity) = severity {
11321                        diagnostic.severity = severity;
11322                    }
11323                    diagnostic.is_unnecessary = is_unnecessary;
11324                }
11325            }
11326        }
11327
11328        DocumentDiagnostics {
11329            diagnostics,
11330            document_abs_path,
11331            version: lsp_diagnostics.version,
11332        }
11333    }
11334
11335    fn insert_newly_running_language_server(
11336        &mut self,
11337        adapter: Arc<CachedLspAdapter>,
11338        language_server: Arc<LanguageServer>,
11339        server_id: LanguageServerId,
11340        key: LanguageServerSeed,
11341        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11342        cx: &mut Context<Self>,
11343    ) {
11344        let Some(local) = self.as_local_mut() else {
11345            return;
11346        };
11347        // If the language server for this key doesn't match the server id, don't store the
11348        // server. Which will cause it to be dropped, killing the process
11349        if local
11350            .language_server_ids
11351            .get(&key)
11352            .map(|state| state.id != server_id)
11353            .unwrap_or(false)
11354        {
11355            return;
11356        }
11357
11358        // Update language_servers collection with Running variant of LanguageServerState
11359        // indicating that the server is up and running and ready
11360        let workspace_folders = workspace_folders.lock().clone();
11361        language_server.set_workspace_folders(workspace_folders);
11362
11363        let workspace_diagnostics_refresh_tasks = language_server
11364            .capabilities()
11365            .diagnostic_provider
11366            .and_then(|provider| {
11367                local
11368                    .language_server_dynamic_registrations
11369                    .entry(server_id)
11370                    .or_default()
11371                    .diagnostics
11372                    .entry(None)
11373                    .or_insert(provider.clone());
11374                let workspace_refresher =
11375                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11376
11377                Some((None, workspace_refresher))
11378            })
11379            .into_iter()
11380            .collect();
11381        local.language_servers.insert(
11382            server_id,
11383            LanguageServerState::Running {
11384                workspace_diagnostics_refresh_tasks,
11385                adapter: adapter.clone(),
11386                server: language_server.clone(),
11387                simulate_disk_based_diagnostics_completion: None,
11388            },
11389        );
11390        local
11391            .languages
11392            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11393        if let Some(file_ops_caps) = language_server
11394            .capabilities()
11395            .workspace
11396            .as_ref()
11397            .and_then(|ws| ws.file_operations.as_ref())
11398        {
11399            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11400            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11401            if did_rename_caps.or(will_rename_caps).is_some() {
11402                let watcher = RenamePathsWatchedForServer::default()
11403                    .with_did_rename_patterns(did_rename_caps)
11404                    .with_will_rename_patterns(will_rename_caps);
11405                local
11406                    .language_server_paths_watched_for_rename
11407                    .insert(server_id, watcher);
11408            }
11409        }
11410
11411        self.language_server_statuses.insert(
11412            server_id,
11413            LanguageServerStatus {
11414                name: language_server.name(),
11415                pending_work: Default::default(),
11416                has_pending_diagnostic_updates: false,
11417                progress_tokens: Default::default(),
11418                worktree: Some(key.worktree_id),
11419                binary: Some(language_server.binary().clone()),
11420                configuration: Some(language_server.configuration().clone()),
11421                workspace_folders: language_server.workspace_folders(),
11422            },
11423        );
11424
11425        cx.emit(LspStoreEvent::LanguageServerAdded(
11426            server_id,
11427            language_server.name(),
11428            Some(key.worktree_id),
11429        ));
11430
11431        let server_capabilities = language_server.capabilities();
11432        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11433            downstream_client
11434                .send(proto::StartLanguageServer {
11435                    project_id: *project_id,
11436                    server: Some(proto::LanguageServer {
11437                        id: server_id.to_proto(),
11438                        name: language_server.name().to_string(),
11439                        worktree_id: Some(key.worktree_id.to_proto()),
11440                    }),
11441                    capabilities: serde_json::to_string(&server_capabilities)
11442                        .expect("serializing server LSP capabilities"),
11443                })
11444                .log_err();
11445        }
11446        self.lsp_server_capabilities
11447            .insert(server_id, server_capabilities);
11448
11449        // Tell the language server about every open buffer in the worktree that matches the language.
11450        // Also check for buffers in worktrees that reused this server
11451        let mut worktrees_using_server = vec![key.worktree_id];
11452        if let Some(local) = self.as_local() {
11453            // Find all worktrees that have this server in their language server tree
11454            for (worktree_id, servers) in &local.lsp_tree.instances {
11455                if *worktree_id != key.worktree_id {
11456                    for server_map in servers.roots.values() {
11457                        if server_map
11458                            .values()
11459                            .any(|(node, _)| node.id() == Some(server_id))
11460                        {
11461                            worktrees_using_server.push(*worktree_id);
11462                        }
11463                    }
11464                }
11465            }
11466        }
11467
11468        let mut buffer_paths_registered = Vec::new();
11469        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11470            let mut lsp_adapters = HashMap::default();
11471            for buffer_handle in buffer_store.buffers() {
11472                let buffer = buffer_handle.read(cx);
11473                let file = match File::from_dyn(buffer.file()) {
11474                    Some(file) => file,
11475                    None => continue,
11476                };
11477                let language = match buffer.language() {
11478                    Some(language) => language,
11479                    None => continue,
11480                };
11481
11482                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11483                    || !lsp_adapters
11484                        .entry(language.name())
11485                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11486                        .iter()
11487                        .any(|a| a.name == key.name)
11488                {
11489                    continue;
11490                }
11491                // didOpen
11492                let file = match file.as_local() {
11493                    Some(file) => file,
11494                    None => continue,
11495                };
11496
11497                let local = self.as_local_mut().unwrap();
11498
11499                let buffer_id = buffer.remote_id();
11500                if local.registered_buffers.contains_key(&buffer_id) {
11501                    let versions = local
11502                        .buffer_snapshots
11503                        .entry(buffer_id)
11504                        .or_default()
11505                        .entry(server_id)
11506                        .and_modify(|_| {
11507                            assert!(
11508                            false,
11509                            "There should not be an existing snapshot for a newly inserted buffer"
11510                        )
11511                        })
11512                        .or_insert_with(|| {
11513                            vec![LspBufferSnapshot {
11514                                version: 0,
11515                                snapshot: buffer.text_snapshot(),
11516                            }]
11517                        });
11518
11519                    let snapshot = versions.last().unwrap();
11520                    let version = snapshot.version;
11521                    let initial_snapshot = &snapshot.snapshot;
11522                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11523                    language_server.register_buffer(
11524                        uri,
11525                        adapter.language_id(&language.name()),
11526                        version,
11527                        initial_snapshot.text(),
11528                    );
11529                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11530                    local
11531                        .buffers_opened_in_servers
11532                        .entry(buffer_id)
11533                        .or_default()
11534                        .insert(server_id);
11535                }
11536                buffer_handle.update(cx, |buffer, cx| {
11537                    buffer.set_completion_triggers(
11538                        server_id,
11539                        language_server
11540                            .capabilities()
11541                            .completion_provider
11542                            .as_ref()
11543                            .and_then(|provider| {
11544                                provider
11545                                    .trigger_characters
11546                                    .as_ref()
11547                                    .map(|characters| characters.iter().cloned().collect())
11548                            })
11549                            .unwrap_or_default(),
11550                        cx,
11551                    )
11552                });
11553            }
11554        });
11555
11556        for (buffer_id, abs_path) in buffer_paths_registered {
11557            cx.emit(LspStoreEvent::LanguageServerUpdate {
11558                language_server_id: server_id,
11559                name: Some(adapter.name()),
11560                message: proto::update_language_server::Variant::RegisteredForBuffer(
11561                    proto::RegisteredForBuffer {
11562                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11563                        buffer_id: buffer_id.to_proto(),
11564                    },
11565                ),
11566            });
11567        }
11568
11569        cx.notify();
11570    }
11571
11572    pub fn language_servers_running_disk_based_diagnostics(
11573        &self,
11574    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11575        self.language_server_statuses
11576            .iter()
11577            .filter_map(|(id, status)| {
11578                if status.has_pending_diagnostic_updates {
11579                    Some(*id)
11580                } else {
11581                    None
11582                }
11583            })
11584    }
11585
11586    pub(crate) fn cancel_language_server_work_for_buffers(
11587        &mut self,
11588        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11589        cx: &mut Context<Self>,
11590    ) {
11591        if let Some((client, project_id)) = self.upstream_client() {
11592            let request = client.request(proto::CancelLanguageServerWork {
11593                project_id,
11594                work: Some(proto::cancel_language_server_work::Work::Buffers(
11595                    proto::cancel_language_server_work::Buffers {
11596                        buffer_ids: buffers
11597                            .into_iter()
11598                            .map(|b| b.read(cx).remote_id().to_proto())
11599                            .collect(),
11600                    },
11601                )),
11602            });
11603            cx.background_spawn(request).detach_and_log_err(cx);
11604        } else if let Some(local) = self.as_local() {
11605            let servers = buffers
11606                .into_iter()
11607                .flat_map(|buffer| {
11608                    buffer.update(cx, |buffer, cx| {
11609                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11610                    })
11611                })
11612                .collect::<HashSet<_>>();
11613            for server_id in servers {
11614                self.cancel_language_server_work(server_id, None, cx);
11615            }
11616        }
11617    }
11618
11619    pub(crate) fn cancel_language_server_work(
11620        &mut self,
11621        server_id: LanguageServerId,
11622        token_to_cancel: Option<ProgressToken>,
11623        cx: &mut Context<Self>,
11624    ) {
11625        if let Some(local) = self.as_local() {
11626            let status = self.language_server_statuses.get(&server_id);
11627            let server = local.language_servers.get(&server_id);
11628            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11629            {
11630                for (token, progress) in &status.pending_work {
11631                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11632                        && token != token_to_cancel
11633                    {
11634                        continue;
11635                    }
11636                    if progress.is_cancellable {
11637                        server
11638                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11639                                WorkDoneProgressCancelParams {
11640                                    token: token.to_lsp(),
11641                                },
11642                            )
11643                            .ok();
11644                    }
11645                }
11646            }
11647        } else if let Some((client, project_id)) = self.upstream_client() {
11648            let request = client.request(proto::CancelLanguageServerWork {
11649                project_id,
11650                work: Some(
11651                    proto::cancel_language_server_work::Work::LanguageServerWork(
11652                        proto::cancel_language_server_work::LanguageServerWork {
11653                            language_server_id: server_id.to_proto(),
11654                            token: token_to_cancel.map(|token| token.to_proto()),
11655                        },
11656                    ),
11657                ),
11658            });
11659            cx.background_spawn(request).detach_and_log_err(cx);
11660        }
11661    }
11662
11663    fn register_supplementary_language_server(
11664        &mut self,
11665        id: LanguageServerId,
11666        name: LanguageServerName,
11667        server: Arc<LanguageServer>,
11668        cx: &mut Context<Self>,
11669    ) {
11670        if let Some(local) = self.as_local_mut() {
11671            local
11672                .supplementary_language_servers
11673                .insert(id, (name.clone(), server));
11674            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11675        }
11676    }
11677
11678    fn unregister_supplementary_language_server(
11679        &mut self,
11680        id: LanguageServerId,
11681        cx: &mut Context<Self>,
11682    ) {
11683        if let Some(local) = self.as_local_mut() {
11684            local.supplementary_language_servers.remove(&id);
11685            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11686        }
11687    }
11688
11689    pub(crate) fn supplementary_language_servers(
11690        &self,
11691    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11692        self.as_local().into_iter().flat_map(|local| {
11693            local
11694                .supplementary_language_servers
11695                .iter()
11696                .map(|(id, (name, _))| (*id, name.clone()))
11697        })
11698    }
11699
11700    pub fn language_server_adapter_for_id(
11701        &self,
11702        id: LanguageServerId,
11703    ) -> Option<Arc<CachedLspAdapter>> {
11704        self.as_local()
11705            .and_then(|local| local.language_servers.get(&id))
11706            .and_then(|language_server_state| match language_server_state {
11707                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11708                _ => None,
11709            })
11710    }
11711
11712    pub(super) fn update_local_worktree_language_servers(
11713        &mut self,
11714        worktree_handle: &Entity<Worktree>,
11715        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11716        cx: &mut Context<Self>,
11717    ) {
11718        if changes.is_empty() {
11719            return;
11720        }
11721
11722        let Some(local) = self.as_local() else { return };
11723
11724        local.prettier_store.update(cx, |prettier_store, cx| {
11725            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11726        });
11727
11728        let worktree_id = worktree_handle.read(cx).id();
11729        let mut language_server_ids = local
11730            .language_server_ids
11731            .iter()
11732            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11733            .collect::<Vec<_>>();
11734        language_server_ids.sort();
11735        language_server_ids.dedup();
11736
11737        // let abs_path = worktree_handle.read(cx).abs_path();
11738        for server_id in &language_server_ids {
11739            if let Some(LanguageServerState::Running { server, .. }) =
11740                local.language_servers.get(server_id)
11741                && let Some(watched_paths) = local
11742                    .language_server_watched_paths
11743                    .get(server_id)
11744                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11745            {
11746                let params = lsp::DidChangeWatchedFilesParams {
11747                    changes: changes
11748                        .iter()
11749                        .filter_map(|(path, _, change)| {
11750                            if !watched_paths.is_match(path.as_std_path()) {
11751                                return None;
11752                            }
11753                            let typ = match change {
11754                                PathChange::Loaded => return None,
11755                                PathChange::Added => lsp::FileChangeType::CREATED,
11756                                PathChange::Removed => lsp::FileChangeType::DELETED,
11757                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11758                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11759                            };
11760                            let uri = lsp::Uri::from_file_path(
11761                                worktree_handle.read(cx).absolutize(&path),
11762                            )
11763                            .ok()?;
11764                            Some(lsp::FileEvent { uri, typ })
11765                        })
11766                        .collect(),
11767                };
11768                if !params.changes.is_empty() {
11769                    server
11770                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11771                        .ok();
11772                }
11773            }
11774        }
11775        for (path, _, _) in changes {
11776            if let Some(file_name) = path.file_name()
11777                && local.watched_manifest_filenames.contains(file_name)
11778            {
11779                self.request_workspace_config_refresh();
11780                break;
11781            }
11782        }
11783    }
11784
11785    pub fn wait_for_remote_buffer(
11786        &mut self,
11787        id: BufferId,
11788        cx: &mut Context<Self>,
11789    ) -> Task<Result<Entity<Buffer>>> {
11790        self.buffer_store.update(cx, |buffer_store, cx| {
11791            buffer_store.wait_for_remote_buffer(id, cx)
11792        })
11793    }
11794
11795    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11796        let mut result = proto::Symbol {
11797            language_server_name: symbol.language_server_name.0.to_string(),
11798            source_worktree_id: symbol.source_worktree_id.to_proto(),
11799            language_server_id: symbol.source_language_server_id.to_proto(),
11800            name: symbol.name.clone(),
11801            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11802            start: Some(proto::PointUtf16 {
11803                row: symbol.range.start.0.row,
11804                column: symbol.range.start.0.column,
11805            }),
11806            end: Some(proto::PointUtf16 {
11807                row: symbol.range.end.0.row,
11808                column: symbol.range.end.0.column,
11809            }),
11810            worktree_id: Default::default(),
11811            path: Default::default(),
11812            signature: Default::default(),
11813        };
11814        match &symbol.path {
11815            SymbolLocation::InProject(path) => {
11816                result.worktree_id = path.worktree_id.to_proto();
11817                result.path = path.path.to_proto();
11818            }
11819            SymbolLocation::OutsideProject {
11820                abs_path,
11821                signature,
11822            } => {
11823                result.path = abs_path.to_string_lossy().into_owned();
11824                result.signature = signature.to_vec();
11825            }
11826        }
11827        result
11828    }
11829
11830    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11831        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11832        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11833        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11834
11835        let path = if serialized_symbol.signature.is_empty() {
11836            SymbolLocation::InProject(ProjectPath {
11837                worktree_id,
11838                path: RelPath::from_proto(&serialized_symbol.path)
11839                    .context("invalid symbol path")?,
11840            })
11841        } else {
11842            SymbolLocation::OutsideProject {
11843                abs_path: Path::new(&serialized_symbol.path).into(),
11844                signature: serialized_symbol
11845                    .signature
11846                    .try_into()
11847                    .map_err(|_| anyhow!("invalid signature"))?,
11848            }
11849        };
11850
11851        let start = serialized_symbol.start.context("invalid start")?;
11852        let end = serialized_symbol.end.context("invalid end")?;
11853        Ok(CoreSymbol {
11854            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11855            source_worktree_id,
11856            source_language_server_id: LanguageServerId::from_proto(
11857                serialized_symbol.language_server_id,
11858            ),
11859            path,
11860            name: serialized_symbol.name,
11861            range: Unclipped(PointUtf16::new(start.row, start.column))
11862                ..Unclipped(PointUtf16::new(end.row, end.column)),
11863            kind,
11864        })
11865    }
11866
11867    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11868        let mut serialized_completion = proto::Completion {
11869            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11870            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11871            new_text: completion.new_text.clone(),
11872            ..proto::Completion::default()
11873        };
11874        match &completion.source {
11875            CompletionSource::Lsp {
11876                insert_range,
11877                server_id,
11878                lsp_completion,
11879                lsp_defaults,
11880                resolved,
11881            } => {
11882                let (old_insert_start, old_insert_end) = insert_range
11883                    .as_ref()
11884                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11885                    .unzip();
11886
11887                serialized_completion.old_insert_start = old_insert_start;
11888                serialized_completion.old_insert_end = old_insert_end;
11889                serialized_completion.source = proto::completion::Source::Lsp as i32;
11890                serialized_completion.server_id = server_id.0 as u64;
11891                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11892                serialized_completion.lsp_defaults = lsp_defaults
11893                    .as_deref()
11894                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11895                serialized_completion.resolved = *resolved;
11896            }
11897            CompletionSource::BufferWord {
11898                word_range,
11899                resolved,
11900            } => {
11901                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11902                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11903                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11904                serialized_completion.resolved = *resolved;
11905            }
11906            CompletionSource::Custom => {
11907                serialized_completion.source = proto::completion::Source::Custom as i32;
11908                serialized_completion.resolved = true;
11909            }
11910            CompletionSource::Dap { sort_text } => {
11911                serialized_completion.source = proto::completion::Source::Dap as i32;
11912                serialized_completion.sort_text = Some(sort_text.clone());
11913            }
11914        }
11915
11916        serialized_completion
11917    }
11918
11919    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11920        let old_replace_start = completion
11921            .old_replace_start
11922            .and_then(deserialize_anchor)
11923            .context("invalid old start")?;
11924        let old_replace_end = completion
11925            .old_replace_end
11926            .and_then(deserialize_anchor)
11927            .context("invalid old end")?;
11928        let insert_range = {
11929            match completion.old_insert_start.zip(completion.old_insert_end) {
11930                Some((start, end)) => {
11931                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11932                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11933                    Some(start..end)
11934                }
11935                None => None,
11936            }
11937        };
11938        Ok(CoreCompletion {
11939            replace_range: old_replace_start..old_replace_end,
11940            new_text: completion.new_text,
11941            source: match proto::completion::Source::from_i32(completion.source) {
11942                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11943                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11944                    insert_range,
11945                    server_id: LanguageServerId::from_proto(completion.server_id),
11946                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11947                    lsp_defaults: completion
11948                        .lsp_defaults
11949                        .as_deref()
11950                        .map(serde_json::from_slice)
11951                        .transpose()?,
11952                    resolved: completion.resolved,
11953                },
11954                Some(proto::completion::Source::BufferWord) => {
11955                    let word_range = completion
11956                        .buffer_word_start
11957                        .and_then(deserialize_anchor)
11958                        .context("invalid buffer word start")?
11959                        ..completion
11960                            .buffer_word_end
11961                            .and_then(deserialize_anchor)
11962                            .context("invalid buffer word end")?;
11963                    CompletionSource::BufferWord {
11964                        word_range,
11965                        resolved: completion.resolved,
11966                    }
11967                }
11968                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11969                    sort_text: completion
11970                        .sort_text
11971                        .context("expected sort text to exist")?,
11972                },
11973                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11974            },
11975        })
11976    }
11977
11978    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11979        let (kind, lsp_action) = match &action.lsp_action {
11980            LspAction::Action(code_action) => (
11981                proto::code_action::Kind::Action as i32,
11982                serde_json::to_vec(code_action).unwrap(),
11983            ),
11984            LspAction::Command(command) => (
11985                proto::code_action::Kind::Command as i32,
11986                serde_json::to_vec(command).unwrap(),
11987            ),
11988            LspAction::CodeLens(code_lens) => (
11989                proto::code_action::Kind::CodeLens as i32,
11990                serde_json::to_vec(code_lens).unwrap(),
11991            ),
11992        };
11993
11994        proto::CodeAction {
11995            server_id: action.server_id.0 as u64,
11996            start: Some(serialize_anchor(&action.range.start)),
11997            end: Some(serialize_anchor(&action.range.end)),
11998            lsp_action,
11999            kind,
12000            resolved: action.resolved,
12001        }
12002    }
12003
12004    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12005        let start = action
12006            .start
12007            .and_then(deserialize_anchor)
12008            .context("invalid start")?;
12009        let end = action
12010            .end
12011            .and_then(deserialize_anchor)
12012            .context("invalid end")?;
12013        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12014            Some(proto::code_action::Kind::Action) => {
12015                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12016            }
12017            Some(proto::code_action::Kind::Command) => {
12018                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12019            }
12020            Some(proto::code_action::Kind::CodeLens) => {
12021                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12022            }
12023            None => anyhow::bail!("Unknown action kind {}", action.kind),
12024        };
12025        Ok(CodeAction {
12026            server_id: LanguageServerId(action.server_id as usize),
12027            range: start..end,
12028            resolved: action.resolved,
12029            lsp_action,
12030        })
12031    }
12032
12033    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12034        match &formatting_result {
12035            Ok(_) => self.last_formatting_failure = None,
12036            Err(error) => {
12037                let error_string = format!("{error:#}");
12038                log::error!("Formatting failed: {error_string}");
12039                self.last_formatting_failure
12040                    .replace(error_string.lines().join(" "));
12041            }
12042        }
12043    }
12044
12045    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12046        self.lsp_server_capabilities.remove(&for_server);
12047        for lsp_data in self.lsp_data.values_mut() {
12048            lsp_data.remove_server_data(for_server);
12049        }
12050        if let Some(local) = self.as_local_mut() {
12051            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12052            local
12053                .workspace_pull_diagnostics_result_ids
12054                .remove(&for_server);
12055            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12056                buffer_servers.remove(&for_server);
12057            }
12058        }
12059    }
12060
12061    pub fn result_id_for_buffer_pull(
12062        &self,
12063        server_id: LanguageServerId,
12064        buffer_id: BufferId,
12065        registration_id: &Option<SharedString>,
12066        cx: &App,
12067    ) -> Option<SharedString> {
12068        let abs_path = self
12069            .buffer_store
12070            .read(cx)
12071            .get(buffer_id)
12072            .and_then(|b| File::from_dyn(b.read(cx).file()))
12073            .map(|f| f.abs_path(cx))?;
12074        self.as_local()?
12075            .buffer_pull_diagnostics_result_ids
12076            .get(&server_id)?
12077            .get(registration_id)?
12078            .get(&abs_path)?
12079            .clone()
12080    }
12081
12082    /// Gets all result_ids for a workspace diagnostics pull request.
12083    /// 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.
12084    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12085    pub fn result_ids_for_workspace_refresh(
12086        &self,
12087        server_id: LanguageServerId,
12088        registration_id: &Option<SharedString>,
12089    ) -> HashMap<PathBuf, SharedString> {
12090        let Some(local) = self.as_local() else {
12091            return HashMap::default();
12092        };
12093        local
12094            .workspace_pull_diagnostics_result_ids
12095            .get(&server_id)
12096            .into_iter()
12097            .filter_map(|diagnostics| diagnostics.get(registration_id))
12098            .flatten()
12099            .filter_map(|(abs_path, result_id)| {
12100                let result_id = local
12101                    .buffer_pull_diagnostics_result_ids
12102                    .get(&server_id)
12103                    .and_then(|buffer_ids_result_ids| {
12104                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12105                    })
12106                    .cloned()
12107                    .flatten()
12108                    .or_else(|| result_id.clone())?;
12109                Some((abs_path.clone(), result_id))
12110            })
12111            .collect()
12112    }
12113
12114    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12115        if let Some(LanguageServerState::Running {
12116            workspace_diagnostics_refresh_tasks,
12117            ..
12118        }) = self
12119            .as_local_mut()
12120            .and_then(|local| local.language_servers.get_mut(&server_id))
12121        {
12122            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12123                diagnostics.refresh_tx.try_send(()).ok();
12124            }
12125        }
12126    }
12127
12128    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
12129        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
12130            return;
12131        };
12132        let Some(local) = self.as_local_mut() else {
12133            return;
12134        };
12135
12136        for server_id in buffer.update(cx, |buffer, cx| {
12137            local.language_server_ids_for_buffer(buffer, cx)
12138        }) {
12139            if let Some(LanguageServerState::Running {
12140                workspace_diagnostics_refresh_tasks,
12141                ..
12142            }) = local.language_servers.get_mut(&server_id)
12143            {
12144                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12145                    diagnostics.refresh_tx.try_send(()).ok();
12146                }
12147            }
12148        }
12149    }
12150
12151    fn apply_workspace_diagnostic_report(
12152        &mut self,
12153        server_id: LanguageServerId,
12154        report: lsp::WorkspaceDiagnosticReportResult,
12155        registration_id: Option<SharedString>,
12156        cx: &mut Context<Self>,
12157    ) {
12158        let workspace_diagnostics =
12159            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12160                report,
12161                server_id,
12162                registration_id,
12163            );
12164        let mut unchanged_buffers = HashMap::default();
12165        let workspace_diagnostics_updates = workspace_diagnostics
12166            .into_iter()
12167            .filter_map(
12168                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12169                    LspPullDiagnostics::Response {
12170                        server_id,
12171                        uri,
12172                        diagnostics,
12173                        registration_id,
12174                    } => Some((
12175                        server_id,
12176                        uri,
12177                        diagnostics,
12178                        workspace_diagnostics.version,
12179                        registration_id,
12180                    )),
12181                    LspPullDiagnostics::Default => None,
12182                },
12183            )
12184            .fold(
12185                HashMap::default(),
12186                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12187                    let (result_id, diagnostics) = match diagnostics {
12188                        PulledDiagnostics::Unchanged { result_id } => {
12189                            unchanged_buffers
12190                                .entry(new_registration_id.clone())
12191                                .or_insert_with(HashSet::default)
12192                                .insert(uri.clone());
12193                            (Some(result_id), Vec::new())
12194                        }
12195                        PulledDiagnostics::Changed {
12196                            result_id,
12197                            diagnostics,
12198                        } => (result_id, diagnostics),
12199                    };
12200                    let disk_based_sources = Cow::Owned(
12201                        self.language_server_adapter_for_id(server_id)
12202                            .as_ref()
12203                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12204                            .unwrap_or(&[])
12205                            .to_vec(),
12206                    );
12207
12208                    let Some(abs_path) = uri.to_file_path().ok() else {
12209                        return acc;
12210                    };
12211                    let Some((worktree, relative_path)) =
12212                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12213                    else {
12214                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12215                        return acc;
12216                    };
12217                    let worktree_id = worktree.read(cx).id();
12218                    let project_path = ProjectPath {
12219                        worktree_id,
12220                        path: relative_path,
12221                    };
12222                    if let Some(local_lsp_store) = self.as_local_mut() {
12223                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12224                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12225                    }
12226                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12227                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12228                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12229                        acc.entry(server_id)
12230                            .or_insert_with(HashMap::default)
12231                            .entry(new_registration_id.clone())
12232                            .or_insert_with(Vec::new)
12233                            .push(DocumentDiagnosticsUpdate {
12234                                server_id,
12235                                diagnostics: lsp::PublishDiagnosticsParams {
12236                                    uri,
12237                                    diagnostics,
12238                                    version,
12239                                },
12240                                result_id,
12241                                disk_based_sources,
12242                                registration_id: new_registration_id,
12243                            });
12244                    }
12245                    acc
12246                },
12247            );
12248
12249        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12250            for (registration_id, diagnostic_updates) in diagnostic_updates {
12251                self.merge_lsp_diagnostics(
12252                    DiagnosticSourceKind::Pulled,
12253                    diagnostic_updates,
12254                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12255                        DiagnosticSourceKind::Pulled => {
12256                            old_diagnostic.registration_id != registration_id
12257                                || unchanged_buffers
12258                                    .get(&old_diagnostic.registration_id)
12259                                    .is_some_and(|unchanged_buffers| {
12260                                        unchanged_buffers.contains(&document_uri)
12261                                    })
12262                        }
12263                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12264                    },
12265                    cx,
12266                )
12267                .log_err();
12268            }
12269        }
12270    }
12271
12272    fn register_server_capabilities(
12273        &mut self,
12274        server_id: LanguageServerId,
12275        params: lsp::RegistrationParams,
12276        cx: &mut Context<Self>,
12277    ) -> anyhow::Result<()> {
12278        let server = self
12279            .language_server_for_id(server_id)
12280            .with_context(|| format!("no server {server_id} found"))?;
12281        for reg in params.registrations {
12282            match reg.method.as_str() {
12283                "workspace/didChangeWatchedFiles" => {
12284                    if let Some(options) = reg.register_options {
12285                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12286                            let caps = serde_json::from_value(options)?;
12287                            local_lsp_store
12288                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12289                            true
12290                        } else {
12291                            false
12292                        };
12293                        if notify {
12294                            notify_server_capabilities_updated(&server, cx);
12295                        }
12296                    }
12297                }
12298                "workspace/didChangeConfiguration" => {
12299                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12300                }
12301                "workspace/didChangeWorkspaceFolders" => {
12302                    // In this case register options is an empty object, we can ignore it
12303                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12304                        supported: Some(true),
12305                        change_notifications: Some(OneOf::Right(reg.id)),
12306                    };
12307                    server.update_capabilities(|capabilities| {
12308                        capabilities
12309                            .workspace
12310                            .get_or_insert_default()
12311                            .workspace_folders = Some(caps);
12312                    });
12313                    notify_server_capabilities_updated(&server, cx);
12314                }
12315                "workspace/symbol" => {
12316                    let options = parse_register_capabilities(reg)?;
12317                    server.update_capabilities(|capabilities| {
12318                        capabilities.workspace_symbol_provider = Some(options);
12319                    });
12320                    notify_server_capabilities_updated(&server, cx);
12321                }
12322                "workspace/fileOperations" => {
12323                    if let Some(options) = reg.register_options {
12324                        let caps = serde_json::from_value(options)?;
12325                        server.update_capabilities(|capabilities| {
12326                            capabilities
12327                                .workspace
12328                                .get_or_insert_default()
12329                                .file_operations = Some(caps);
12330                        });
12331                        notify_server_capabilities_updated(&server, cx);
12332                    }
12333                }
12334                "workspace/executeCommand" => {
12335                    if let Some(options) = reg.register_options {
12336                        let options = serde_json::from_value(options)?;
12337                        server.update_capabilities(|capabilities| {
12338                            capabilities.execute_command_provider = Some(options);
12339                        });
12340                        notify_server_capabilities_updated(&server, cx);
12341                    }
12342                }
12343                "textDocument/rangeFormatting" => {
12344                    let options = parse_register_capabilities(reg)?;
12345                    server.update_capabilities(|capabilities| {
12346                        capabilities.document_range_formatting_provider = Some(options);
12347                    });
12348                    notify_server_capabilities_updated(&server, cx);
12349                }
12350                "textDocument/onTypeFormatting" => {
12351                    if let Some(options) = reg
12352                        .register_options
12353                        .map(serde_json::from_value)
12354                        .transpose()?
12355                    {
12356                        server.update_capabilities(|capabilities| {
12357                            capabilities.document_on_type_formatting_provider = Some(options);
12358                        });
12359                        notify_server_capabilities_updated(&server, cx);
12360                    }
12361                }
12362                "textDocument/formatting" => {
12363                    let options = parse_register_capabilities(reg)?;
12364                    server.update_capabilities(|capabilities| {
12365                        capabilities.document_formatting_provider = Some(options);
12366                    });
12367                    notify_server_capabilities_updated(&server, cx);
12368                }
12369                "textDocument/rename" => {
12370                    let options = parse_register_capabilities(reg)?;
12371                    server.update_capabilities(|capabilities| {
12372                        capabilities.rename_provider = Some(options);
12373                    });
12374                    notify_server_capabilities_updated(&server, cx);
12375                }
12376                "textDocument/inlayHint" => {
12377                    let options = parse_register_capabilities(reg)?;
12378                    server.update_capabilities(|capabilities| {
12379                        capabilities.inlay_hint_provider = Some(options);
12380                    });
12381                    notify_server_capabilities_updated(&server, cx);
12382                }
12383                "textDocument/documentSymbol" => {
12384                    let options = parse_register_capabilities(reg)?;
12385                    server.update_capabilities(|capabilities| {
12386                        capabilities.document_symbol_provider = Some(options);
12387                    });
12388                    notify_server_capabilities_updated(&server, cx);
12389                }
12390                "textDocument/codeAction" => {
12391                    let options = parse_register_capabilities(reg)?;
12392                    let provider = match options {
12393                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12394                        OneOf::Right(caps) => caps,
12395                    };
12396                    server.update_capabilities(|capabilities| {
12397                        capabilities.code_action_provider = Some(provider);
12398                    });
12399                    notify_server_capabilities_updated(&server, cx);
12400                }
12401                "textDocument/definition" => {
12402                    let options = parse_register_capabilities(reg)?;
12403                    server.update_capabilities(|capabilities| {
12404                        capabilities.definition_provider = Some(options);
12405                    });
12406                    notify_server_capabilities_updated(&server, cx);
12407                }
12408                "textDocument/completion" => {
12409                    if let Some(caps) = reg
12410                        .register_options
12411                        .map(serde_json::from_value::<CompletionOptions>)
12412                        .transpose()?
12413                    {
12414                        server.update_capabilities(|capabilities| {
12415                            capabilities.completion_provider = Some(caps.clone());
12416                        });
12417
12418                        if let Some(local) = self.as_local() {
12419                            let mut buffers_with_language_server = Vec::new();
12420                            for handle in self.buffer_store.read(cx).buffers() {
12421                                let buffer_id = handle.read(cx).remote_id();
12422                                if local
12423                                    .buffers_opened_in_servers
12424                                    .get(&buffer_id)
12425                                    .filter(|s| s.contains(&server_id))
12426                                    .is_some()
12427                                {
12428                                    buffers_with_language_server.push(handle);
12429                                }
12430                            }
12431                            let triggers = caps
12432                                .trigger_characters
12433                                .unwrap_or_default()
12434                                .into_iter()
12435                                .collect::<BTreeSet<_>>();
12436                            for handle in buffers_with_language_server {
12437                                let triggers = triggers.clone();
12438                                let _ = handle.update(cx, move |buffer, cx| {
12439                                    buffer.set_completion_triggers(server_id, triggers, cx);
12440                                });
12441                            }
12442                        }
12443                        notify_server_capabilities_updated(&server, cx);
12444                    }
12445                }
12446                "textDocument/hover" => {
12447                    let options = parse_register_capabilities(reg)?;
12448                    let provider = match options {
12449                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12450                        OneOf::Right(caps) => caps,
12451                    };
12452                    server.update_capabilities(|capabilities| {
12453                        capabilities.hover_provider = Some(provider);
12454                    });
12455                    notify_server_capabilities_updated(&server, cx);
12456                }
12457                "textDocument/signatureHelp" => {
12458                    if let Some(caps) = reg
12459                        .register_options
12460                        .map(serde_json::from_value)
12461                        .transpose()?
12462                    {
12463                        server.update_capabilities(|capabilities| {
12464                            capabilities.signature_help_provider = Some(caps);
12465                        });
12466                        notify_server_capabilities_updated(&server, cx);
12467                    }
12468                }
12469                "textDocument/didChange" => {
12470                    if let Some(sync_kind) = reg
12471                        .register_options
12472                        .and_then(|opts| opts.get("syncKind").cloned())
12473                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12474                        .transpose()?
12475                    {
12476                        server.update_capabilities(|capabilities| {
12477                            let mut sync_options =
12478                                Self::take_text_document_sync_options(capabilities);
12479                            sync_options.change = Some(sync_kind);
12480                            capabilities.text_document_sync =
12481                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12482                        });
12483                        notify_server_capabilities_updated(&server, cx);
12484                    }
12485                }
12486                "textDocument/didSave" => {
12487                    if let Some(include_text) = reg
12488                        .register_options
12489                        .map(|opts| {
12490                            let transpose = opts
12491                                .get("includeText")
12492                                .cloned()
12493                                .map(serde_json::from_value::<Option<bool>>)
12494                                .transpose();
12495                            match transpose {
12496                                Ok(value) => Ok(value.flatten()),
12497                                Err(e) => Err(e),
12498                            }
12499                        })
12500                        .transpose()?
12501                    {
12502                        server.update_capabilities(|capabilities| {
12503                            let mut sync_options =
12504                                Self::take_text_document_sync_options(capabilities);
12505                            sync_options.save =
12506                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12507                                    include_text,
12508                                }));
12509                            capabilities.text_document_sync =
12510                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12511                        });
12512                        notify_server_capabilities_updated(&server, cx);
12513                    }
12514                }
12515                "textDocument/codeLens" => {
12516                    if let Some(caps) = reg
12517                        .register_options
12518                        .map(serde_json::from_value)
12519                        .transpose()?
12520                    {
12521                        server.update_capabilities(|capabilities| {
12522                            capabilities.code_lens_provider = Some(caps);
12523                        });
12524                        notify_server_capabilities_updated(&server, cx);
12525                    }
12526                }
12527                "textDocument/diagnostic" => {
12528                    if let Some(caps) = reg
12529                        .register_options
12530                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12531                        .transpose()?
12532                    {
12533                        let local = self
12534                            .as_local_mut()
12535                            .context("Expected LSP Store to be local")?;
12536                        let state = local
12537                            .language_servers
12538                            .get_mut(&server_id)
12539                            .context("Could not obtain Language Servers state")?;
12540                        local
12541                            .language_server_dynamic_registrations
12542                            .entry(server_id)
12543                            .or_default()
12544                            .diagnostics
12545                            .insert(Some(reg.id.clone()), caps.clone());
12546
12547                        let supports_workspace_diagnostics =
12548                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12549                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12550                                    diagnostic_options.workspace_diagnostics
12551                                }
12552                                DiagnosticServerCapabilities::RegistrationOptions(
12553                                    diagnostic_registration_options,
12554                                ) => {
12555                                    diagnostic_registration_options
12556                                        .diagnostic_options
12557                                        .workspace_diagnostics
12558                                }
12559                            };
12560
12561                        if supports_workspace_diagnostics(&caps) {
12562                            if let LanguageServerState::Running {
12563                                workspace_diagnostics_refresh_tasks,
12564                                ..
12565                            } = state
12566                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12567                                    Some(reg.id.clone()),
12568                                    caps.clone(),
12569                                    server.clone(),
12570                                    cx,
12571                                )
12572                            {
12573                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12574                            }
12575                        }
12576
12577                        server.update_capabilities(|capabilities| {
12578                            capabilities.diagnostic_provider = Some(caps);
12579                        });
12580
12581                        notify_server_capabilities_updated(&server, cx);
12582                    }
12583                }
12584                "textDocument/documentColor" => {
12585                    let options = parse_register_capabilities(reg)?;
12586                    let provider = match options {
12587                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12588                        OneOf::Right(caps) => caps,
12589                    };
12590                    server.update_capabilities(|capabilities| {
12591                        capabilities.color_provider = Some(provider);
12592                    });
12593                    notify_server_capabilities_updated(&server, cx);
12594                }
12595                _ => log::warn!("unhandled capability registration: {reg:?}"),
12596            }
12597        }
12598
12599        Ok(())
12600    }
12601
12602    fn unregister_server_capabilities(
12603        &mut self,
12604        server_id: LanguageServerId,
12605        params: lsp::UnregistrationParams,
12606        cx: &mut Context<Self>,
12607    ) -> anyhow::Result<()> {
12608        let server = self
12609            .language_server_for_id(server_id)
12610            .with_context(|| format!("no server {server_id} found"))?;
12611        for unreg in params.unregisterations.iter() {
12612            match unreg.method.as_str() {
12613                "workspace/didChangeWatchedFiles" => {
12614                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12615                        local_lsp_store
12616                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12617                        true
12618                    } else {
12619                        false
12620                    };
12621                    if notify {
12622                        notify_server_capabilities_updated(&server, cx);
12623                    }
12624                }
12625                "workspace/didChangeConfiguration" => {
12626                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12627                }
12628                "workspace/didChangeWorkspaceFolders" => {
12629                    server.update_capabilities(|capabilities| {
12630                        capabilities
12631                            .workspace
12632                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12633                                workspace_folders: None,
12634                                file_operations: None,
12635                            })
12636                            .workspace_folders = None;
12637                    });
12638                    notify_server_capabilities_updated(&server, cx);
12639                }
12640                "workspace/symbol" => {
12641                    server.update_capabilities(|capabilities| {
12642                        capabilities.workspace_symbol_provider = None
12643                    });
12644                    notify_server_capabilities_updated(&server, cx);
12645                }
12646                "workspace/fileOperations" => {
12647                    server.update_capabilities(|capabilities| {
12648                        capabilities
12649                            .workspace
12650                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12651                                workspace_folders: None,
12652                                file_operations: None,
12653                            })
12654                            .file_operations = None;
12655                    });
12656                    notify_server_capabilities_updated(&server, cx);
12657                }
12658                "workspace/executeCommand" => {
12659                    server.update_capabilities(|capabilities| {
12660                        capabilities.execute_command_provider = None;
12661                    });
12662                    notify_server_capabilities_updated(&server, cx);
12663                }
12664                "textDocument/rangeFormatting" => {
12665                    server.update_capabilities(|capabilities| {
12666                        capabilities.document_range_formatting_provider = None
12667                    });
12668                    notify_server_capabilities_updated(&server, cx);
12669                }
12670                "textDocument/onTypeFormatting" => {
12671                    server.update_capabilities(|capabilities| {
12672                        capabilities.document_on_type_formatting_provider = None;
12673                    });
12674                    notify_server_capabilities_updated(&server, cx);
12675                }
12676                "textDocument/formatting" => {
12677                    server.update_capabilities(|capabilities| {
12678                        capabilities.document_formatting_provider = None;
12679                    });
12680                    notify_server_capabilities_updated(&server, cx);
12681                }
12682                "textDocument/rename" => {
12683                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12684                    notify_server_capabilities_updated(&server, cx);
12685                }
12686                "textDocument/codeAction" => {
12687                    server.update_capabilities(|capabilities| {
12688                        capabilities.code_action_provider = None;
12689                    });
12690                    notify_server_capabilities_updated(&server, cx);
12691                }
12692                "textDocument/definition" => {
12693                    server.update_capabilities(|capabilities| {
12694                        capabilities.definition_provider = None;
12695                    });
12696                    notify_server_capabilities_updated(&server, cx);
12697                }
12698                "textDocument/completion" => {
12699                    server.update_capabilities(|capabilities| {
12700                        capabilities.completion_provider = None;
12701                    });
12702                    notify_server_capabilities_updated(&server, cx);
12703                }
12704                "textDocument/hover" => {
12705                    server.update_capabilities(|capabilities| {
12706                        capabilities.hover_provider = None;
12707                    });
12708                    notify_server_capabilities_updated(&server, cx);
12709                }
12710                "textDocument/signatureHelp" => {
12711                    server.update_capabilities(|capabilities| {
12712                        capabilities.signature_help_provider = None;
12713                    });
12714                    notify_server_capabilities_updated(&server, cx);
12715                }
12716                "textDocument/didChange" => {
12717                    server.update_capabilities(|capabilities| {
12718                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12719                        sync_options.change = None;
12720                        capabilities.text_document_sync =
12721                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12722                    });
12723                    notify_server_capabilities_updated(&server, cx);
12724                }
12725                "textDocument/didSave" => {
12726                    server.update_capabilities(|capabilities| {
12727                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12728                        sync_options.save = None;
12729                        capabilities.text_document_sync =
12730                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12731                    });
12732                    notify_server_capabilities_updated(&server, cx);
12733                }
12734                "textDocument/codeLens" => {
12735                    server.update_capabilities(|capabilities| {
12736                        capabilities.code_lens_provider = None;
12737                    });
12738                    notify_server_capabilities_updated(&server, cx);
12739                }
12740                "textDocument/diagnostic" => {
12741                    let local = self
12742                        .as_local_mut()
12743                        .context("Expected LSP Store to be local")?;
12744
12745                    let state = local
12746                        .language_servers
12747                        .get_mut(&server_id)
12748                        .context("Could not obtain Language Servers state")?;
12749                    let registrations = local
12750                        .language_server_dynamic_registrations
12751                        .get_mut(&server_id)
12752                        .with_context(|| {
12753                            format!("Expected dynamic registration to exist for server {server_id}")
12754                        })?;
12755                    registrations.diagnostics
12756                        .remove(&Some(unreg.id.clone()))
12757                        .with_context(|| format!(
12758                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12759                            unreg.id)
12760                        )?;
12761                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12762
12763                    if let LanguageServerState::Running {
12764                        workspace_diagnostics_refresh_tasks,
12765                        ..
12766                    } = state
12767                    {
12768                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12769                    }
12770
12771                    if removed_last_diagnostic_provider {
12772                        server.update_capabilities(|capabilities| {
12773                            debug_assert!(capabilities.diagnostic_provider.is_some());
12774                            capabilities.diagnostic_provider = None;
12775                        });
12776                    }
12777
12778                    notify_server_capabilities_updated(&server, cx);
12779                }
12780                "textDocument/documentColor" => {
12781                    server.update_capabilities(|capabilities| {
12782                        capabilities.color_provider = None;
12783                    });
12784                    notify_server_capabilities_updated(&server, cx);
12785                }
12786                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12787            }
12788        }
12789
12790        Ok(())
12791    }
12792
12793    async fn deduplicate_range_based_lsp_requests<T>(
12794        lsp_store: &Entity<Self>,
12795        server_id: Option<LanguageServerId>,
12796        lsp_request_id: LspRequestId,
12797        proto_request: &T::ProtoRequest,
12798        range: Range<Anchor>,
12799        cx: &mut AsyncApp,
12800    ) -> Result<()>
12801    where
12802        T: LspCommand,
12803        T::ProtoRequest: proto::LspRequestMessage,
12804    {
12805        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12806        let version = deserialize_version(proto_request.buffer_version());
12807        let buffer = lsp_store.update(cx, |this, cx| {
12808            this.buffer_store.read(cx).get_existing(buffer_id)
12809        })??;
12810        buffer
12811            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12812            .await?;
12813        lsp_store.update(cx, |lsp_store, cx| {
12814            let buffer_snapshot = buffer.read(cx).snapshot();
12815            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12816            let chunks_queried_for = lsp_data
12817                .inlay_hints
12818                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12819                .collect::<Vec<_>>();
12820            match chunks_queried_for.as_slice() {
12821                &[chunk] => {
12822                    let key = LspKey {
12823                        request_type: TypeId::of::<T>(),
12824                        server_queried: server_id,
12825                    };
12826                    let previous_request = lsp_data
12827                        .chunk_lsp_requests
12828                        .entry(key)
12829                        .or_default()
12830                        .insert(chunk, lsp_request_id);
12831                    if let Some((previous_request, running_requests)) =
12832                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12833                    {
12834                        running_requests.remove(&previous_request);
12835                    }
12836                }
12837                _ambiguous_chunks => {
12838                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12839                    // there, a buffer version-based check will be performed and outdated requests discarded.
12840                }
12841            }
12842            anyhow::Ok(())
12843        })??;
12844
12845        Ok(())
12846    }
12847
12848    async fn query_lsp_locally<T>(
12849        lsp_store: Entity<Self>,
12850        for_server_id: Option<LanguageServerId>,
12851        sender_id: proto::PeerId,
12852        lsp_request_id: LspRequestId,
12853        proto_request: T::ProtoRequest,
12854        position: Option<Anchor>,
12855        cx: &mut AsyncApp,
12856    ) -> Result<()>
12857    where
12858        T: LspCommand + Clone,
12859        T::ProtoRequest: proto::LspRequestMessage,
12860        <T::ProtoRequest as proto::RequestMessage>::Response:
12861            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12862    {
12863        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12864        let version = deserialize_version(proto_request.buffer_version());
12865        let buffer = lsp_store.update(cx, |this, cx| {
12866            this.buffer_store.read(cx).get_existing(buffer_id)
12867        })??;
12868        buffer
12869            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12870            .await?;
12871        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12872        let request =
12873            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12874        let key = LspKey {
12875            request_type: TypeId::of::<T>(),
12876            server_queried: for_server_id,
12877        };
12878        lsp_store.update(cx, |lsp_store, cx| {
12879            let request_task = match for_server_id {
12880                Some(server_id) => {
12881                    let server_task = lsp_store.request_lsp(
12882                        buffer.clone(),
12883                        LanguageServerToQuery::Other(server_id),
12884                        request.clone(),
12885                        cx,
12886                    );
12887                    cx.background_spawn(async move {
12888                        let mut responses = Vec::new();
12889                        match server_task.await {
12890                            Ok(response) => responses.push((server_id, response)),
12891                            // rust-analyzer likes to error with this when its still loading up
12892                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12893                            Err(e) => log::error!(
12894                                "Error handling response for request {request:?}: {e:#}"
12895                            ),
12896                        }
12897                        responses
12898                    })
12899                }
12900                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12901            };
12902            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12903            if T::ProtoRequest::stop_previous_requests() {
12904                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12905                    lsp_requests.clear();
12906                }
12907            }
12908            lsp_data.lsp_requests.entry(key).or_default().insert(
12909                lsp_request_id,
12910                cx.spawn(async move |lsp_store, cx| {
12911                    let response = request_task.await;
12912                    lsp_store
12913                        .update(cx, |lsp_store, cx| {
12914                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12915                            {
12916                                let response = response
12917                                    .into_iter()
12918                                    .map(|(server_id, response)| {
12919                                        (
12920                                            server_id.to_proto(),
12921                                            T::response_to_proto(
12922                                                response,
12923                                                lsp_store,
12924                                                sender_id,
12925                                                &buffer_version,
12926                                                cx,
12927                                            )
12928                                            .into(),
12929                                        )
12930                                    })
12931                                    .collect::<HashMap<_, _>>();
12932                                match client.send_lsp_response::<T::ProtoRequest>(
12933                                    project_id,
12934                                    lsp_request_id,
12935                                    response,
12936                                ) {
12937                                    Ok(()) => {}
12938                                    Err(e) => {
12939                                        log::error!("Failed to send LSP response: {e:#}",)
12940                                    }
12941                                }
12942                            }
12943                        })
12944                        .ok();
12945                }),
12946            );
12947        })?;
12948        Ok(())
12949    }
12950
12951    fn take_text_document_sync_options(
12952        capabilities: &mut lsp::ServerCapabilities,
12953    ) -> lsp::TextDocumentSyncOptions {
12954        match capabilities.text_document_sync.take() {
12955            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12956            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12957                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12958                sync_options.change = Some(sync_kind);
12959                sync_options
12960            }
12961            None => lsp::TextDocumentSyncOptions::default(),
12962        }
12963    }
12964
12965    #[cfg(any(test, feature = "test-support"))]
12966    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12967        Some(
12968            self.lsp_data
12969                .get_mut(&buffer_id)?
12970                .code_lens
12971                .take()?
12972                .update
12973                .take()?
12974                .1,
12975        )
12976    }
12977
12978    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12979        self.downstream_client.clone()
12980    }
12981
12982    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12983        self.worktree_store.clone()
12984    }
12985
12986    /// Gets what's stored in the LSP data for the given buffer.
12987    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12988        self.lsp_data.get_mut(&buffer_id)
12989    }
12990
12991    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12992    /// new [`BufferLspData`] will be created to replace the previous state.
12993    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
12994        let (buffer_id, buffer_version) =
12995            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
12996        let lsp_data = self
12997            .lsp_data
12998            .entry(buffer_id)
12999            .or_insert_with(|| BufferLspData::new(buffer, cx));
13000        if buffer_version.changed_since(&lsp_data.buffer_version) {
13001            *lsp_data = BufferLspData::new(buffer, cx);
13002        }
13003        lsp_data
13004    }
13005}
13006
13007// Registration with registerOptions as null, should fallback to true.
13008// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13009fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13010    reg: lsp::Registration,
13011) -> Result<OneOf<bool, T>> {
13012    Ok(match reg.register_options {
13013        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13014        None => OneOf::Left(true),
13015    })
13016}
13017
13018fn subscribe_to_binary_statuses(
13019    languages: &Arc<LanguageRegistry>,
13020    cx: &mut Context<'_, LspStore>,
13021) -> Task<()> {
13022    let mut server_statuses = languages.language_server_binary_statuses();
13023    cx.spawn(async move |lsp_store, cx| {
13024        while let Some((server_name, binary_status)) = server_statuses.next().await {
13025            if lsp_store
13026                .update(cx, |_, cx| {
13027                    let mut message = None;
13028                    let binary_status = match binary_status {
13029                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13030                        BinaryStatus::CheckingForUpdate => {
13031                            proto::ServerBinaryStatus::CheckingForUpdate
13032                        }
13033                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13034                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13035                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13036                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13037                        BinaryStatus::Failed { error } => {
13038                            message = Some(error);
13039                            proto::ServerBinaryStatus::Failed
13040                        }
13041                    };
13042                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13043                        // Binary updates are about the binary that might not have any language server id at that point.
13044                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13045                        language_server_id: LanguageServerId(0),
13046                        name: Some(server_name),
13047                        message: proto::update_language_server::Variant::StatusUpdate(
13048                            proto::StatusUpdate {
13049                                message,
13050                                status: Some(proto::status_update::Status::Binary(
13051                                    binary_status as i32,
13052                                )),
13053                            },
13054                        ),
13055                    });
13056                })
13057                .is_err()
13058            {
13059                break;
13060            }
13061        }
13062    })
13063}
13064
13065fn lsp_workspace_diagnostics_refresh(
13066    registration_id: Option<String>,
13067    options: DiagnosticServerCapabilities,
13068    server: Arc<LanguageServer>,
13069    cx: &mut Context<'_, LspStore>,
13070) -> Option<WorkspaceRefreshTask> {
13071    let identifier = workspace_diagnostic_identifier(&options)?;
13072    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13073
13074    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13075    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13076    refresh_tx.try_send(()).ok();
13077
13078    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13079        let mut attempts = 0;
13080        let max_attempts = 50;
13081        let mut requests = 0;
13082
13083        loop {
13084            let Some(()) = refresh_rx.recv().await else {
13085                return;
13086            };
13087
13088            'request: loop {
13089                requests += 1;
13090                if attempts > max_attempts {
13091                    log::error!(
13092                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13093                    );
13094                    return;
13095                }
13096                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13097                cx.background_executor()
13098                    .timer(Duration::from_millis(backoff_millis))
13099                    .await;
13100                attempts += 1;
13101
13102                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13103                    lsp_store
13104                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13105                        .into_iter()
13106                        .filter_map(|(abs_path, result_id)| {
13107                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13108                            Some(lsp::PreviousResultId {
13109                                uri,
13110                                value: result_id.to_string(),
13111                            })
13112                        })
13113                        .collect()
13114                }) else {
13115                    return;
13116                };
13117
13118                let token = if let Some(registration_id) = &registration_id {
13119                    format!(
13120                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13121                        server.server_id(),
13122                    )
13123                } else {
13124                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13125                };
13126
13127                progress_rx.try_recv().ok();
13128                let timer =
13129                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13130                let progress = pin!(progress_rx.recv().fuse());
13131                let response_result = server
13132                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13133                        lsp::WorkspaceDiagnosticParams {
13134                            previous_result_ids,
13135                            identifier: identifier.clone(),
13136                            work_done_progress_params: Default::default(),
13137                            partial_result_params: lsp::PartialResultParams {
13138                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13139                            },
13140                        },
13141                        select(timer, progress).then(|either| match either {
13142                            Either::Left((message, ..)) => ready(message).left_future(),
13143                            Either::Right(..) => pending::<String>().right_future(),
13144                        }),
13145                    )
13146                    .await;
13147
13148                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13149                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13150                match response_result {
13151                    ConnectionResult::Timeout => {
13152                        log::error!("Timeout during workspace diagnostics pull");
13153                        continue 'request;
13154                    }
13155                    ConnectionResult::ConnectionReset => {
13156                        log::error!("Server closed a workspace diagnostics pull request");
13157                        continue 'request;
13158                    }
13159                    ConnectionResult::Result(Err(e)) => {
13160                        log::error!("Error during workspace diagnostics pull: {e:#}");
13161                        break 'request;
13162                    }
13163                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13164                        attempts = 0;
13165                        if lsp_store
13166                            .update(cx, |lsp_store, cx| {
13167                                lsp_store.apply_workspace_diagnostic_report(
13168                                    server.server_id(),
13169                                    pulled_diagnostics,
13170                                    registration_id_shared.clone(),
13171                                    cx,
13172                                )
13173                            })
13174                            .is_err()
13175                        {
13176                            return;
13177                        }
13178                        break 'request;
13179                    }
13180                }
13181            }
13182        }
13183    });
13184
13185    Some(WorkspaceRefreshTask {
13186        refresh_tx,
13187        progress_tx,
13188        task: workspace_query_language_server,
13189    })
13190}
13191
13192fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13193    match &options {
13194        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13195            diagnostic_options.identifier.clone()
13196        }
13197        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13198            let diagnostic_options = &registration_options.diagnostic_options;
13199            diagnostic_options.identifier.clone()
13200        }
13201    }
13202}
13203
13204fn workspace_diagnostic_identifier(
13205    options: &DiagnosticServerCapabilities,
13206) -> Option<Option<String>> {
13207    match &options {
13208        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13209            if !diagnostic_options.workspace_diagnostics {
13210                return None;
13211            }
13212            Some(diagnostic_options.identifier.clone())
13213        }
13214        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13215            let diagnostic_options = &registration_options.diagnostic_options;
13216            if !diagnostic_options.workspace_diagnostics {
13217                return None;
13218            }
13219            Some(diagnostic_options.identifier.clone())
13220        }
13221    }
13222}
13223
13224fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13225    let CompletionSource::BufferWord {
13226        word_range,
13227        resolved,
13228    } = &mut completion.source
13229    else {
13230        return;
13231    };
13232    if *resolved {
13233        return;
13234    }
13235
13236    if completion.new_text
13237        != snapshot
13238            .text_for_range(word_range.clone())
13239            .collect::<String>()
13240    {
13241        return;
13242    }
13243
13244    let mut offset = 0;
13245    for chunk in snapshot.chunks(word_range.clone(), true) {
13246        let end_offset = offset + chunk.text.len();
13247        if let Some(highlight_id) = chunk.syntax_highlight_id {
13248            completion
13249                .label
13250                .runs
13251                .push((offset..end_offset, highlight_id));
13252        }
13253        offset = end_offset;
13254    }
13255    *resolved = true;
13256}
13257
13258impl EventEmitter<LspStoreEvent> for LspStore {}
13259
13260fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13261    hover
13262        .contents
13263        .retain(|hover_block| !hover_block.text.trim().is_empty());
13264    if hover.contents.is_empty() {
13265        None
13266    } else {
13267        Some(hover)
13268    }
13269}
13270
13271async fn populate_labels_for_completions(
13272    new_completions: Vec<CoreCompletion>,
13273    language: Option<Arc<Language>>,
13274    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13275) -> Vec<Completion> {
13276    let lsp_completions = new_completions
13277        .iter()
13278        .filter_map(|new_completion| {
13279            new_completion
13280                .source
13281                .lsp_completion(true)
13282                .map(|lsp_completion| lsp_completion.into_owned())
13283        })
13284        .collect::<Vec<_>>();
13285
13286    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13287        lsp_adapter
13288            .labels_for_completions(&lsp_completions, language)
13289            .await
13290            .log_err()
13291            .unwrap_or_default()
13292    } else {
13293        Vec::new()
13294    }
13295    .into_iter()
13296    .fuse();
13297
13298    let mut completions = Vec::new();
13299    for completion in new_completions {
13300        match completion.source.lsp_completion(true) {
13301            Some(lsp_completion) => {
13302                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13303
13304                let mut label = labels.next().flatten().unwrap_or_else(|| {
13305                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13306                });
13307                ensure_uniform_list_compatible_label(&mut label);
13308                completions.push(Completion {
13309                    label,
13310                    documentation,
13311                    replace_range: completion.replace_range,
13312                    new_text: completion.new_text,
13313                    insert_text_mode: lsp_completion.insert_text_mode,
13314                    source: completion.source,
13315                    icon_path: None,
13316                    confirm: None,
13317                    match_start: None,
13318                    snippet_deduplication_key: None,
13319                });
13320            }
13321            None => {
13322                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13323                ensure_uniform_list_compatible_label(&mut label);
13324                completions.push(Completion {
13325                    label,
13326                    documentation: None,
13327                    replace_range: completion.replace_range,
13328                    new_text: completion.new_text,
13329                    source: completion.source,
13330                    insert_text_mode: None,
13331                    icon_path: None,
13332                    confirm: None,
13333                    match_start: None,
13334                    snippet_deduplication_key: None,
13335                });
13336            }
13337        }
13338    }
13339    completions
13340}
13341
13342#[derive(Debug)]
13343pub enum LanguageServerToQuery {
13344    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13345    FirstCapable,
13346    /// Query a specific language server.
13347    Other(LanguageServerId),
13348}
13349
13350#[derive(Default)]
13351struct RenamePathsWatchedForServer {
13352    did_rename: Vec<RenameActionPredicate>,
13353    will_rename: Vec<RenameActionPredicate>,
13354}
13355
13356impl RenamePathsWatchedForServer {
13357    fn with_did_rename_patterns(
13358        mut self,
13359        did_rename: Option<&FileOperationRegistrationOptions>,
13360    ) -> Self {
13361        if let Some(did_rename) = did_rename {
13362            self.did_rename = did_rename
13363                .filters
13364                .iter()
13365                .filter_map(|filter| filter.try_into().log_err())
13366                .collect();
13367        }
13368        self
13369    }
13370    fn with_will_rename_patterns(
13371        mut self,
13372        will_rename: Option<&FileOperationRegistrationOptions>,
13373    ) -> Self {
13374        if let Some(will_rename) = will_rename {
13375            self.will_rename = will_rename
13376                .filters
13377                .iter()
13378                .filter_map(|filter| filter.try_into().log_err())
13379                .collect();
13380        }
13381        self
13382    }
13383
13384    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13385        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13386    }
13387    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13388        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13389    }
13390}
13391
13392impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13393    type Error = globset::Error;
13394    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13395        Ok(Self {
13396            kind: ops.pattern.matches.clone(),
13397            glob: GlobBuilder::new(&ops.pattern.glob)
13398                .case_insensitive(
13399                    ops.pattern
13400                        .options
13401                        .as_ref()
13402                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13403                )
13404                .build()?
13405                .compile_matcher(),
13406        })
13407    }
13408}
13409struct RenameActionPredicate {
13410    glob: GlobMatcher,
13411    kind: Option<FileOperationPatternKind>,
13412}
13413
13414impl RenameActionPredicate {
13415    // Returns true if language server should be notified
13416    fn eval(&self, path: &str, is_dir: bool) -> bool {
13417        self.kind.as_ref().is_none_or(|kind| {
13418            let expected_kind = if is_dir {
13419                FileOperationPatternKind::Folder
13420            } else {
13421                FileOperationPatternKind::File
13422            };
13423            kind == &expected_kind
13424        }) && self.glob.is_match(path)
13425    }
13426}
13427
13428#[derive(Default)]
13429struct LanguageServerWatchedPaths {
13430    worktree_paths: HashMap<WorktreeId, GlobSet>,
13431    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13432}
13433
13434#[derive(Default)]
13435struct LanguageServerWatchedPathsBuilder {
13436    worktree_paths: HashMap<WorktreeId, GlobSet>,
13437    abs_paths: HashMap<Arc<Path>, GlobSet>,
13438}
13439
13440impl LanguageServerWatchedPathsBuilder {
13441    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13442        self.worktree_paths.insert(worktree_id, glob_set);
13443    }
13444    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13445        self.abs_paths.insert(path, glob_set);
13446    }
13447    fn build(
13448        self,
13449        fs: Arc<dyn Fs>,
13450        language_server_id: LanguageServerId,
13451        cx: &mut Context<LspStore>,
13452    ) -> LanguageServerWatchedPaths {
13453        let lsp_store = cx.weak_entity();
13454
13455        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13456        let abs_paths = self
13457            .abs_paths
13458            .into_iter()
13459            .map(|(abs_path, globset)| {
13460                let task = cx.spawn({
13461                    let abs_path = abs_path.clone();
13462                    let fs = fs.clone();
13463
13464                    let lsp_store = lsp_store.clone();
13465                    async move |_, cx| {
13466                        maybe!(async move {
13467                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13468                            while let Some(update) = push_updates.0.next().await {
13469                                let action = lsp_store
13470                                    .update(cx, |this, _| {
13471                                        let Some(local) = this.as_local() else {
13472                                            return ControlFlow::Break(());
13473                                        };
13474                                        let Some(watcher) = local
13475                                            .language_server_watched_paths
13476                                            .get(&language_server_id)
13477                                        else {
13478                                            return ControlFlow::Break(());
13479                                        };
13480                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13481                                            "Watched abs path is not registered with a watcher",
13482                                        );
13483                                        let matching_entries = update
13484                                            .into_iter()
13485                                            .filter(|event| globs.is_match(&event.path))
13486                                            .collect::<Vec<_>>();
13487                                        this.lsp_notify_abs_paths_changed(
13488                                            language_server_id,
13489                                            matching_entries,
13490                                        );
13491                                        ControlFlow::Continue(())
13492                                    })
13493                                    .ok()?;
13494
13495                                if action.is_break() {
13496                                    break;
13497                                }
13498                            }
13499                            Some(())
13500                        })
13501                        .await;
13502                    }
13503                });
13504                (abs_path, (globset, task))
13505            })
13506            .collect();
13507        LanguageServerWatchedPaths {
13508            worktree_paths: self.worktree_paths,
13509            abs_paths,
13510        }
13511    }
13512}
13513
13514struct LspBufferSnapshot {
13515    version: i32,
13516    snapshot: TextBufferSnapshot,
13517}
13518
13519/// A prompt requested by LSP server.
13520#[derive(Clone, Debug)]
13521pub struct LanguageServerPromptRequest {
13522    pub level: PromptLevel,
13523    pub message: String,
13524    pub actions: Vec<MessageActionItem>,
13525    pub lsp_name: String,
13526    pub(crate) response_channel: Sender<MessageActionItem>,
13527}
13528
13529impl LanguageServerPromptRequest {
13530    pub async fn respond(self, index: usize) -> Option<()> {
13531        if let Some(response) = self.actions.into_iter().nth(index) {
13532            self.response_channel.send(response).await.ok()
13533        } else {
13534            None
13535        }
13536    }
13537}
13538impl PartialEq for LanguageServerPromptRequest {
13539    fn eq(&self, other: &Self) -> bool {
13540        self.message == other.message && self.actions == other.actions
13541    }
13542}
13543
13544#[derive(Clone, Debug, PartialEq)]
13545pub enum LanguageServerLogType {
13546    Log(MessageType),
13547    Trace { verbose_info: Option<String> },
13548    Rpc { received: bool },
13549}
13550
13551impl LanguageServerLogType {
13552    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13553        match self {
13554            Self::Log(log_type) => {
13555                use proto::log_message::LogLevel;
13556                let level = match *log_type {
13557                    MessageType::ERROR => LogLevel::Error,
13558                    MessageType::WARNING => LogLevel::Warning,
13559                    MessageType::INFO => LogLevel::Info,
13560                    MessageType::LOG => LogLevel::Log,
13561                    other => {
13562                        log::warn!("Unknown lsp log message type: {other:?}");
13563                        LogLevel::Log
13564                    }
13565                };
13566                proto::language_server_log::LogType::Log(proto::LogMessage {
13567                    level: level as i32,
13568                })
13569            }
13570            Self::Trace { verbose_info } => {
13571                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13572                    verbose_info: verbose_info.to_owned(),
13573                })
13574            }
13575            Self::Rpc { received } => {
13576                let kind = if *received {
13577                    proto::rpc_message::Kind::Received
13578                } else {
13579                    proto::rpc_message::Kind::Sent
13580                };
13581                let kind = kind as i32;
13582                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13583            }
13584        }
13585    }
13586
13587    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13588        use proto::log_message::LogLevel;
13589        use proto::rpc_message;
13590        match log_type {
13591            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13592                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13593                    LogLevel::Error => MessageType::ERROR,
13594                    LogLevel::Warning => MessageType::WARNING,
13595                    LogLevel::Info => MessageType::INFO,
13596                    LogLevel::Log => MessageType::LOG,
13597                },
13598            ),
13599            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13600                verbose_info: trace_message.verbose_info,
13601            },
13602            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13603                received: match rpc_message::Kind::from_i32(message.kind)
13604                    .unwrap_or(rpc_message::Kind::Received)
13605                {
13606                    rpc_message::Kind::Received => true,
13607                    rpc_message::Kind::Sent => false,
13608                },
13609            },
13610        }
13611    }
13612}
13613
13614pub struct WorkspaceRefreshTask {
13615    refresh_tx: mpsc::Sender<()>,
13616    progress_tx: mpsc::Sender<()>,
13617    #[allow(dead_code)]
13618    task: Task<()>,
13619}
13620
13621pub enum LanguageServerState {
13622    Starting {
13623        startup: Task<Option<Arc<LanguageServer>>>,
13624        /// List of language servers that will be added to the workspace once it's initialization completes.
13625        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13626    },
13627
13628    Running {
13629        adapter: Arc<CachedLspAdapter>,
13630        server: Arc<LanguageServer>,
13631        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13632        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13633    },
13634}
13635
13636impl LanguageServerState {
13637    fn add_workspace_folder(&self, uri: Uri) {
13638        match self {
13639            LanguageServerState::Starting {
13640                pending_workspace_folders,
13641                ..
13642            } => {
13643                pending_workspace_folders.lock().insert(uri);
13644            }
13645            LanguageServerState::Running { server, .. } => {
13646                server.add_workspace_folder(uri);
13647            }
13648        }
13649    }
13650    fn _remove_workspace_folder(&self, uri: Uri) {
13651        match self {
13652            LanguageServerState::Starting {
13653                pending_workspace_folders,
13654                ..
13655            } => {
13656                pending_workspace_folders.lock().remove(&uri);
13657            }
13658            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13659        }
13660    }
13661}
13662
13663impl std::fmt::Debug for LanguageServerState {
13664    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13665        match self {
13666            LanguageServerState::Starting { .. } => {
13667                f.debug_struct("LanguageServerState::Starting").finish()
13668            }
13669            LanguageServerState::Running { .. } => {
13670                f.debug_struct("LanguageServerState::Running").finish()
13671            }
13672        }
13673    }
13674}
13675
13676#[derive(Clone, Debug, Serialize)]
13677pub struct LanguageServerProgress {
13678    pub is_disk_based_diagnostics_progress: bool,
13679    pub is_cancellable: bool,
13680    pub title: Option<String>,
13681    pub message: Option<String>,
13682    pub percentage: Option<usize>,
13683    #[serde(skip_serializing)]
13684    pub last_update_at: Instant,
13685}
13686
13687#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13688pub struct DiagnosticSummary {
13689    pub error_count: usize,
13690    pub warning_count: usize,
13691}
13692
13693impl DiagnosticSummary {
13694    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13695        let mut this = Self {
13696            error_count: 0,
13697            warning_count: 0,
13698        };
13699
13700        for entry in diagnostics {
13701            if entry.diagnostic.is_primary {
13702                match entry.diagnostic.severity {
13703                    DiagnosticSeverity::ERROR => this.error_count += 1,
13704                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13705                    _ => {}
13706                }
13707            }
13708        }
13709
13710        this
13711    }
13712
13713    pub fn is_empty(&self) -> bool {
13714        self.error_count == 0 && self.warning_count == 0
13715    }
13716
13717    pub fn to_proto(
13718        self,
13719        language_server_id: LanguageServerId,
13720        path: &RelPath,
13721    ) -> proto::DiagnosticSummary {
13722        proto::DiagnosticSummary {
13723            path: path.to_proto(),
13724            language_server_id: language_server_id.0 as u64,
13725            error_count: self.error_count as u32,
13726            warning_count: self.warning_count as u32,
13727        }
13728    }
13729}
13730
13731#[derive(Clone, Debug)]
13732pub enum CompletionDocumentation {
13733    /// There is no documentation for this completion.
13734    Undocumented,
13735    /// A single line of documentation.
13736    SingleLine(SharedString),
13737    /// Multiple lines of plain text documentation.
13738    MultiLinePlainText(SharedString),
13739    /// Markdown documentation.
13740    MultiLineMarkdown(SharedString),
13741    /// Both single line and multiple lines of plain text documentation.
13742    SingleLineAndMultiLinePlainText {
13743        single_line: SharedString,
13744        plain_text: Option<SharedString>,
13745    },
13746}
13747
13748impl CompletionDocumentation {
13749    #[cfg(any(test, feature = "test-support"))]
13750    pub fn text(&self) -> SharedString {
13751        match self {
13752            CompletionDocumentation::Undocumented => "".into(),
13753            CompletionDocumentation::SingleLine(s) => s.clone(),
13754            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13755            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13756            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13757                single_line.clone()
13758            }
13759        }
13760    }
13761}
13762
13763impl From<lsp::Documentation> for CompletionDocumentation {
13764    fn from(docs: lsp::Documentation) -> Self {
13765        match docs {
13766            lsp::Documentation::String(text) => {
13767                if text.lines().count() <= 1 {
13768                    CompletionDocumentation::SingleLine(text.into())
13769                } else {
13770                    CompletionDocumentation::MultiLinePlainText(text.into())
13771                }
13772            }
13773
13774            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13775                lsp::MarkupKind::PlainText => {
13776                    if value.lines().count() <= 1 {
13777                        CompletionDocumentation::SingleLine(value.into())
13778                    } else {
13779                        CompletionDocumentation::MultiLinePlainText(value.into())
13780                    }
13781                }
13782
13783                lsp::MarkupKind::Markdown => {
13784                    CompletionDocumentation::MultiLineMarkdown(value.into())
13785                }
13786            },
13787        }
13788    }
13789}
13790
13791pub enum ResolvedHint {
13792    Resolved(InlayHint),
13793    Resolving(Shared<Task<()>>),
13794}
13795
13796fn glob_literal_prefix(glob: &Path) -> PathBuf {
13797    glob.components()
13798        .take_while(|component| match component {
13799            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13800            _ => true,
13801        })
13802        .collect()
13803}
13804
13805pub struct SshLspAdapter {
13806    name: LanguageServerName,
13807    binary: LanguageServerBinary,
13808    initialization_options: Option<String>,
13809    code_action_kinds: Option<Vec<CodeActionKind>>,
13810}
13811
13812impl SshLspAdapter {
13813    pub fn new(
13814        name: LanguageServerName,
13815        binary: LanguageServerBinary,
13816        initialization_options: Option<String>,
13817        code_action_kinds: Option<String>,
13818    ) -> Self {
13819        Self {
13820            name,
13821            binary,
13822            initialization_options,
13823            code_action_kinds: code_action_kinds
13824                .as_ref()
13825                .and_then(|c| serde_json::from_str(c).ok()),
13826        }
13827    }
13828}
13829
13830impl LspInstaller for SshLspAdapter {
13831    type BinaryVersion = ();
13832    async fn check_if_user_installed(
13833        &self,
13834        _: &dyn LspAdapterDelegate,
13835        _: Option<Toolchain>,
13836        _: &AsyncApp,
13837    ) -> Option<LanguageServerBinary> {
13838        Some(self.binary.clone())
13839    }
13840
13841    async fn cached_server_binary(
13842        &self,
13843        _: PathBuf,
13844        _: &dyn LspAdapterDelegate,
13845    ) -> Option<LanguageServerBinary> {
13846        None
13847    }
13848
13849    async fn fetch_latest_server_version(
13850        &self,
13851        _: &dyn LspAdapterDelegate,
13852        _: bool,
13853        _: &mut AsyncApp,
13854    ) -> Result<()> {
13855        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13856    }
13857
13858    async fn fetch_server_binary(
13859        &self,
13860        _: (),
13861        _: PathBuf,
13862        _: &dyn LspAdapterDelegate,
13863    ) -> Result<LanguageServerBinary> {
13864        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13865    }
13866}
13867
13868#[async_trait(?Send)]
13869impl LspAdapter for SshLspAdapter {
13870    fn name(&self) -> LanguageServerName {
13871        self.name.clone()
13872    }
13873
13874    async fn initialization_options(
13875        self: Arc<Self>,
13876        _: &Arc<dyn LspAdapterDelegate>,
13877    ) -> Result<Option<serde_json::Value>> {
13878        let Some(options) = &self.initialization_options else {
13879            return Ok(None);
13880        };
13881        let result = serde_json::from_str(options)?;
13882        Ok(result)
13883    }
13884
13885    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13886        self.code_action_kinds.clone()
13887    }
13888}
13889
13890pub fn language_server_settings<'a>(
13891    delegate: &'a dyn LspAdapterDelegate,
13892    language: &LanguageServerName,
13893    cx: &'a App,
13894) -> Option<&'a LspSettings> {
13895    language_server_settings_for(
13896        SettingsLocation {
13897            worktree_id: delegate.worktree_id(),
13898            path: RelPath::empty(),
13899        },
13900        language,
13901        cx,
13902    )
13903}
13904
13905pub fn language_server_settings_for<'a>(
13906    location: SettingsLocation<'a>,
13907    language: &LanguageServerName,
13908    cx: &'a App,
13909) -> Option<&'a LspSettings> {
13910    ProjectSettings::get(Some(location), cx).lsp.get(language)
13911}
13912
13913pub struct LocalLspAdapterDelegate {
13914    lsp_store: WeakEntity<LspStore>,
13915    worktree: worktree::Snapshot,
13916    fs: Arc<dyn Fs>,
13917    http_client: Arc<dyn HttpClient>,
13918    language_registry: Arc<LanguageRegistry>,
13919    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13920}
13921
13922impl LocalLspAdapterDelegate {
13923    pub fn new(
13924        language_registry: Arc<LanguageRegistry>,
13925        environment: &Entity<ProjectEnvironment>,
13926        lsp_store: WeakEntity<LspStore>,
13927        worktree: &Entity<Worktree>,
13928        http_client: Arc<dyn HttpClient>,
13929        fs: Arc<dyn Fs>,
13930        cx: &mut App,
13931    ) -> Arc<Self> {
13932        let load_shell_env_task =
13933            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
13934
13935        Arc::new(Self {
13936            lsp_store,
13937            worktree: worktree.read(cx).snapshot(),
13938            fs,
13939            http_client,
13940            language_registry,
13941            load_shell_env_task,
13942        })
13943    }
13944
13945    fn from_local_lsp(
13946        local: &LocalLspStore,
13947        worktree: &Entity<Worktree>,
13948        cx: &mut App,
13949    ) -> Arc<Self> {
13950        Self::new(
13951            local.languages.clone(),
13952            &local.environment,
13953            local.weak.clone(),
13954            worktree,
13955            local.http_client.clone(),
13956            local.fs.clone(),
13957            cx,
13958        )
13959    }
13960}
13961
13962#[async_trait]
13963impl LspAdapterDelegate for LocalLspAdapterDelegate {
13964    fn show_notification(&self, message: &str, cx: &mut App) {
13965        self.lsp_store
13966            .update(cx, |_, cx| {
13967                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13968            })
13969            .ok();
13970    }
13971
13972    fn http_client(&self) -> Arc<dyn HttpClient> {
13973        self.http_client.clone()
13974    }
13975
13976    fn worktree_id(&self) -> WorktreeId {
13977        self.worktree.id()
13978    }
13979
13980    fn worktree_root_path(&self) -> &Path {
13981        self.worktree.abs_path().as_ref()
13982    }
13983
13984    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
13985        self.worktree.resolve_executable_path(path)
13986    }
13987
13988    async fn shell_env(&self) -> HashMap<String, String> {
13989        let task = self.load_shell_env_task.clone();
13990        task.await.unwrap_or_default()
13991    }
13992
13993    async fn npm_package_installed_version(
13994        &self,
13995        package_name: &str,
13996    ) -> Result<Option<(PathBuf, Version)>> {
13997        let local_package_directory = self.worktree_root_path();
13998        let node_modules_directory = local_package_directory.join("node_modules");
13999
14000        if let Some(version) =
14001            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14002        {
14003            return Ok(Some((node_modules_directory, version)));
14004        }
14005        let Some(npm) = self.which("npm".as_ref()).await else {
14006            log::warn!(
14007                "Failed to find npm executable for {:?}",
14008                local_package_directory
14009            );
14010            return Ok(None);
14011        };
14012
14013        let env = self.shell_env().await;
14014        let output = util::command::new_smol_command(&npm)
14015            .args(["root", "-g"])
14016            .envs(env)
14017            .current_dir(local_package_directory)
14018            .output()
14019            .await?;
14020        let global_node_modules =
14021            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14022
14023        if let Some(version) =
14024            read_package_installed_version(global_node_modules.clone(), package_name).await?
14025        {
14026            return Ok(Some((global_node_modules, version)));
14027        }
14028        return Ok(None);
14029    }
14030
14031    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14032        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14033        if self.fs.is_file(&worktree_abs_path).await {
14034            worktree_abs_path.pop();
14035        }
14036
14037        let env = self.shell_env().await;
14038
14039        let shell_path = env.get("PATH").cloned();
14040
14041        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14042    }
14043
14044    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14045        let mut working_dir = self.worktree_root_path().to_path_buf();
14046        if self.fs.is_file(&working_dir).await {
14047            working_dir.pop();
14048        }
14049        let output = util::command::new_smol_command(&command.path)
14050            .args(command.arguments)
14051            .envs(command.env.clone().unwrap_or_default())
14052            .current_dir(working_dir)
14053            .output()
14054            .await?;
14055
14056        anyhow::ensure!(
14057            output.status.success(),
14058            "{}, stdout: {:?}, stderr: {:?}",
14059            output.status,
14060            String::from_utf8_lossy(&output.stdout),
14061            String::from_utf8_lossy(&output.stderr)
14062        );
14063        Ok(())
14064    }
14065
14066    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14067        self.language_registry
14068            .update_lsp_binary_status(server_name, status);
14069    }
14070
14071    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14072        self.language_registry
14073            .all_lsp_adapters()
14074            .into_iter()
14075            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14076            .collect()
14077    }
14078
14079    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14080        let dir = self.language_registry.language_server_download_dir(name)?;
14081
14082        if !dir.exists() {
14083            smol::fs::create_dir_all(&dir)
14084                .await
14085                .context("failed to create container directory")
14086                .log_err()?;
14087        }
14088
14089        Some(dir)
14090    }
14091
14092    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14093        let entry = self
14094            .worktree
14095            .entry_for_path(path)
14096            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14097        let abs_path = self.worktree.absolutize(&entry.path);
14098        self.fs.load(&abs_path).await
14099    }
14100}
14101
14102async fn populate_labels_for_symbols(
14103    symbols: Vec<CoreSymbol>,
14104    language_registry: &Arc<LanguageRegistry>,
14105    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14106    output: &mut Vec<Symbol>,
14107) {
14108    #[allow(clippy::mutable_key_type)]
14109    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14110
14111    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14112    for symbol in symbols {
14113        let Some(file_name) = symbol.path.file_name() else {
14114            continue;
14115        };
14116        let language = language_registry
14117            .load_language_for_file_path(Path::new(file_name))
14118            .await
14119            .ok()
14120            .or_else(|| {
14121                unknown_paths.insert(file_name.into());
14122                None
14123            });
14124        symbols_by_language
14125            .entry(language)
14126            .or_default()
14127            .push(symbol);
14128    }
14129
14130    for unknown_path in unknown_paths {
14131        log::info!("no language found for symbol in file {unknown_path:?}");
14132    }
14133
14134    let mut label_params = Vec::new();
14135    for (language, mut symbols) in symbols_by_language {
14136        label_params.clear();
14137        label_params.extend(
14138            symbols
14139                .iter_mut()
14140                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14141        );
14142
14143        let mut labels = Vec::new();
14144        if let Some(language) = language {
14145            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14146                language_registry
14147                    .lsp_adapters(&language.name())
14148                    .first()
14149                    .cloned()
14150            });
14151            if let Some(lsp_adapter) = lsp_adapter {
14152                labels = lsp_adapter
14153                    .labels_for_symbols(&label_params, &language)
14154                    .await
14155                    .log_err()
14156                    .unwrap_or_default();
14157            }
14158        }
14159
14160        for ((symbol, (name, _)), label) in symbols
14161            .into_iter()
14162            .zip(label_params.drain(..))
14163            .zip(labels.into_iter().chain(iter::repeat(None)))
14164        {
14165            output.push(Symbol {
14166                language_server_name: symbol.language_server_name,
14167                source_worktree_id: symbol.source_worktree_id,
14168                source_language_server_id: symbol.source_language_server_id,
14169                path: symbol.path,
14170                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14171                name,
14172                kind: symbol.kind,
14173                range: symbol.range,
14174            });
14175        }
14176    }
14177}
14178
14179fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14180    match server.capabilities().text_document_sync.as_ref()? {
14181        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14182            // Server wants didSave but didn't specify includeText.
14183            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14184            // Server doesn't want didSave at all.
14185            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14186            // Server provided SaveOptions.
14187            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14188                Some(save_options.include_text.unwrap_or(false))
14189            }
14190        },
14191        // We do not have any save info. Kind affects didChange only.
14192        lsp::TextDocumentSyncCapability::Kind(_) => None,
14193    }
14194}
14195
14196/// Completion items are displayed in a `UniformList`.
14197/// Usually, those items are single-line strings, but in LSP responses,
14198/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14199/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14200/// 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,
14201/// breaking the completions menu presentation.
14202///
14203/// 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.
14204fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14205    let mut new_text = String::with_capacity(label.text.len());
14206    let mut offset_map = vec![0; label.text.len() + 1];
14207    let mut last_char_was_space = false;
14208    let mut new_idx = 0;
14209    let chars = label.text.char_indices().fuse();
14210    let mut newlines_removed = false;
14211
14212    for (idx, c) in chars {
14213        offset_map[idx] = new_idx;
14214
14215        match c {
14216            '\n' if last_char_was_space => {
14217                newlines_removed = true;
14218            }
14219            '\t' | ' ' if last_char_was_space => {}
14220            '\n' if !last_char_was_space => {
14221                new_text.push(' ');
14222                new_idx += 1;
14223                last_char_was_space = true;
14224                newlines_removed = true;
14225            }
14226            ' ' | '\t' => {
14227                new_text.push(' ');
14228                new_idx += 1;
14229                last_char_was_space = true;
14230            }
14231            _ => {
14232                new_text.push(c);
14233                new_idx += c.len_utf8();
14234                last_char_was_space = false;
14235            }
14236        }
14237    }
14238    offset_map[label.text.len()] = new_idx;
14239
14240    // Only modify the label if newlines were removed.
14241    if !newlines_removed {
14242        return;
14243    }
14244
14245    let last_index = new_idx;
14246    let mut run_ranges_errors = Vec::new();
14247    label.runs.retain_mut(|(range, _)| {
14248        match offset_map.get(range.start) {
14249            Some(&start) => range.start = start,
14250            None => {
14251                run_ranges_errors.push(range.clone());
14252                return false;
14253            }
14254        }
14255
14256        match offset_map.get(range.end) {
14257            Some(&end) => range.end = end,
14258            None => {
14259                run_ranges_errors.push(range.clone());
14260                range.end = last_index;
14261            }
14262        }
14263        true
14264    });
14265    if !run_ranges_errors.is_empty() {
14266        log::error!(
14267            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14268            label.text
14269        );
14270    }
14271
14272    let mut wrong_filter_range = None;
14273    if label.filter_range == (0..label.text.len()) {
14274        label.filter_range = 0..new_text.len();
14275    } else {
14276        let mut original_filter_range = Some(label.filter_range.clone());
14277        match offset_map.get(label.filter_range.start) {
14278            Some(&start) => label.filter_range.start = start,
14279            None => {
14280                wrong_filter_range = original_filter_range.take();
14281                label.filter_range.start = last_index;
14282            }
14283        }
14284
14285        match offset_map.get(label.filter_range.end) {
14286            Some(&end) => label.filter_range.end = end,
14287            None => {
14288                wrong_filter_range = original_filter_range.take();
14289                label.filter_range.end = last_index;
14290            }
14291        }
14292    }
14293    if let Some(wrong_filter_range) = wrong_filter_range {
14294        log::error!(
14295            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14296            label.text
14297        );
14298    }
14299
14300    label.text = new_text;
14301}
14302
14303#[cfg(test)]
14304mod tests {
14305    use language::HighlightId;
14306
14307    use super::*;
14308
14309    #[test]
14310    fn test_glob_literal_prefix() {
14311        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14312        assert_eq!(
14313            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14314            Path::new("node_modules")
14315        );
14316        assert_eq!(
14317            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14318            Path::new("foo")
14319        );
14320        assert_eq!(
14321            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14322            Path::new("foo/bar/baz.js")
14323        );
14324
14325        #[cfg(target_os = "windows")]
14326        {
14327            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14328            assert_eq!(
14329                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14330                Path::new("node_modules")
14331            );
14332            assert_eq!(
14333                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14334                Path::new("foo")
14335            );
14336            assert_eq!(
14337                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14338                Path::new("foo/bar/baz.js")
14339            );
14340        }
14341    }
14342
14343    #[test]
14344    fn test_multi_len_chars_normalization() {
14345        let mut label = CodeLabel::new(
14346            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14347            0..6,
14348            vec![(0..6, HighlightId(1))],
14349        );
14350        ensure_uniform_list_compatible_label(&mut label);
14351        assert_eq!(
14352            label,
14353            CodeLabel::new(
14354                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14355                0..6,
14356                vec![(0..6, HighlightId(1))],
14357            )
14358        );
14359    }
14360}