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 serde::Serialize;
   97use serde_json::Value;
   98use settings::{Settings, SettingsLocation, SettingsStore};
   99use sha2::{Digest, Sha256};
  100use smol::channel::{Receiver, Sender};
  101use snippet::Snippet;
  102use std::{
  103    any::TypeId,
  104    borrow::Cow,
  105    cell::RefCell,
  106    cmp::{Ordering, Reverse},
  107    collections::hash_map,
  108    convert::TryInto,
  109    ffi::OsStr,
  110    future::ready,
  111    iter, mem,
  112    ops::{ControlFlow, Range},
  113    path::{self, Path, PathBuf},
  114    pin::pin,
  115    rc::Rc,
  116    sync::{
  117        Arc,
  118        atomic::{self, AtomicUsize},
  119    },
  120    time::{Duration, Instant},
  121    vec,
  122};
  123use sum_tree::Dimensions;
  124use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  125
  126use util::{
  127    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  128    paths::{PathStyle, SanitizedPath},
  129    post_inc,
  130    rel_path::RelPath,
  131};
  132
  133pub use fs::*;
  134pub use language::Location;
  135pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  136#[cfg(any(test, feature = "test-support"))]
  137pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  138pub use worktree::{
  139    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  140    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  141};
  142
  143const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  144pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  145const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  146const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  147
  148#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  149pub enum ProgressToken {
  150    Number(i32),
  151    String(SharedString),
  152}
  153
  154impl std::fmt::Display for ProgressToken {
  155    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  156        match self {
  157            Self::Number(number) => write!(f, "{number}"),
  158            Self::String(string) => write!(f, "{string}"),
  159        }
  160    }
  161}
  162
  163impl ProgressToken {
  164    fn from_lsp(value: lsp::NumberOrString) -> Self {
  165        match value {
  166            lsp::NumberOrString::Number(number) => Self::Number(number),
  167            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  168        }
  169    }
  170
  171    fn to_lsp(&self) -> lsp::NumberOrString {
  172        match self {
  173            Self::Number(number) => lsp::NumberOrString::Number(*number),
  174            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  175        }
  176    }
  177
  178    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  179        Some(match value.value? {
  180            proto::progress_token::Value::Number(number) => Self::Number(number),
  181            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  182        })
  183    }
  184
  185    fn to_proto(&self) -> proto::ProgressToken {
  186        proto::ProgressToken {
  187            value: Some(match self {
  188                Self::Number(number) => proto::progress_token::Value::Number(*number),
  189                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  190            }),
  191        }
  192    }
  193}
  194
  195#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  196pub enum FormatTrigger {
  197    Save,
  198    Manual,
  199}
  200
  201pub enum LspFormatTarget {
  202    Buffers,
  203    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  204}
  205
  206#[derive(Clone, PartialEq, Eq, Hash)]
  207pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  208
  209struct OpenLspBuffer(Entity<Buffer>);
  210
  211impl FormatTrigger {
  212    fn from_proto(value: i32) -> FormatTrigger {
  213        match value {
  214            0 => FormatTrigger::Save,
  215            1 => FormatTrigger::Manual,
  216            _ => FormatTrigger::Save,
  217        }
  218    }
  219}
  220
  221#[derive(Clone)]
  222struct UnifiedLanguageServer {
  223    id: LanguageServerId,
  224    project_roots: HashSet<Arc<RelPath>>,
  225}
  226
  227#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  228struct LanguageServerSeed {
  229    worktree_id: WorktreeId,
  230    name: LanguageServerName,
  231    toolchain: Option<Toolchain>,
  232    settings: Arc<LspSettings>,
  233}
  234
  235#[derive(Debug)]
  236pub struct DocumentDiagnosticsUpdate<'a, D> {
  237    pub diagnostics: D,
  238    pub result_id: Option<SharedString>,
  239    pub registration_id: Option<SharedString>,
  240    pub server_id: LanguageServerId,
  241    pub disk_based_sources: Cow<'a, [String]>,
  242}
  243
  244pub struct DocumentDiagnostics {
  245    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  246    document_abs_path: PathBuf,
  247    version: Option<i32>,
  248}
  249
  250#[derive(Default, Debug)]
  251struct DynamicRegistrations {
  252    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  253    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  254}
  255
  256pub struct LocalLspStore {
  257    weak: WeakEntity<LspStore>,
  258    worktree_store: Entity<WorktreeStore>,
  259    toolchain_store: Entity<LocalToolchainStore>,
  260    http_client: Arc<dyn HttpClient>,
  261    environment: Entity<ProjectEnvironment>,
  262    fs: Arc<dyn Fs>,
  263    languages: Arc<LanguageRegistry>,
  264    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  265    yarn: Entity<YarnPathStore>,
  266    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  267    buffers_being_formatted: HashSet<BufferId>,
  268    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  269    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  270    watched_manifest_filenames: HashSet<ManifestName>,
  271    language_server_paths_watched_for_rename:
  272        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  273    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  274    supplementary_language_servers:
  275        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  276    prettier_store: Entity<PrettierStore>,
  277    next_diagnostic_group_id: usize,
  278    diagnostics: HashMap<
  279        WorktreeId,
  280        HashMap<
  281            Arc<RelPath>,
  282            Vec<(
  283                LanguageServerId,
  284                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  285            )>,
  286        >,
  287    >,
  288    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  289    _subscription: gpui::Subscription,
  290    lsp_tree: LanguageServerTree,
  291    registered_buffers: HashMap<BufferId, usize>,
  292    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  293    buffer_pull_diagnostics_result_ids: HashMap<
  294        LanguageServerId,
  295        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  296    >,
  297    workspace_pull_diagnostics_result_ids: HashMap<
  298        LanguageServerId,
  299        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  300    >,
  301    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, Receiver<()>)>,
  302}
  303
  304impl LocalLspStore {
  305    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  306    pub fn running_language_server_for_id(
  307        &self,
  308        id: LanguageServerId,
  309    ) -> Option<&Arc<LanguageServer>> {
  310        let language_server_state = self.language_servers.get(&id)?;
  311
  312        match language_server_state {
  313            LanguageServerState::Running { server, .. } => Some(server),
  314            LanguageServerState::Starting { .. } => None,
  315        }
  316    }
  317
  318    fn get_or_insert_language_server(
  319        &mut self,
  320        worktree_handle: &Entity<Worktree>,
  321        delegate: Arc<LocalLspAdapterDelegate>,
  322        disposition: &Arc<LaunchDisposition>,
  323        language_name: &LanguageName,
  324        cx: &mut App,
  325    ) -> LanguageServerId {
  326        let key = LanguageServerSeed {
  327            worktree_id: worktree_handle.read(cx).id(),
  328            name: disposition.server_name.clone(),
  329            settings: disposition.settings.clone(),
  330            toolchain: disposition.toolchain.clone(),
  331        };
  332        if let Some(state) = self.language_server_ids.get_mut(&key) {
  333            state.project_roots.insert(disposition.path.path.clone());
  334            state.id
  335        } else {
  336            let adapter = self
  337                .languages
  338                .lsp_adapters(language_name)
  339                .into_iter()
  340                .find(|adapter| adapter.name() == disposition.server_name)
  341                .expect("To find LSP adapter");
  342            let new_language_server_id = self.start_language_server(
  343                worktree_handle,
  344                delegate,
  345                adapter,
  346                disposition.settings.clone(),
  347                key.clone(),
  348                cx,
  349            );
  350            if let Some(state) = self.language_server_ids.get_mut(&key) {
  351                state.project_roots.insert(disposition.path.path.clone());
  352            } else {
  353                debug_assert!(
  354                    false,
  355                    "Expected `start_language_server` to ensure that `key` exists in a map"
  356                );
  357            }
  358            new_language_server_id
  359        }
  360    }
  361
  362    fn start_language_server(
  363        &mut self,
  364        worktree_handle: &Entity<Worktree>,
  365        delegate: Arc<LocalLspAdapterDelegate>,
  366        adapter: Arc<CachedLspAdapter>,
  367        settings: Arc<LspSettings>,
  368        key: LanguageServerSeed,
  369        cx: &mut App,
  370    ) -> LanguageServerId {
  371        let worktree = worktree_handle.read(cx);
  372
  373        let worktree_id = worktree.id();
  374        let worktree_abs_path = worktree.abs_path();
  375        let toolchain = key.toolchain.clone();
  376        let override_options = settings.initialization_options.clone();
  377
  378        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  379
  380        let server_id = self.languages.next_language_server_id();
  381        log::trace!(
  382            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  383            adapter.name.0
  384        );
  385
  386        let untrusted_worktree_task =
  387            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  388                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  389                    trusted_worktrees.can_trust(worktree_id, cx)
  390                });
  391                if can_trust {
  392                    self.restricted_worktrees_tasks.remove(&worktree_id);
  393                    None
  394                } else {
  395                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  396                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  397                        hash_map::Entry::Vacant(v) => {
  398                            let (tx, rx) = smol::channel::bounded::<()>(1);
  399                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, _| {
  400                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  401                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  402                                        tx.send_blocking(()).ok();
  403                                    }
  404                                }
  405                            });
  406                            v.insert((subscription, rx.clone()));
  407                            Some(rx)
  408                        }
  409                    }
  410                }
  411            });
  412        let update_binary_status = untrusted_worktree_task.is_none();
  413
  414        let binary = self.get_language_server_binary(
  415            worktree_abs_path.clone(),
  416            adapter.clone(),
  417            settings,
  418            toolchain.clone(),
  419            delegate.clone(),
  420            true,
  421            untrusted_worktree_task,
  422            cx,
  423        );
  424        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  425
  426        let pending_server = cx.spawn({
  427            let adapter = adapter.clone();
  428            let server_name = adapter.name.clone();
  429            let stderr_capture = stderr_capture.clone();
  430            #[cfg(any(test, feature = "test-support"))]
  431            let lsp_store = self.weak.clone();
  432            let pending_workspace_folders = pending_workspace_folders.clone();
  433            async move |cx| {
  434                let binary = binary.await?;
  435                #[cfg(any(test, feature = "test-support"))]
  436                if let Some(server) = lsp_store
  437                    .update(&mut cx.clone(), |this, cx| {
  438                        this.languages.create_fake_language_server(
  439                            server_id,
  440                            &server_name,
  441                            binary.clone(),
  442                            &mut cx.to_async(),
  443                        )
  444                    })
  445                    .ok()
  446                    .flatten()
  447                {
  448                    return Ok(server);
  449                }
  450
  451                let code_action_kinds = adapter.code_action_kinds();
  452                lsp::LanguageServer::new(
  453                    stderr_capture,
  454                    server_id,
  455                    server_name,
  456                    binary,
  457                    &worktree_abs_path,
  458                    code_action_kinds,
  459                    Some(pending_workspace_folders),
  460                    cx,
  461                )
  462            }
  463        });
  464
  465        let startup = {
  466            let server_name = adapter.name.0.clone();
  467            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  468            let key = key.clone();
  469            let adapter = adapter.clone();
  470            let lsp_store = self.weak.clone();
  471            let pending_workspace_folders = pending_workspace_folders.clone();
  472
  473            let pull_diagnostics = ProjectSettings::get_global(cx)
  474                .diagnostics
  475                .lsp_pull_diagnostics
  476                .enabled;
  477            cx.spawn(async move |cx| {
  478                let result = async {
  479                    let language_server = pending_server.await?;
  480
  481                    let workspace_config = Self::workspace_configuration_for_adapter(
  482                        adapter.adapter.clone(),
  483                        &delegate,
  484                        toolchain,
  485                        None,
  486                        cx,
  487                    )
  488                    .await?;
  489
  490                    let mut initialization_options = Self::initialization_options_for_adapter(
  491                        adapter.adapter.clone(),
  492                        &delegate,
  493                    )
  494                    .await?;
  495
  496                    match (&mut initialization_options, override_options) {
  497                        (Some(initialization_options), Some(override_options)) => {
  498                            merge_json_value_into(override_options, initialization_options);
  499                        }
  500                        (None, override_options) => initialization_options = override_options,
  501                        _ => {}
  502                    }
  503
  504                    let initialization_params = cx.update(|cx| {
  505                        let mut params =
  506                            language_server.default_initialize_params(pull_diagnostics, cx);
  507                        params.initialization_options = initialization_options;
  508                        adapter.adapter.prepare_initialize_params(params, cx)
  509                    })??;
  510
  511                    Self::setup_lsp_messages(
  512                        lsp_store.clone(),
  513                        &language_server,
  514                        delegate.clone(),
  515                        adapter.clone(),
  516                    );
  517
  518                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  519                        settings: workspace_config,
  520                    };
  521                    let language_server = cx
  522                        .update(|cx| {
  523                            language_server.initialize(
  524                                initialization_params,
  525                                Arc::new(did_change_configuration_params.clone()),
  526                                cx,
  527                            )
  528                        })?
  529                        .await
  530                        .inspect_err(|_| {
  531                            if let Some(lsp_store) = lsp_store.upgrade() {
  532                                lsp_store
  533                                    .update(cx, |lsp_store, cx| {
  534                                        lsp_store.cleanup_lsp_data(server_id);
  535                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  536                                    })
  537                                    .ok();
  538                            }
  539                        })?;
  540
  541                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  542                        did_change_configuration_params,
  543                    )?;
  544
  545                    anyhow::Ok(language_server)
  546                }
  547                .await;
  548
  549                match result {
  550                    Ok(server) => {
  551                        lsp_store
  552                            .update(cx, |lsp_store, cx| {
  553                                lsp_store.insert_newly_running_language_server(
  554                                    adapter,
  555                                    server.clone(),
  556                                    server_id,
  557                                    key,
  558                                    pending_workspace_folders,
  559                                    cx,
  560                                );
  561                            })
  562                            .ok();
  563                        stderr_capture.lock().take();
  564                        Some(server)
  565                    }
  566
  567                    Err(err) => {
  568                        let log = stderr_capture.lock().take().unwrap_or_default();
  569                        delegate.update_status(
  570                            adapter.name(),
  571                            BinaryStatus::Failed {
  572                                error: if log.is_empty() {
  573                                    format!("{err:#}")
  574                                } else {
  575                                    format!("{err:#}\n-- stderr --\n{log}")
  576                                },
  577                            },
  578                        );
  579                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  580                        if !log.is_empty() {
  581                            log::error!("server stderr: {log}");
  582                        }
  583                        None
  584                    }
  585                }
  586            })
  587        };
  588        let state = LanguageServerState::Starting {
  589            startup,
  590            pending_workspace_folders,
  591        };
  592
  593        if update_binary_status {
  594            self.languages
  595                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  596        }
  597
  598        self.language_servers.insert(server_id, state);
  599        self.language_server_ids
  600            .entry(key)
  601            .or_insert(UnifiedLanguageServer {
  602                id: server_id,
  603                project_roots: Default::default(),
  604            });
  605        server_id
  606    }
  607
  608    fn get_language_server_binary(
  609        &self,
  610        worktree_abs_path: Arc<Path>,
  611        adapter: Arc<CachedLspAdapter>,
  612        settings: Arc<LspSettings>,
  613        toolchain: Option<Toolchain>,
  614        delegate: Arc<dyn LspAdapterDelegate>,
  615        allow_binary_download: bool,
  616        untrusted_worktree_task: Option<Receiver<()>>,
  617        cx: &mut App,
  618    ) -> Task<Result<LanguageServerBinary>> {
  619        if let Some(settings) = &settings.binary
  620            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  621        {
  622            let settings = settings.clone();
  623            let languages = self.languages.clone();
  624            return cx.background_spawn(async move {
  625                if let Some(untrusted_worktree_task) = untrusted_worktree_task {
  626                    log::info!(
  627                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  628                        adapter.name(),
  629                    );
  630                    untrusted_worktree_task.recv().await.ok();
  631                    log::info!(
  632                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  633                        adapter.name(),
  634                    );
  635                    languages
  636                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  637                }
  638                let mut env = delegate.shell_env().await;
  639                env.extend(settings.env.unwrap_or_default());
  640
  641                Ok(LanguageServerBinary {
  642                    path: delegate.resolve_executable_path(path),
  643                    env: Some(env),
  644                    arguments: settings
  645                        .arguments
  646                        .unwrap_or_default()
  647                        .iter()
  648                        .map(Into::into)
  649                        .collect(),
  650                })
  651            });
  652        }
  653        let lsp_binary_options = LanguageServerBinaryOptions {
  654            allow_path_lookup: !settings
  655                .binary
  656                .as_ref()
  657                .and_then(|b| b.ignore_system_version)
  658                .unwrap_or_default(),
  659            allow_binary_download,
  660            pre_release: settings
  661                .fetch
  662                .as_ref()
  663                .and_then(|f| f.pre_release)
  664                .unwrap_or(false),
  665        };
  666
  667        cx.spawn(async move |cx| {
  668            if let Some(untrusted_worktree_task) = untrusted_worktree_task {
  669                log::info!(
  670                    "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  671                    adapter.name(),
  672                );
  673                untrusted_worktree_task.recv().await.ok();
  674                log::info!(
  675                    "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  676                    adapter.name(),
  677                );
  678            }
  679
  680            let (existing_binary, maybe_download_binary) = adapter
  681                .clone()
  682                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  683                .await
  684                .await;
  685
  686            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  687
  688            let mut binary = match (existing_binary, maybe_download_binary) {
  689                (binary, None) => binary?,
  690                (Err(_), Some(downloader)) => downloader.await?,
  691                (Ok(existing_binary), Some(downloader)) => {
  692                    let mut download_timeout = cx
  693                        .background_executor()
  694                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  695                        .fuse();
  696                    let mut downloader = downloader.fuse();
  697                    futures::select! {
  698                        _ = download_timeout => {
  699                            // Return existing binary and kick the existing work to the background.
  700                            cx.spawn(async move |_| downloader.await).detach();
  701                            Ok(existing_binary)
  702                        },
  703                        downloaded_or_existing_binary = downloader => {
  704                            // If download fails, this results in the existing binary.
  705                            downloaded_or_existing_binary
  706                        }
  707                    }?
  708                }
  709            };
  710            let mut shell_env = delegate.shell_env().await;
  711
  712            shell_env.extend(binary.env.unwrap_or_default());
  713
  714            if let Some(settings) = settings.binary.as_ref() {
  715                if let Some(arguments) = &settings.arguments {
  716                    binary.arguments = arguments.iter().map(Into::into).collect();
  717                }
  718                if let Some(env) = &settings.env {
  719                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  720                }
  721            }
  722
  723            binary.env = Some(shell_env);
  724            Ok(binary)
  725        })
  726    }
  727
  728    fn setup_lsp_messages(
  729        lsp_store: WeakEntity<LspStore>,
  730        language_server: &LanguageServer,
  731        delegate: Arc<dyn LspAdapterDelegate>,
  732        adapter: Arc<CachedLspAdapter>,
  733    ) {
  734        let name = language_server.name();
  735        let server_id = language_server.server_id();
  736        language_server
  737            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  738                let adapter = adapter.clone();
  739                let this = lsp_store.clone();
  740                move |mut params, cx| {
  741                    let adapter = adapter.clone();
  742                    if let Some(this) = this.upgrade() {
  743                        this.update(cx, |this, cx| {
  744                            {
  745                                let buffer = params
  746                                    .uri
  747                                    .to_file_path()
  748                                    .map(|file_path| this.get_buffer(&file_path, cx))
  749                                    .ok()
  750                                    .flatten();
  751                                adapter.process_diagnostics(&mut params, server_id, buffer);
  752                            }
  753
  754                            this.merge_lsp_diagnostics(
  755                                DiagnosticSourceKind::Pushed,
  756                                vec![DocumentDiagnosticsUpdate {
  757                                    server_id,
  758                                    diagnostics: params,
  759                                    result_id: None,
  760                                    disk_based_sources: Cow::Borrowed(
  761                                        &adapter.disk_based_diagnostic_sources,
  762                                    ),
  763                                    registration_id: None,
  764                                }],
  765                                |_, diagnostic, cx| match diagnostic.source_kind {
  766                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  767                                        adapter.retain_old_diagnostic(diagnostic, cx)
  768                                    }
  769                                    DiagnosticSourceKind::Pulled => true,
  770                                },
  771                                cx,
  772                            )
  773                            .log_err();
  774                        })
  775                        .ok();
  776                    }
  777                }
  778            })
  779            .detach();
  780        language_server
  781            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  782                let adapter = adapter.adapter.clone();
  783                let delegate = delegate.clone();
  784                let this = lsp_store.clone();
  785                move |params, cx| {
  786                    let adapter = adapter.clone();
  787                    let delegate = delegate.clone();
  788                    let this = this.clone();
  789                    let mut cx = cx.clone();
  790                    async move {
  791                        let toolchain_for_id = this
  792                            .update(&mut cx, |this, _| {
  793                                this.as_local()?.language_server_ids.iter().find_map(
  794                                    |(seed, value)| {
  795                                        (value.id == server_id).then(|| seed.toolchain.clone())
  796                                    },
  797                                )
  798                            })?
  799                            .context("Expected the LSP store to be in a local mode")?;
  800
  801                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  802                        for item in &params.items {
  803                            let scope_uri = item.scope_uri.clone();
  804                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  805                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  806                            else {
  807                                // We've already queried workspace configuration of this URI.
  808                                continue;
  809                            };
  810                            let workspace_config = Self::workspace_configuration_for_adapter(
  811                                adapter.clone(),
  812                                &delegate,
  813                                toolchain_for_id.clone(),
  814                                scope_uri,
  815                                &mut cx,
  816                            )
  817                            .await?;
  818                            new_scope_uri.insert(workspace_config);
  819                        }
  820
  821                        Ok(params
  822                            .items
  823                            .into_iter()
  824                            .filter_map(|item| {
  825                                let workspace_config =
  826                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  827                                if let Some(section) = &item.section {
  828                                    Some(
  829                                        workspace_config
  830                                            .get(section)
  831                                            .cloned()
  832                                            .unwrap_or(serde_json::Value::Null),
  833                                    )
  834                                } else {
  835                                    Some(workspace_config.clone())
  836                                }
  837                            })
  838                            .collect())
  839                    }
  840                }
  841            })
  842            .detach();
  843
  844        language_server
  845            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  846                let this = lsp_store.clone();
  847                move |_, cx| {
  848                    let this = this.clone();
  849                    let cx = cx.clone();
  850                    async move {
  851                        let Some(server) =
  852                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  853                        else {
  854                            return Ok(None);
  855                        };
  856                        let root = server.workspace_folders();
  857                        Ok(Some(
  858                            root.into_iter()
  859                                .map(|uri| WorkspaceFolder {
  860                                    uri,
  861                                    name: Default::default(),
  862                                })
  863                                .collect(),
  864                        ))
  865                    }
  866                }
  867            })
  868            .detach();
  869        // Even though we don't have handling for these requests, respond to them to
  870        // avoid stalling any language server like `gopls` which waits for a response
  871        // to these requests when initializing.
  872        language_server
  873            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  874                let this = lsp_store.clone();
  875                move |params, cx| {
  876                    let this = this.clone();
  877                    let mut cx = cx.clone();
  878                    async move {
  879                        this.update(&mut cx, |this, _| {
  880                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  881                            {
  882                                status
  883                                    .progress_tokens
  884                                    .insert(ProgressToken::from_lsp(params.token));
  885                            }
  886                        })?;
  887
  888                        Ok(())
  889                    }
  890                }
  891            })
  892            .detach();
  893
  894        language_server
  895            .on_request::<lsp::request::RegisterCapability, _, _>({
  896                let lsp_store = lsp_store.clone();
  897                move |params, cx| {
  898                    let lsp_store = lsp_store.clone();
  899                    let mut cx = cx.clone();
  900                    async move {
  901                        lsp_store
  902                            .update(&mut cx, |lsp_store, cx| {
  903                                if lsp_store.as_local().is_some() {
  904                                    match lsp_store
  905                                        .register_server_capabilities(server_id, params, cx)
  906                                    {
  907                                        Ok(()) => {}
  908                                        Err(e) => {
  909                                            log::error!(
  910                                                "Failed to register server capabilities: {e:#}"
  911                                            );
  912                                        }
  913                                    };
  914                                }
  915                            })
  916                            .ok();
  917                        Ok(())
  918                    }
  919                }
  920            })
  921            .detach();
  922
  923        language_server
  924            .on_request::<lsp::request::UnregisterCapability, _, _>({
  925                let lsp_store = lsp_store.clone();
  926                move |params, cx| {
  927                    let lsp_store = lsp_store.clone();
  928                    let mut cx = cx.clone();
  929                    async move {
  930                        lsp_store
  931                            .update(&mut cx, |lsp_store, cx| {
  932                                if lsp_store.as_local().is_some() {
  933                                    match lsp_store
  934                                        .unregister_server_capabilities(server_id, params, cx)
  935                                    {
  936                                        Ok(()) => {}
  937                                        Err(e) => {
  938                                            log::error!(
  939                                                "Failed to unregister server capabilities: {e:#}"
  940                                            );
  941                                        }
  942                                    }
  943                                }
  944                            })
  945                            .ok();
  946                        Ok(())
  947                    }
  948                }
  949            })
  950            .detach();
  951
  952        language_server
  953            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  954                let this = lsp_store.clone();
  955                move |params, cx| {
  956                    let mut cx = cx.clone();
  957                    let this = this.clone();
  958                    async move {
  959                        LocalLspStore::on_lsp_workspace_edit(
  960                            this.clone(),
  961                            params,
  962                            server_id,
  963                            &mut cx,
  964                        )
  965                        .await
  966                    }
  967                }
  968            })
  969            .detach();
  970
  971        language_server
  972            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  973                let lsp_store = lsp_store.clone();
  974                let request_id = Arc::new(AtomicUsize::new(0));
  975                move |(), cx| {
  976                    let lsp_store = lsp_store.clone();
  977                    let request_id = request_id.clone();
  978                    let mut cx = cx.clone();
  979                    async move {
  980                        lsp_store
  981                            .update(&mut cx, |lsp_store, cx| {
  982                                let request_id =
  983                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
  984                                cx.emit(LspStoreEvent::RefreshInlayHints {
  985                                    server_id,
  986                                    request_id,
  987                                });
  988                                lsp_store
  989                                    .downstream_client
  990                                    .as_ref()
  991                                    .map(|(client, project_id)| {
  992                                        client.send(proto::RefreshInlayHints {
  993                                            project_id: *project_id,
  994                                            server_id: server_id.to_proto(),
  995                                            request_id: request_id.map(|id| id as u64),
  996                                        })
  997                                    })
  998                            })?
  999                            .transpose()?;
 1000                        Ok(())
 1001                    }
 1002                }
 1003            })
 1004            .detach();
 1005
 1006        language_server
 1007            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1008                let this = lsp_store.clone();
 1009                move |(), cx| {
 1010                    let this = this.clone();
 1011                    let mut cx = cx.clone();
 1012                    async move {
 1013                        this.update(&mut cx, |this, cx| {
 1014                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1015                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1016                                client.send(proto::RefreshCodeLens {
 1017                                    project_id: *project_id,
 1018                                })
 1019                            })
 1020                        })?
 1021                        .transpose()?;
 1022                        Ok(())
 1023                    }
 1024                }
 1025            })
 1026            .detach();
 1027
 1028        language_server
 1029            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1030                let this = lsp_store.clone();
 1031                move |(), cx| {
 1032                    let this = this.clone();
 1033                    let mut cx = cx.clone();
 1034                    async move {
 1035                        this.update(&mut cx, |lsp_store, _| {
 1036                            lsp_store.pull_workspace_diagnostics(server_id);
 1037                            lsp_store
 1038                                .downstream_client
 1039                                .as_ref()
 1040                                .map(|(client, project_id)| {
 1041                                    client.send(proto::PullWorkspaceDiagnostics {
 1042                                        project_id: *project_id,
 1043                                        server_id: server_id.to_proto(),
 1044                                    })
 1045                                })
 1046                        })?
 1047                        .transpose()?;
 1048                        Ok(())
 1049                    }
 1050                }
 1051            })
 1052            .detach();
 1053
 1054        language_server
 1055            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1056                let this = lsp_store.clone();
 1057                let name = name.to_string();
 1058                move |params, cx| {
 1059                    let this = this.clone();
 1060                    let name = name.to_string();
 1061                    let mut cx = cx.clone();
 1062                    async move {
 1063                        let actions = params.actions.unwrap_or_default();
 1064                        let (tx, rx) = smol::channel::bounded(1);
 1065                        let request = LanguageServerPromptRequest {
 1066                            level: match params.typ {
 1067                                lsp::MessageType::ERROR => PromptLevel::Critical,
 1068                                lsp::MessageType::WARNING => PromptLevel::Warning,
 1069                                _ => PromptLevel::Info,
 1070                            },
 1071                            message: params.message,
 1072                            actions,
 1073                            response_channel: tx,
 1074                            lsp_name: name.clone(),
 1075                        };
 1076
 1077                        let did_update = this
 1078                            .update(&mut cx, |_, cx| {
 1079                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1080                            })
 1081                            .is_ok();
 1082                        if did_update {
 1083                            let response = rx.recv().await.ok();
 1084                            Ok(response)
 1085                        } else {
 1086                            Ok(None)
 1087                        }
 1088                    }
 1089                }
 1090            })
 1091            .detach();
 1092        language_server
 1093            .on_notification::<lsp::notification::ShowMessage, _>({
 1094                let this = lsp_store.clone();
 1095                let name = name.to_string();
 1096                move |params, cx| {
 1097                    let this = this.clone();
 1098                    let name = name.to_string();
 1099                    let mut cx = cx.clone();
 1100
 1101                    let (tx, _) = smol::channel::bounded(1);
 1102                    let request = LanguageServerPromptRequest {
 1103                        level: match params.typ {
 1104                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1105                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1106                            _ => PromptLevel::Info,
 1107                        },
 1108                        message: params.message,
 1109                        actions: vec![],
 1110                        response_channel: tx,
 1111                        lsp_name: name,
 1112                    };
 1113
 1114                    let _ = this.update(&mut cx, |_, cx| {
 1115                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1116                    });
 1117                }
 1118            })
 1119            .detach();
 1120
 1121        let disk_based_diagnostics_progress_token =
 1122            adapter.disk_based_diagnostics_progress_token.clone();
 1123
 1124        language_server
 1125            .on_notification::<lsp::notification::Progress, _>({
 1126                let this = lsp_store.clone();
 1127                move |params, cx| {
 1128                    if let Some(this) = this.upgrade() {
 1129                        this.update(cx, |this, cx| {
 1130                            this.on_lsp_progress(
 1131                                params,
 1132                                server_id,
 1133                                disk_based_diagnostics_progress_token.clone(),
 1134                                cx,
 1135                            );
 1136                        })
 1137                        .ok();
 1138                    }
 1139                }
 1140            })
 1141            .detach();
 1142
 1143        language_server
 1144            .on_notification::<lsp::notification::LogMessage, _>({
 1145                let this = lsp_store.clone();
 1146                move |params, cx| {
 1147                    if let Some(this) = this.upgrade() {
 1148                        this.update(cx, |_, cx| {
 1149                            cx.emit(LspStoreEvent::LanguageServerLog(
 1150                                server_id,
 1151                                LanguageServerLogType::Log(params.typ),
 1152                                params.message,
 1153                            ));
 1154                        })
 1155                        .ok();
 1156                    }
 1157                }
 1158            })
 1159            .detach();
 1160
 1161        language_server
 1162            .on_notification::<lsp::notification::LogTrace, _>({
 1163                let this = lsp_store.clone();
 1164                move |params, cx| {
 1165                    let mut cx = cx.clone();
 1166                    if let Some(this) = this.upgrade() {
 1167                        this.update(&mut cx, |_, cx| {
 1168                            cx.emit(LspStoreEvent::LanguageServerLog(
 1169                                server_id,
 1170                                LanguageServerLogType::Trace {
 1171                                    verbose_info: params.verbose,
 1172                                },
 1173                                params.message,
 1174                            ));
 1175                        })
 1176                        .ok();
 1177                    }
 1178                }
 1179            })
 1180            .detach();
 1181
 1182        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1183        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1184        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1185        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1186    }
 1187
 1188    fn shutdown_language_servers_on_quit(
 1189        &mut self,
 1190        _: &mut Context<LspStore>,
 1191    ) -> impl Future<Output = ()> + use<> {
 1192        let shutdown_futures = self
 1193            .language_servers
 1194            .drain()
 1195            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1196            .collect::<Vec<_>>();
 1197
 1198        async move {
 1199            join_all(shutdown_futures).await;
 1200        }
 1201    }
 1202
 1203    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1204        match server_state {
 1205            LanguageServerState::Running { server, .. } => {
 1206                if let Some(shutdown) = server.shutdown() {
 1207                    shutdown.await;
 1208                }
 1209            }
 1210            LanguageServerState::Starting { startup, .. } => {
 1211                if let Some(server) = startup.await
 1212                    && let Some(shutdown) = server.shutdown()
 1213                {
 1214                    shutdown.await;
 1215                }
 1216            }
 1217        }
 1218        Ok(())
 1219    }
 1220
 1221    fn language_servers_for_worktree(
 1222        &self,
 1223        worktree_id: WorktreeId,
 1224    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1225        self.language_server_ids
 1226            .iter()
 1227            .filter_map(move |(seed, state)| {
 1228                if seed.worktree_id != worktree_id {
 1229                    return None;
 1230                }
 1231
 1232                if let Some(LanguageServerState::Running { server, .. }) =
 1233                    self.language_servers.get(&state.id)
 1234                {
 1235                    Some(server)
 1236                } else {
 1237                    None
 1238                }
 1239            })
 1240    }
 1241
 1242    fn language_server_ids_for_project_path(
 1243        &self,
 1244        project_path: ProjectPath,
 1245        language: &Language,
 1246        cx: &mut App,
 1247    ) -> Vec<LanguageServerId> {
 1248        let Some(worktree) = self
 1249            .worktree_store
 1250            .read(cx)
 1251            .worktree_for_id(project_path.worktree_id, cx)
 1252        else {
 1253            return Vec::new();
 1254        };
 1255        let delegate: Arc<dyn ManifestDelegate> =
 1256            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1257
 1258        self.lsp_tree
 1259            .get(
 1260                project_path,
 1261                language.name(),
 1262                language.manifest(),
 1263                &delegate,
 1264                cx,
 1265            )
 1266            .collect::<Vec<_>>()
 1267    }
 1268
 1269    fn language_server_ids_for_buffer(
 1270        &self,
 1271        buffer: &Buffer,
 1272        cx: &mut App,
 1273    ) -> Vec<LanguageServerId> {
 1274        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1275            let worktree_id = file.worktree_id(cx);
 1276
 1277            let path: Arc<RelPath> = file
 1278                .path()
 1279                .parent()
 1280                .map(Arc::from)
 1281                .unwrap_or_else(|| file.path().clone());
 1282            let worktree_path = ProjectPath { worktree_id, path };
 1283            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1284        } else {
 1285            Vec::new()
 1286        }
 1287    }
 1288
 1289    fn language_servers_for_buffer<'a>(
 1290        &'a self,
 1291        buffer: &'a Buffer,
 1292        cx: &'a mut App,
 1293    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1294        self.language_server_ids_for_buffer(buffer, cx)
 1295            .into_iter()
 1296            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1297                LanguageServerState::Running {
 1298                    adapter, server, ..
 1299                } => Some((adapter, server)),
 1300                _ => None,
 1301            })
 1302    }
 1303
 1304    async fn execute_code_action_kind_locally(
 1305        lsp_store: WeakEntity<LspStore>,
 1306        mut buffers: Vec<Entity<Buffer>>,
 1307        kind: CodeActionKind,
 1308        push_to_history: bool,
 1309        cx: &mut AsyncApp,
 1310    ) -> anyhow::Result<ProjectTransaction> {
 1311        // Do not allow multiple concurrent code actions requests for the
 1312        // same buffer.
 1313        lsp_store.update(cx, |this, cx| {
 1314            let this = this.as_local_mut().unwrap();
 1315            buffers.retain(|buffer| {
 1316                this.buffers_being_formatted
 1317                    .insert(buffer.read(cx).remote_id())
 1318            });
 1319        })?;
 1320        let _cleanup = defer({
 1321            let this = lsp_store.clone();
 1322            let mut cx = cx.clone();
 1323            let buffers = &buffers;
 1324            move || {
 1325                this.update(&mut cx, |this, cx| {
 1326                    let this = this.as_local_mut().unwrap();
 1327                    for buffer in buffers {
 1328                        this.buffers_being_formatted
 1329                            .remove(&buffer.read(cx).remote_id());
 1330                    }
 1331                })
 1332                .ok();
 1333            }
 1334        });
 1335        let mut project_transaction = ProjectTransaction::default();
 1336
 1337        for buffer in &buffers {
 1338            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1339                buffer.update(cx, |buffer, cx| {
 1340                    lsp_store
 1341                        .as_local()
 1342                        .unwrap()
 1343                        .language_servers_for_buffer(buffer, cx)
 1344                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1345                        .collect::<Vec<_>>()
 1346                })
 1347            })?;
 1348            for (_, language_server) in adapters_and_servers.iter() {
 1349                let actions = Self::get_server_code_actions_from_action_kinds(
 1350                    &lsp_store,
 1351                    language_server.server_id(),
 1352                    vec![kind.clone()],
 1353                    buffer,
 1354                    cx,
 1355                )
 1356                .await?;
 1357                Self::execute_code_actions_on_server(
 1358                    &lsp_store,
 1359                    language_server,
 1360                    actions,
 1361                    push_to_history,
 1362                    &mut project_transaction,
 1363                    cx,
 1364                )
 1365                .await?;
 1366            }
 1367        }
 1368        Ok(project_transaction)
 1369    }
 1370
 1371    async fn format_locally(
 1372        lsp_store: WeakEntity<LspStore>,
 1373        mut buffers: Vec<FormattableBuffer>,
 1374        push_to_history: bool,
 1375        trigger: FormatTrigger,
 1376        logger: zlog::Logger,
 1377        cx: &mut AsyncApp,
 1378    ) -> anyhow::Result<ProjectTransaction> {
 1379        // Do not allow multiple concurrent formatting requests for the
 1380        // same buffer.
 1381        lsp_store.update(cx, |this, cx| {
 1382            let this = this.as_local_mut().unwrap();
 1383            buffers.retain(|buffer| {
 1384                this.buffers_being_formatted
 1385                    .insert(buffer.handle.read(cx).remote_id())
 1386            });
 1387        })?;
 1388
 1389        let _cleanup = defer({
 1390            let this = lsp_store.clone();
 1391            let mut cx = cx.clone();
 1392            let buffers = &buffers;
 1393            move || {
 1394                this.update(&mut cx, |this, cx| {
 1395                    let this = this.as_local_mut().unwrap();
 1396                    for buffer in buffers {
 1397                        this.buffers_being_formatted
 1398                            .remove(&buffer.handle.read(cx).remote_id());
 1399                    }
 1400                })
 1401                .ok();
 1402            }
 1403        });
 1404
 1405        let mut project_transaction = ProjectTransaction::default();
 1406
 1407        for buffer in &buffers {
 1408            zlog::debug!(
 1409                logger =>
 1410                "formatting buffer '{:?}'",
 1411                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1412            );
 1413            // Create an empty transaction to hold all of the formatting edits.
 1414            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1415                // ensure no transactions created while formatting are
 1416                // grouped with the previous transaction in the history
 1417                // based on the transaction group interval
 1418                buffer.finalize_last_transaction();
 1419                buffer
 1420                    .start_transaction()
 1421                    .context("transaction already open")?;
 1422                buffer.end_transaction(cx);
 1423                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1424                buffer.finalize_last_transaction();
 1425                anyhow::Ok(transaction_id)
 1426            })??;
 1427
 1428            let result = Self::format_buffer_locally(
 1429                lsp_store.clone(),
 1430                buffer,
 1431                formatting_transaction_id,
 1432                trigger,
 1433                logger,
 1434                cx,
 1435            )
 1436            .await;
 1437
 1438            buffer.handle.update(cx, |buffer, cx| {
 1439                let Some(formatting_transaction) =
 1440                    buffer.get_transaction(formatting_transaction_id).cloned()
 1441                else {
 1442                    zlog::warn!(logger => "no formatting transaction");
 1443                    return;
 1444                };
 1445                if formatting_transaction.edit_ids.is_empty() {
 1446                    zlog::debug!(logger => "no changes made while formatting");
 1447                    buffer.forget_transaction(formatting_transaction_id);
 1448                    return;
 1449                }
 1450                if !push_to_history {
 1451                    zlog::trace!(logger => "forgetting format transaction");
 1452                    buffer.forget_transaction(formatting_transaction.id);
 1453                }
 1454                project_transaction
 1455                    .0
 1456                    .insert(cx.entity(), formatting_transaction);
 1457            })?;
 1458
 1459            result?;
 1460        }
 1461
 1462        Ok(project_transaction)
 1463    }
 1464
 1465    async fn format_buffer_locally(
 1466        lsp_store: WeakEntity<LspStore>,
 1467        buffer: &FormattableBuffer,
 1468        formatting_transaction_id: clock::Lamport,
 1469        trigger: FormatTrigger,
 1470        logger: zlog::Logger,
 1471        cx: &mut AsyncApp,
 1472    ) -> Result<()> {
 1473        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1474            buffer.handle.update(cx, |buffer, cx| {
 1475                let adapters_and_servers = lsp_store
 1476                    .as_local()
 1477                    .unwrap()
 1478                    .language_servers_for_buffer(buffer, cx)
 1479                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1480                    .collect::<Vec<_>>();
 1481                let settings =
 1482                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1483                        .into_owned();
 1484                (adapters_and_servers, settings)
 1485            })
 1486        })?;
 1487
 1488        /// Apply edits to the buffer that will become part of the formatting transaction.
 1489        /// Fails if the buffer has been edited since the start of that transaction.
 1490        fn extend_formatting_transaction(
 1491            buffer: &FormattableBuffer,
 1492            formatting_transaction_id: text::TransactionId,
 1493            cx: &mut AsyncApp,
 1494            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1495        ) -> anyhow::Result<()> {
 1496            buffer.handle.update(cx, |buffer, cx| {
 1497                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1498                if last_transaction_id != Some(formatting_transaction_id) {
 1499                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1500                }
 1501                buffer.start_transaction();
 1502                operation(buffer, cx);
 1503                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1504                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1505                }
 1506                Ok(())
 1507            })?
 1508        }
 1509
 1510        // handle whitespace formatting
 1511        if settings.remove_trailing_whitespace_on_save {
 1512            zlog::trace!(logger => "removing trailing whitespace");
 1513            let diff = buffer
 1514                .handle
 1515                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1516                .await;
 1517            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1518                buffer.apply_diff(diff, cx);
 1519            })?;
 1520        }
 1521
 1522        if settings.ensure_final_newline_on_save {
 1523            zlog::trace!(logger => "ensuring final newline");
 1524            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1525                buffer.ensure_final_newline(cx);
 1526            })?;
 1527        }
 1528
 1529        // Formatter for `code_actions_on_format` that runs before
 1530        // the rest of the formatters
 1531        let mut code_actions_on_format_formatters = None;
 1532        let should_run_code_actions_on_format = !matches!(
 1533            (trigger, &settings.format_on_save),
 1534            (FormatTrigger::Save, &FormatOnSave::Off)
 1535        );
 1536        if should_run_code_actions_on_format {
 1537            let have_code_actions_to_run_on_format = settings
 1538                .code_actions_on_format
 1539                .values()
 1540                .any(|enabled| *enabled);
 1541            if have_code_actions_to_run_on_format {
 1542                zlog::trace!(logger => "going to run code actions on format");
 1543                code_actions_on_format_formatters = Some(
 1544                    settings
 1545                        .code_actions_on_format
 1546                        .iter()
 1547                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1548                        .cloned()
 1549                        .map(Formatter::CodeAction)
 1550                        .collect::<Vec<_>>(),
 1551                );
 1552            }
 1553        }
 1554
 1555        let formatters = match (trigger, &settings.format_on_save) {
 1556            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1557            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1558                settings.formatter.as_ref()
 1559            }
 1560        };
 1561
 1562        let formatters = code_actions_on_format_formatters
 1563            .iter()
 1564            .flatten()
 1565            .chain(formatters);
 1566
 1567        for formatter in formatters {
 1568            let formatter = if formatter == &Formatter::Auto {
 1569                if settings.prettier.allowed {
 1570                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1571                    &Formatter::Prettier
 1572                } else {
 1573                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1574                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1575                }
 1576            } else {
 1577                formatter
 1578            };
 1579            match formatter {
 1580                Formatter::Auto => unreachable!("Auto resolved above"),
 1581                Formatter::Prettier => {
 1582                    let logger = zlog::scoped!(logger => "prettier");
 1583                    zlog::trace!(logger => "formatting");
 1584                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1585
 1586                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1587                        lsp_store.prettier_store().unwrap().downgrade()
 1588                    })?;
 1589                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1590                        .await
 1591                        .transpose()?;
 1592                    let Some(diff) = diff else {
 1593                        zlog::trace!(logger => "No changes");
 1594                        continue;
 1595                    };
 1596
 1597                    extend_formatting_transaction(
 1598                        buffer,
 1599                        formatting_transaction_id,
 1600                        cx,
 1601                        |buffer, cx| {
 1602                            buffer.apply_diff(diff, cx);
 1603                        },
 1604                    )?;
 1605                }
 1606                Formatter::External { command, arguments } => {
 1607                    let logger = zlog::scoped!(logger => "command");
 1608                    zlog::trace!(logger => "formatting");
 1609                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1610
 1611                    let diff = Self::format_via_external_command(
 1612                        buffer,
 1613                        command.as_ref(),
 1614                        arguments.as_deref(),
 1615                        cx,
 1616                    )
 1617                    .await
 1618                    .with_context(|| {
 1619                        format!("Failed to format buffer via external command: {}", command)
 1620                    })?;
 1621                    let Some(diff) = diff else {
 1622                        zlog::trace!(logger => "No changes");
 1623                        continue;
 1624                    };
 1625
 1626                    extend_formatting_transaction(
 1627                        buffer,
 1628                        formatting_transaction_id,
 1629                        cx,
 1630                        |buffer, cx| {
 1631                            buffer.apply_diff(diff, cx);
 1632                        },
 1633                    )?;
 1634                }
 1635                Formatter::LanguageServer(specifier) => {
 1636                    let logger = zlog::scoped!(logger => "language-server");
 1637                    zlog::trace!(logger => "formatting");
 1638                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1639
 1640                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1641                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1642                        continue;
 1643                    };
 1644
 1645                    let language_server = match specifier {
 1646                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1647                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1648                                if adapter.name.0.as_ref() == name {
 1649                                    Some(server.clone())
 1650                                } else {
 1651                                    None
 1652                                }
 1653                            })
 1654                        }
 1655                        settings::LanguageServerFormatterSpecifier::Current => {
 1656                            adapters_and_servers.first().map(|e| e.1.clone())
 1657                        }
 1658                    };
 1659
 1660                    let Some(language_server) = language_server else {
 1661                        log::debug!(
 1662                            "No language server found to format buffer '{:?}'. Skipping",
 1663                            buffer_path_abs.as_path().to_string_lossy()
 1664                        );
 1665                        continue;
 1666                    };
 1667
 1668                    zlog::trace!(
 1669                        logger =>
 1670                        "Formatting buffer '{:?}' using language server '{:?}'",
 1671                        buffer_path_abs.as_path().to_string_lossy(),
 1672                        language_server.name()
 1673                    );
 1674
 1675                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1676                        zlog::trace!(logger => "formatting ranges");
 1677                        Self::format_ranges_via_lsp(
 1678                            &lsp_store,
 1679                            &buffer.handle,
 1680                            ranges,
 1681                            buffer_path_abs,
 1682                            &language_server,
 1683                            &settings,
 1684                            cx,
 1685                        )
 1686                        .await
 1687                        .context("Failed to format ranges via language server")?
 1688                    } else {
 1689                        zlog::trace!(logger => "formatting full");
 1690                        Self::format_via_lsp(
 1691                            &lsp_store,
 1692                            &buffer.handle,
 1693                            buffer_path_abs,
 1694                            &language_server,
 1695                            &settings,
 1696                            cx,
 1697                        )
 1698                        .await
 1699                        .context("failed to format via language server")?
 1700                    };
 1701
 1702                    if edits.is_empty() {
 1703                        zlog::trace!(logger => "No changes");
 1704                        continue;
 1705                    }
 1706                    extend_formatting_transaction(
 1707                        buffer,
 1708                        formatting_transaction_id,
 1709                        cx,
 1710                        |buffer, cx| {
 1711                            buffer.edit(edits, None, cx);
 1712                        },
 1713                    )?;
 1714                }
 1715                Formatter::CodeAction(code_action_name) => {
 1716                    let logger = zlog::scoped!(logger => "code-actions");
 1717                    zlog::trace!(logger => "formatting");
 1718                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1719
 1720                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1721                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1722                        continue;
 1723                    };
 1724
 1725                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1726                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1727
 1728                    let mut actions_and_servers = Vec::new();
 1729
 1730                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1731                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1732                            &lsp_store,
 1733                            language_server.server_id(),
 1734                            vec![code_action_kind.clone()],
 1735                            &buffer.handle,
 1736                            cx,
 1737                        )
 1738                        .await
 1739                        .with_context(|| {
 1740                            format!(
 1741                                "Failed to resolve code action {:?} with language server {}",
 1742                                code_action_kind,
 1743                                language_server.name()
 1744                            )
 1745                        });
 1746                        let Ok(actions) = actions_result else {
 1747                            // note: it may be better to set result to the error and break formatters here
 1748                            // but for now we try to execute the actions that we can resolve and skip the rest
 1749                            zlog::error!(
 1750                                logger =>
 1751                                "Failed to resolve code action {:?} with language server {}",
 1752                                code_action_kind,
 1753                                language_server.name()
 1754                            );
 1755                            continue;
 1756                        };
 1757                        for action in actions {
 1758                            actions_and_servers.push((action, index));
 1759                        }
 1760                    }
 1761
 1762                    if actions_and_servers.is_empty() {
 1763                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1764                        continue;
 1765                    }
 1766
 1767                    'actions: for (mut action, server_index) in actions_and_servers {
 1768                        let server = &adapters_and_servers[server_index].1;
 1769
 1770                        let describe_code_action = |action: &CodeAction| {
 1771                            format!(
 1772                                "code action '{}' with title \"{}\" on server {}",
 1773                                action
 1774                                    .lsp_action
 1775                                    .action_kind()
 1776                                    .unwrap_or("unknown".into())
 1777                                    .as_str(),
 1778                                action.lsp_action.title(),
 1779                                server.name(),
 1780                            )
 1781                        };
 1782
 1783                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1784
 1785                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1786                            zlog::error!(
 1787                                logger =>
 1788                                "Failed to resolve {}. Error: {}",
 1789                                describe_code_action(&action),
 1790                                err
 1791                            );
 1792                            continue;
 1793                        }
 1794
 1795                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1796                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1797                            // but filters out and logs warnings for code actions that require unreasonably
 1798                            // difficult handling on our part, such as:
 1799                            // - applying edits that call commands
 1800                            //   which can result in arbitrary workspace edits being sent from the server that
 1801                            //   have no way of being tied back to the command that initiated them (i.e. we
 1802                            //   can't know which edits are part of the format request, or if the server is done sending
 1803                            //   actions in response to the command)
 1804                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1805                            //   as we then would need to handle such changes correctly in the local history as well
 1806                            //   as the remote history through the ProjectTransaction
 1807                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1808                            // Supporting these actions is not impossible, but not supported as of yet.
 1809                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1810                                zlog::trace!(
 1811                                    logger =>
 1812                                    "No changes for code action. Skipping {}",
 1813                                    describe_code_action(&action),
 1814                                );
 1815                                continue;
 1816                            }
 1817
 1818                            let mut operations = Vec::new();
 1819                            if let Some(document_changes) = edit.document_changes {
 1820                                match document_changes {
 1821                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1822                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1823                                    ),
 1824                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1825                                }
 1826                            } else if let Some(changes) = edit.changes {
 1827                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1828                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1829                                        text_document:
 1830                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1831                                                uri,
 1832                                                version: None,
 1833                                            },
 1834                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1835                                    })
 1836                                }));
 1837                            }
 1838
 1839                            let mut edits = Vec::with_capacity(operations.len());
 1840
 1841                            if operations.is_empty() {
 1842                                zlog::trace!(
 1843                                    logger =>
 1844                                    "No changes for code action. Skipping {}",
 1845                                    describe_code_action(&action),
 1846                                );
 1847                                continue;
 1848                            }
 1849                            for operation in operations {
 1850                                let op = match operation {
 1851                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1852                                    lsp::DocumentChangeOperation::Op(_) => {
 1853                                        zlog::warn!(
 1854                                            logger =>
 1855                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1856                                            describe_code_action(&action),
 1857                                        );
 1858                                        continue 'actions;
 1859                                    }
 1860                                };
 1861                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1862                                    zlog::warn!(
 1863                                        logger =>
 1864                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1865                                        &op.text_document.uri,
 1866                                        describe_code_action(&action),
 1867                                    );
 1868                                    continue 'actions;
 1869                                };
 1870                                if &file_path != buffer_path_abs {
 1871                                    zlog::warn!(
 1872                                        logger =>
 1873                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1874                                        file_path,
 1875                                        buffer_path_abs,
 1876                                        describe_code_action(&action),
 1877                                    );
 1878                                    continue 'actions;
 1879                                }
 1880
 1881                                let mut lsp_edits = Vec::new();
 1882                                for edit in op.edits {
 1883                                    match edit {
 1884                                        Edit::Plain(edit) => {
 1885                                            if !lsp_edits.contains(&edit) {
 1886                                                lsp_edits.push(edit);
 1887                                            }
 1888                                        }
 1889                                        Edit::Annotated(edit) => {
 1890                                            if !lsp_edits.contains(&edit.text_edit) {
 1891                                                lsp_edits.push(edit.text_edit);
 1892                                            }
 1893                                        }
 1894                                        Edit::Snippet(_) => {
 1895                                            zlog::warn!(
 1896                                                logger =>
 1897                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1898                                                describe_code_action(&action),
 1899                                            );
 1900                                            continue 'actions;
 1901                                        }
 1902                                    }
 1903                                }
 1904                                let edits_result = lsp_store
 1905                                    .update(cx, |lsp_store, cx| {
 1906                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1907                                            &buffer.handle,
 1908                                            lsp_edits,
 1909                                            server.server_id(),
 1910                                            op.text_document.version,
 1911                                            cx,
 1912                                        )
 1913                                    })?
 1914                                    .await;
 1915                                let Ok(resolved_edits) = edits_result else {
 1916                                    zlog::warn!(
 1917                                        logger =>
 1918                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1919                                        buffer_path_abs.as_path(),
 1920                                        describe_code_action(&action),
 1921                                    );
 1922                                    continue 'actions;
 1923                                };
 1924                                edits.extend(resolved_edits);
 1925                            }
 1926
 1927                            if edits.is_empty() {
 1928                                zlog::warn!(logger => "No edits resolved from LSP");
 1929                                continue;
 1930                            }
 1931
 1932                            extend_formatting_transaction(
 1933                                buffer,
 1934                                formatting_transaction_id,
 1935                                cx,
 1936                                |buffer, cx| {
 1937                                    zlog::info!(
 1938                                        "Applying edits {edits:?}. Content: {:?}",
 1939                                        buffer.text()
 1940                                    );
 1941                                    buffer.edit(edits, None, cx);
 1942                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1943                                },
 1944                            )?;
 1945                        }
 1946
 1947                        if let Some(command) = action.lsp_action.command() {
 1948                            zlog::warn!(
 1949                                logger =>
 1950                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1951                                &command.command,
 1952                            );
 1953
 1954                            // bail early if command is invalid
 1955                            let server_capabilities = server.capabilities();
 1956                            let available_commands = server_capabilities
 1957                                .execute_command_provider
 1958                                .as_ref()
 1959                                .map(|options| options.commands.as_slice())
 1960                                .unwrap_or_default();
 1961                            if !available_commands.contains(&command.command) {
 1962                                zlog::warn!(
 1963                                    logger =>
 1964                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1965                                    command.command,
 1966                                    server.name(),
 1967                                );
 1968                                continue;
 1969                            }
 1970
 1971                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1972                            extend_formatting_transaction(
 1973                                buffer,
 1974                                formatting_transaction_id,
 1975                                cx,
 1976                                |_, _| {},
 1977                            )?;
 1978                            zlog::info!(logger => "Executing command {}", &command.command);
 1979
 1980                            lsp_store.update(cx, |this, _| {
 1981                                this.as_local_mut()
 1982                                    .unwrap()
 1983                                    .last_workspace_edits_by_language_server
 1984                                    .remove(&server.server_id());
 1985                            })?;
 1986
 1987                            let execute_command_result = server
 1988                                .request::<lsp::request::ExecuteCommand>(
 1989                                    lsp::ExecuteCommandParams {
 1990                                        command: command.command.clone(),
 1991                                        arguments: command.arguments.clone().unwrap_or_default(),
 1992                                        ..Default::default()
 1993                                    },
 1994                                )
 1995                                .await
 1996                                .into_response();
 1997
 1998                            if execute_command_result.is_err() {
 1999                                zlog::error!(
 2000                                    logger =>
 2001                                    "Failed to execute command '{}' as part of {}",
 2002                                    &command.command,
 2003                                    describe_code_action(&action),
 2004                                );
 2005                                continue 'actions;
 2006                            }
 2007
 2008                            let mut project_transaction_command =
 2009                                lsp_store.update(cx, |this, _| {
 2010                                    this.as_local_mut()
 2011                                        .unwrap()
 2012                                        .last_workspace_edits_by_language_server
 2013                                        .remove(&server.server_id())
 2014                                        .unwrap_or_default()
 2015                                })?;
 2016
 2017                            if let Some(transaction) =
 2018                                project_transaction_command.0.remove(&buffer.handle)
 2019                            {
 2020                                zlog::trace!(
 2021                                    logger =>
 2022                                    "Successfully captured {} edits that resulted from command {}",
 2023                                    transaction.edit_ids.len(),
 2024                                    &command.command,
 2025                                );
 2026                                let transaction_id_project_transaction = transaction.id;
 2027                                buffer.handle.update(cx, |buffer, _| {
 2028                                    // it may have been removed from history if push_to_history was
 2029                                    // false in deserialize_workspace_edit. If so push it so we
 2030                                    // can merge it with the format transaction
 2031                                    // and pop the combined transaction off the history stack
 2032                                    // later if push_to_history is false
 2033                                    if buffer.get_transaction(transaction.id).is_none() {
 2034                                        buffer.push_transaction(transaction, Instant::now());
 2035                                    }
 2036                                    buffer.merge_transactions(
 2037                                        transaction_id_project_transaction,
 2038                                        formatting_transaction_id,
 2039                                    );
 2040                                })?;
 2041                            }
 2042
 2043                            if !project_transaction_command.0.is_empty() {
 2044                                let mut extra_buffers = String::new();
 2045                                for buffer in project_transaction_command.0.keys() {
 2046                                    buffer
 2047                                        .read_with(cx, |b, cx| {
 2048                                            if let Some(path) = b.project_path(cx) {
 2049                                                if !extra_buffers.is_empty() {
 2050                                                    extra_buffers.push_str(", ");
 2051                                                }
 2052                                                extra_buffers.push_str(path.path.as_unix_str());
 2053                                            }
 2054                                        })
 2055                                        .ok();
 2056                                }
 2057                                zlog::warn!(
 2058                                    logger =>
 2059                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2060                                    &command.command,
 2061                                    extra_buffers,
 2062                                );
 2063                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2064                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2065                                // add it so it's included, and merge it into the format transaction when its created later
 2066                            }
 2067                        }
 2068                    }
 2069                }
 2070            }
 2071        }
 2072
 2073        Ok(())
 2074    }
 2075
 2076    pub async fn format_ranges_via_lsp(
 2077        this: &WeakEntity<LspStore>,
 2078        buffer_handle: &Entity<Buffer>,
 2079        ranges: &[Range<Anchor>],
 2080        abs_path: &Path,
 2081        language_server: &Arc<LanguageServer>,
 2082        settings: &LanguageSettings,
 2083        cx: &mut AsyncApp,
 2084    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2085        let capabilities = &language_server.capabilities();
 2086        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2087        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2088            anyhow::bail!(
 2089                "{} language server does not support range formatting",
 2090                language_server.name()
 2091            );
 2092        }
 2093
 2094        let uri = file_path_to_lsp_url(abs_path)?;
 2095        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2096
 2097        let lsp_edits = {
 2098            let mut lsp_ranges = Vec::new();
 2099            this.update(cx, |_this, cx| {
 2100                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2101                // not have been sent to the language server. This seems like a fairly systemic
 2102                // issue, though, the resolution probably is not specific to formatting.
 2103                //
 2104                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2105                // LSP.
 2106                let snapshot = buffer_handle.read(cx).snapshot();
 2107                for range in ranges {
 2108                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2109                }
 2110                anyhow::Ok(())
 2111            })??;
 2112
 2113            let mut edits = None;
 2114            for range in lsp_ranges {
 2115                if let Some(mut edit) = language_server
 2116                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2117                        text_document: text_document.clone(),
 2118                        range,
 2119                        options: lsp_command::lsp_formatting_options(settings),
 2120                        work_done_progress_params: Default::default(),
 2121                    })
 2122                    .await
 2123                    .into_response()?
 2124                {
 2125                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2126                }
 2127            }
 2128            edits
 2129        };
 2130
 2131        if let Some(lsp_edits) = lsp_edits {
 2132            this.update(cx, |this, cx| {
 2133                this.as_local_mut().unwrap().edits_from_lsp(
 2134                    buffer_handle,
 2135                    lsp_edits,
 2136                    language_server.server_id(),
 2137                    None,
 2138                    cx,
 2139                )
 2140            })?
 2141            .await
 2142        } else {
 2143            Ok(Vec::with_capacity(0))
 2144        }
 2145    }
 2146
 2147    async fn format_via_lsp(
 2148        this: &WeakEntity<LspStore>,
 2149        buffer: &Entity<Buffer>,
 2150        abs_path: &Path,
 2151        language_server: &Arc<LanguageServer>,
 2152        settings: &LanguageSettings,
 2153        cx: &mut AsyncApp,
 2154    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2155        let logger = zlog::scoped!("lsp_format");
 2156        zlog::debug!(logger => "Formatting via LSP");
 2157
 2158        let uri = file_path_to_lsp_url(abs_path)?;
 2159        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2160        let capabilities = &language_server.capabilities();
 2161
 2162        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2163        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2164
 2165        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2166            let _timer = zlog::time!(logger => "format-full");
 2167            language_server
 2168                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2169                    text_document,
 2170                    options: lsp_command::lsp_formatting_options(settings),
 2171                    work_done_progress_params: Default::default(),
 2172                })
 2173                .await
 2174                .into_response()?
 2175        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2176            let _timer = zlog::time!(logger => "format-range");
 2177            let buffer_start = lsp::Position::new(0, 0);
 2178            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2179            language_server
 2180                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2181                    text_document: text_document.clone(),
 2182                    range: lsp::Range::new(buffer_start, buffer_end),
 2183                    options: lsp_command::lsp_formatting_options(settings),
 2184                    work_done_progress_params: Default::default(),
 2185                })
 2186                .await
 2187                .into_response()?
 2188        } else {
 2189            None
 2190        };
 2191
 2192        if let Some(lsp_edits) = lsp_edits {
 2193            this.update(cx, |this, cx| {
 2194                this.as_local_mut().unwrap().edits_from_lsp(
 2195                    buffer,
 2196                    lsp_edits,
 2197                    language_server.server_id(),
 2198                    None,
 2199                    cx,
 2200                )
 2201            })?
 2202            .await
 2203        } else {
 2204            Ok(Vec::with_capacity(0))
 2205        }
 2206    }
 2207
 2208    async fn format_via_external_command(
 2209        buffer: &FormattableBuffer,
 2210        command: &str,
 2211        arguments: Option<&[String]>,
 2212        cx: &mut AsyncApp,
 2213    ) -> Result<Option<Diff>> {
 2214        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2215            let file = File::from_dyn(buffer.file())?;
 2216            let worktree = file.worktree.read(cx);
 2217            let mut worktree_path = worktree.abs_path().to_path_buf();
 2218            if worktree.root_entry()?.is_file() {
 2219                worktree_path.pop();
 2220            }
 2221            Some(worktree_path)
 2222        })?;
 2223
 2224        let mut child = util::command::new_smol_command(command);
 2225
 2226        if let Some(buffer_env) = buffer.env.as_ref() {
 2227            child.envs(buffer_env);
 2228        }
 2229
 2230        if let Some(working_dir_path) = working_dir_path {
 2231            child.current_dir(working_dir_path);
 2232        }
 2233
 2234        if let Some(arguments) = arguments {
 2235            child.args(arguments.iter().map(|arg| {
 2236                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2237                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2238                } else {
 2239                    arg.replace("{buffer_path}", "Untitled")
 2240                }
 2241            }));
 2242        }
 2243
 2244        let mut child = child
 2245            .stdin(smol::process::Stdio::piped())
 2246            .stdout(smol::process::Stdio::piped())
 2247            .stderr(smol::process::Stdio::piped())
 2248            .spawn()?;
 2249
 2250        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2251        let text = buffer
 2252            .handle
 2253            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2254        for chunk in text.chunks() {
 2255            stdin.write_all(chunk.as_bytes()).await?;
 2256        }
 2257        stdin.flush().await?;
 2258
 2259        let output = child.output().await?;
 2260        anyhow::ensure!(
 2261            output.status.success(),
 2262            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2263            output.status.code(),
 2264            String::from_utf8_lossy(&output.stdout),
 2265            String::from_utf8_lossy(&output.stderr),
 2266        );
 2267
 2268        let stdout = String::from_utf8(output.stdout)?;
 2269        Ok(Some(
 2270            buffer
 2271                .handle
 2272                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2273                .await,
 2274        ))
 2275    }
 2276
 2277    async fn try_resolve_code_action(
 2278        lang_server: &LanguageServer,
 2279        action: &mut CodeAction,
 2280    ) -> anyhow::Result<()> {
 2281        match &mut action.lsp_action {
 2282            LspAction::Action(lsp_action) => {
 2283                if !action.resolved
 2284                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2285                    && lsp_action.data.is_some()
 2286                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2287                {
 2288                    **lsp_action = lang_server
 2289                        .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2290                        .await
 2291                        .into_response()?;
 2292                }
 2293            }
 2294            LspAction::CodeLens(lens) => {
 2295                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2296                    *lens = lang_server
 2297                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2298                        .await
 2299                        .into_response()?;
 2300                }
 2301            }
 2302            LspAction::Command(_) => {}
 2303        }
 2304
 2305        action.resolved = true;
 2306        anyhow::Ok(())
 2307    }
 2308
 2309    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2310        let buffer = buffer_handle.read(cx);
 2311
 2312        let file = buffer.file().cloned();
 2313
 2314        let Some(file) = File::from_dyn(file.as_ref()) else {
 2315            return;
 2316        };
 2317        if !file.is_local() {
 2318            return;
 2319        }
 2320        let path = ProjectPath::from_file(file, cx);
 2321        let worktree_id = file.worktree_id(cx);
 2322        let language = buffer.language().cloned();
 2323
 2324        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2325            for (server_id, diagnostics) in
 2326                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2327            {
 2328                self.update_buffer_diagnostics(
 2329                    buffer_handle,
 2330                    server_id,
 2331                    None,
 2332                    None,
 2333                    None,
 2334                    Vec::new(),
 2335                    diagnostics,
 2336                    cx,
 2337                )
 2338                .log_err();
 2339            }
 2340        }
 2341        let Some(language) = language else {
 2342            return;
 2343        };
 2344        let Some(snapshot) = self
 2345            .worktree_store
 2346            .read(cx)
 2347            .worktree_for_id(worktree_id, cx)
 2348            .map(|worktree| worktree.read(cx).snapshot())
 2349        else {
 2350            return;
 2351        };
 2352        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2353
 2354        for server_id in
 2355            self.lsp_tree
 2356                .get(path, language.name(), language.manifest(), &delegate, cx)
 2357        {
 2358            let server = self
 2359                .language_servers
 2360                .get(&server_id)
 2361                .and_then(|server_state| {
 2362                    if let LanguageServerState::Running { server, .. } = server_state {
 2363                        Some(server.clone())
 2364                    } else {
 2365                        None
 2366                    }
 2367                });
 2368            let server = match server {
 2369                Some(server) => server,
 2370                None => continue,
 2371            };
 2372
 2373            buffer_handle.update(cx, |buffer, cx| {
 2374                buffer.set_completion_triggers(
 2375                    server.server_id(),
 2376                    server
 2377                        .capabilities()
 2378                        .completion_provider
 2379                        .as_ref()
 2380                        .and_then(|provider| {
 2381                            provider
 2382                                .trigger_characters
 2383                                .as_ref()
 2384                                .map(|characters| characters.iter().cloned().collect())
 2385                        })
 2386                        .unwrap_or_default(),
 2387                    cx,
 2388                );
 2389            });
 2390        }
 2391    }
 2392
 2393    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2394        buffer.update(cx, |buffer, cx| {
 2395            let Some(language) = buffer.language() else {
 2396                return;
 2397            };
 2398            let path = ProjectPath {
 2399                worktree_id: old_file.worktree_id(cx),
 2400                path: old_file.path.clone(),
 2401            };
 2402            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2403                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2404                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2405            }
 2406        });
 2407    }
 2408
 2409    fn update_buffer_diagnostics(
 2410        &mut self,
 2411        buffer: &Entity<Buffer>,
 2412        server_id: LanguageServerId,
 2413        registration_id: Option<Option<SharedString>>,
 2414        result_id: Option<SharedString>,
 2415        version: Option<i32>,
 2416        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2417        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2418        cx: &mut Context<LspStore>,
 2419    ) -> Result<()> {
 2420        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2421            Ordering::Equal
 2422                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2423                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2424                .then_with(|| a.severity.cmp(&b.severity))
 2425                .then_with(|| a.message.cmp(&b.message))
 2426        }
 2427
 2428        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2429        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2430        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2431
 2432        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2433            Ordering::Equal
 2434                .then_with(|| a.range.start.cmp(&b.range.start))
 2435                .then_with(|| b.range.end.cmp(&a.range.end))
 2436                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2437        });
 2438
 2439        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2440
 2441        let edits_since_save = std::cell::LazyCell::new(|| {
 2442            let saved_version = buffer.read(cx).saved_version();
 2443            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2444        });
 2445
 2446        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2447
 2448        for (new_diagnostic, entry) in diagnostics {
 2449            let start;
 2450            let end;
 2451            if new_diagnostic && entry.diagnostic.is_disk_based {
 2452                // Some diagnostics are based on files on disk instead of buffers'
 2453                // current contents. Adjust these diagnostics' ranges to reflect
 2454                // any unsaved edits.
 2455                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2456                // and were properly adjusted on reuse.
 2457                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2458                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2459            } else {
 2460                start = entry.range.start;
 2461                end = entry.range.end;
 2462            }
 2463
 2464            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2465                ..snapshot.clip_point_utf16(end, Bias::Right);
 2466
 2467            // Expand empty ranges by one codepoint
 2468            if range.start == range.end {
 2469                // This will be go to the next boundary when being clipped
 2470                range.end.column += 1;
 2471                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2472                if range.start == range.end && range.end.column > 0 {
 2473                    range.start.column -= 1;
 2474                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2475                }
 2476            }
 2477
 2478            sanitized_diagnostics.push(DiagnosticEntry {
 2479                range,
 2480                diagnostic: entry.diagnostic,
 2481            });
 2482        }
 2483        drop(edits_since_save);
 2484
 2485        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2486        buffer.update(cx, |buffer, cx| {
 2487            if let Some(registration_id) = registration_id {
 2488                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2489                    self.buffer_pull_diagnostics_result_ids
 2490                        .entry(server_id)
 2491                        .or_default()
 2492                        .entry(registration_id)
 2493                        .or_default()
 2494                        .insert(abs_path, result_id);
 2495                }
 2496            }
 2497
 2498            buffer.update_diagnostics(server_id, set, cx)
 2499        });
 2500
 2501        Ok(())
 2502    }
 2503
 2504    fn register_language_server_for_invisible_worktree(
 2505        &mut self,
 2506        worktree: &Entity<Worktree>,
 2507        language_server_id: LanguageServerId,
 2508        cx: &mut App,
 2509    ) {
 2510        let worktree = worktree.read(cx);
 2511        let worktree_id = worktree.id();
 2512        debug_assert!(!worktree.is_visible());
 2513        let Some(mut origin_seed) = self
 2514            .language_server_ids
 2515            .iter()
 2516            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2517        else {
 2518            return;
 2519        };
 2520        origin_seed.worktree_id = worktree_id;
 2521        self.language_server_ids
 2522            .entry(origin_seed)
 2523            .or_insert_with(|| UnifiedLanguageServer {
 2524                id: language_server_id,
 2525                project_roots: Default::default(),
 2526            });
 2527    }
 2528
 2529    fn register_buffer_with_language_servers(
 2530        &mut self,
 2531        buffer_handle: &Entity<Buffer>,
 2532        only_register_servers: HashSet<LanguageServerSelector>,
 2533        cx: &mut Context<LspStore>,
 2534    ) {
 2535        let buffer = buffer_handle.read(cx);
 2536        let buffer_id = buffer.remote_id();
 2537
 2538        let Some(file) = File::from_dyn(buffer.file()) else {
 2539            return;
 2540        };
 2541        if !file.is_local() {
 2542            return;
 2543        }
 2544
 2545        let abs_path = file.abs_path(cx);
 2546        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2547            return;
 2548        };
 2549        let initial_snapshot = buffer.text_snapshot();
 2550        let worktree_id = file.worktree_id(cx);
 2551
 2552        let Some(language) = buffer.language().cloned() else {
 2553            return;
 2554        };
 2555        let path: Arc<RelPath> = file
 2556            .path()
 2557            .parent()
 2558            .map(Arc::from)
 2559            .unwrap_or_else(|| file.path().clone());
 2560        let Some(worktree) = self
 2561            .worktree_store
 2562            .read(cx)
 2563            .worktree_for_id(worktree_id, cx)
 2564        else {
 2565            return;
 2566        };
 2567        let language_name = language.name();
 2568        let (reused, delegate, servers) = self
 2569            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2570            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2571            .unwrap_or_else(|| {
 2572                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2573                let delegate: Arc<dyn ManifestDelegate> =
 2574                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2575
 2576                let servers = self
 2577                    .lsp_tree
 2578                    .walk(
 2579                        ProjectPath { worktree_id, path },
 2580                        language.name(),
 2581                        language.manifest(),
 2582                        &delegate,
 2583                        cx,
 2584                    )
 2585                    .collect::<Vec<_>>();
 2586                (false, lsp_delegate, servers)
 2587            });
 2588        let servers_and_adapters = servers
 2589            .into_iter()
 2590            .filter_map(|server_node| {
 2591                if reused && server_node.server_id().is_none() {
 2592                    return None;
 2593                }
 2594                if !only_register_servers.is_empty() {
 2595                    if let Some(server_id) = server_node.server_id()
 2596                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2597                    {
 2598                        return None;
 2599                    }
 2600                    if let Some(name) = server_node.name()
 2601                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2602                    {
 2603                        return None;
 2604                    }
 2605                }
 2606
 2607                let server_id = server_node.server_id_or_init(|disposition| {
 2608                    let path = &disposition.path;
 2609
 2610                    {
 2611                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2612
 2613                        let server_id = self.get_or_insert_language_server(
 2614                            &worktree,
 2615                            delegate.clone(),
 2616                            disposition,
 2617                            &language_name,
 2618                            cx,
 2619                        );
 2620
 2621                        if let Some(state) = self.language_servers.get(&server_id)
 2622                            && let Ok(uri) = uri
 2623                        {
 2624                            state.add_workspace_folder(uri);
 2625                        };
 2626                        server_id
 2627                    }
 2628                })?;
 2629                let server_state = self.language_servers.get(&server_id)?;
 2630                if let LanguageServerState::Running {
 2631                    server, adapter, ..
 2632                } = server_state
 2633                {
 2634                    Some((server.clone(), adapter.clone()))
 2635                } else {
 2636                    None
 2637                }
 2638            })
 2639            .collect::<Vec<_>>();
 2640        for (server, adapter) in servers_and_adapters {
 2641            buffer_handle.update(cx, |buffer, cx| {
 2642                buffer.set_completion_triggers(
 2643                    server.server_id(),
 2644                    server
 2645                        .capabilities()
 2646                        .completion_provider
 2647                        .as_ref()
 2648                        .and_then(|provider| {
 2649                            provider
 2650                                .trigger_characters
 2651                                .as_ref()
 2652                                .map(|characters| characters.iter().cloned().collect())
 2653                        })
 2654                        .unwrap_or_default(),
 2655                    cx,
 2656                );
 2657            });
 2658
 2659            let snapshot = LspBufferSnapshot {
 2660                version: 0,
 2661                snapshot: initial_snapshot.clone(),
 2662            };
 2663
 2664            let mut registered = false;
 2665            self.buffer_snapshots
 2666                .entry(buffer_id)
 2667                .or_default()
 2668                .entry(server.server_id())
 2669                .or_insert_with(|| {
 2670                    registered = true;
 2671                    server.register_buffer(
 2672                        uri.clone(),
 2673                        adapter.language_id(&language.name()),
 2674                        0,
 2675                        initial_snapshot.text(),
 2676                    );
 2677
 2678                    vec![snapshot]
 2679                });
 2680
 2681            self.buffers_opened_in_servers
 2682                .entry(buffer_id)
 2683                .or_default()
 2684                .insert(server.server_id());
 2685            if registered {
 2686                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2687                    language_server_id: server.server_id(),
 2688                    name: None,
 2689                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2690                        proto::RegisteredForBuffer {
 2691                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2692                            buffer_id: buffer_id.to_proto(),
 2693                        },
 2694                    ),
 2695                });
 2696            }
 2697        }
 2698    }
 2699
 2700    fn reuse_existing_language_server<'lang_name>(
 2701        &self,
 2702        server_tree: &LanguageServerTree,
 2703        worktree: &Entity<Worktree>,
 2704        language_name: &'lang_name LanguageName,
 2705        cx: &mut App,
 2706    ) -> Option<(
 2707        Arc<LocalLspAdapterDelegate>,
 2708        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2709    )> {
 2710        if worktree.read(cx).is_visible() {
 2711            return None;
 2712        }
 2713
 2714        let worktree_store = self.worktree_store.read(cx);
 2715        let servers = server_tree
 2716            .instances
 2717            .iter()
 2718            .filter(|(worktree_id, _)| {
 2719                worktree_store
 2720                    .worktree_for_id(**worktree_id, cx)
 2721                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2722            })
 2723            .flat_map(|(worktree_id, servers)| {
 2724                servers
 2725                    .roots
 2726                    .iter()
 2727                    .flat_map(|(_, language_servers)| language_servers)
 2728                    .map(move |(_, (server_node, server_languages))| {
 2729                        (worktree_id, server_node, server_languages)
 2730                    })
 2731                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2732                    .map(|(worktree_id, server_node, _)| {
 2733                        (
 2734                            *worktree_id,
 2735                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2736                        )
 2737                    })
 2738            })
 2739            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2740                acc.entry(worktree_id)
 2741                    .or_insert_with(Vec::new)
 2742                    .push(server_node);
 2743                acc
 2744            })
 2745            .into_values()
 2746            .max_by_key(|servers| servers.len())?;
 2747
 2748        let worktree_id = worktree.read(cx).id();
 2749        let apply = move |tree: &mut LanguageServerTree| {
 2750            for server_node in &servers {
 2751                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2752            }
 2753            servers
 2754        };
 2755
 2756        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2757        Some((delegate, apply))
 2758    }
 2759
 2760    pub(crate) fn unregister_old_buffer_from_language_servers(
 2761        &mut self,
 2762        buffer: &Entity<Buffer>,
 2763        old_file: &File,
 2764        cx: &mut App,
 2765    ) {
 2766        let old_path = match old_file.as_local() {
 2767            Some(local) => local.abs_path(cx),
 2768            None => return,
 2769        };
 2770
 2771        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2772            debug_panic!("{old_path:?} is not parseable as an URI");
 2773            return;
 2774        };
 2775        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2776    }
 2777
 2778    pub(crate) fn unregister_buffer_from_language_servers(
 2779        &mut self,
 2780        buffer: &Entity<Buffer>,
 2781        file_url: &lsp::Uri,
 2782        cx: &mut App,
 2783    ) {
 2784        buffer.update(cx, |buffer, cx| {
 2785            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2786
 2787            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2788                if snapshots
 2789                    .as_mut()
 2790                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2791                {
 2792                    language_server.unregister_buffer(file_url.clone());
 2793                }
 2794            }
 2795        });
 2796    }
 2797
 2798    fn buffer_snapshot_for_lsp_version(
 2799        &mut self,
 2800        buffer: &Entity<Buffer>,
 2801        server_id: LanguageServerId,
 2802        version: Option<i32>,
 2803        cx: &App,
 2804    ) -> Result<TextBufferSnapshot> {
 2805        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2806
 2807        if let Some(version) = version {
 2808            let buffer_id = buffer.read(cx).remote_id();
 2809            let snapshots = if let Some(snapshots) = self
 2810                .buffer_snapshots
 2811                .get_mut(&buffer_id)
 2812                .and_then(|m| m.get_mut(&server_id))
 2813            {
 2814                snapshots
 2815            } else if version == 0 {
 2816                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2817                // We detect this case and treat it as if the version was `None`.
 2818                return Ok(buffer.read(cx).text_snapshot());
 2819            } else {
 2820                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2821            };
 2822
 2823            let found_snapshot = snapshots
 2824                    .binary_search_by_key(&version, |e| e.version)
 2825                    .map(|ix| snapshots[ix].snapshot.clone())
 2826                    .map_err(|_| {
 2827                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2828                    })?;
 2829
 2830            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2831            Ok(found_snapshot)
 2832        } else {
 2833            Ok((buffer.read(cx)).text_snapshot())
 2834        }
 2835    }
 2836
 2837    async fn get_server_code_actions_from_action_kinds(
 2838        lsp_store: &WeakEntity<LspStore>,
 2839        language_server_id: LanguageServerId,
 2840        code_action_kinds: Vec<lsp::CodeActionKind>,
 2841        buffer: &Entity<Buffer>,
 2842        cx: &mut AsyncApp,
 2843    ) -> Result<Vec<CodeAction>> {
 2844        let actions = lsp_store
 2845            .update(cx, move |this, cx| {
 2846                let request = GetCodeActions {
 2847                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 2848                    kinds: Some(code_action_kinds),
 2849                };
 2850                let server = LanguageServerToQuery::Other(language_server_id);
 2851                this.request_lsp(buffer.clone(), server, request, cx)
 2852            })?
 2853            .await?;
 2854        Ok(actions)
 2855    }
 2856
 2857    pub async fn execute_code_actions_on_server(
 2858        lsp_store: &WeakEntity<LspStore>,
 2859        language_server: &Arc<LanguageServer>,
 2860
 2861        actions: Vec<CodeAction>,
 2862        push_to_history: bool,
 2863        project_transaction: &mut ProjectTransaction,
 2864        cx: &mut AsyncApp,
 2865    ) -> anyhow::Result<()> {
 2866        for mut action in actions {
 2867            Self::try_resolve_code_action(language_server, &mut action)
 2868                .await
 2869                .context("resolving a formatting code action")?;
 2870
 2871            if let Some(edit) = action.lsp_action.edit() {
 2872                if edit.changes.is_none() && edit.document_changes.is_none() {
 2873                    continue;
 2874                }
 2875
 2876                let new = Self::deserialize_workspace_edit(
 2877                    lsp_store.upgrade().context("project dropped")?,
 2878                    edit.clone(),
 2879                    push_to_history,
 2880                    language_server.clone(),
 2881                    cx,
 2882                )
 2883                .await?;
 2884                project_transaction.0.extend(new.0);
 2885            }
 2886
 2887            if let Some(command) = action.lsp_action.command() {
 2888                let server_capabilities = language_server.capabilities();
 2889                let available_commands = server_capabilities
 2890                    .execute_command_provider
 2891                    .as_ref()
 2892                    .map(|options| options.commands.as_slice())
 2893                    .unwrap_or_default();
 2894                if available_commands.contains(&command.command) {
 2895                    lsp_store.update(cx, |lsp_store, _| {
 2896                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2897                            mode.last_workspace_edits_by_language_server
 2898                                .remove(&language_server.server_id());
 2899                        }
 2900                    })?;
 2901
 2902                    language_server
 2903                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2904                            command: command.command.clone(),
 2905                            arguments: command.arguments.clone().unwrap_or_default(),
 2906                            ..Default::default()
 2907                        })
 2908                        .await
 2909                        .into_response()
 2910                        .context("execute command")?;
 2911
 2912                    lsp_store.update(cx, |this, _| {
 2913                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2914                            project_transaction.0.extend(
 2915                                mode.last_workspace_edits_by_language_server
 2916                                    .remove(&language_server.server_id())
 2917                                    .unwrap_or_default()
 2918                                    .0,
 2919                            )
 2920                        }
 2921                    })?;
 2922                } else {
 2923                    log::warn!(
 2924                        "Cannot execute a command {} not listed in the language server capabilities",
 2925                        command.command
 2926                    )
 2927                }
 2928            }
 2929        }
 2930        Ok(())
 2931    }
 2932
 2933    pub async fn deserialize_text_edits(
 2934        this: Entity<LspStore>,
 2935        buffer_to_edit: Entity<Buffer>,
 2936        edits: Vec<lsp::TextEdit>,
 2937        push_to_history: bool,
 2938        _: Arc<CachedLspAdapter>,
 2939        language_server: Arc<LanguageServer>,
 2940        cx: &mut AsyncApp,
 2941    ) -> Result<Option<Transaction>> {
 2942        let edits = this
 2943            .update(cx, |this, cx| {
 2944                this.as_local_mut().unwrap().edits_from_lsp(
 2945                    &buffer_to_edit,
 2946                    edits,
 2947                    language_server.server_id(),
 2948                    None,
 2949                    cx,
 2950                )
 2951            })?
 2952            .await?;
 2953
 2954        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2955            buffer.finalize_last_transaction();
 2956            buffer.start_transaction();
 2957            for (range, text) in edits {
 2958                buffer.edit([(range, text)], None, cx);
 2959            }
 2960
 2961            if buffer.end_transaction(cx).is_some() {
 2962                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2963                if !push_to_history {
 2964                    buffer.forget_transaction(transaction.id);
 2965                }
 2966                Some(transaction)
 2967            } else {
 2968                None
 2969            }
 2970        })?;
 2971
 2972        Ok(transaction)
 2973    }
 2974
 2975    #[allow(clippy::type_complexity)]
 2976    pub(crate) fn edits_from_lsp(
 2977        &mut self,
 2978        buffer: &Entity<Buffer>,
 2979        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2980        server_id: LanguageServerId,
 2981        version: Option<i32>,
 2982        cx: &mut Context<LspStore>,
 2983    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2984        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2985        cx.background_spawn(async move {
 2986            let snapshot = snapshot?;
 2987            let mut lsp_edits = lsp_edits
 2988                .into_iter()
 2989                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2990                .collect::<Vec<_>>();
 2991
 2992            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2993
 2994            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2995            let mut edits = Vec::new();
 2996            while let Some((range, mut new_text)) = lsp_edits.next() {
 2997                // Clip invalid ranges provided by the language server.
 2998                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2999                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3000
 3001                // Combine any LSP edits that are adjacent.
 3002                //
 3003                // Also, combine LSP edits that are separated from each other by only
 3004                // a newline. This is important because for some code actions,
 3005                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3006                // are separated by unchanged newline characters.
 3007                //
 3008                // In order for the diffing logic below to work properly, any edits that
 3009                // cancel each other out must be combined into one.
 3010                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3011                    if next_range.start.0 > range.end {
 3012                        if next_range.start.0.row > range.end.row + 1
 3013                            || next_range.start.0.column > 0
 3014                            || snapshot.clip_point_utf16(
 3015                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3016                                Bias::Left,
 3017                            ) > range.end
 3018                        {
 3019                            break;
 3020                        }
 3021                        new_text.push('\n');
 3022                    }
 3023                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3024                    new_text.push_str(next_text);
 3025                    lsp_edits.next();
 3026                }
 3027
 3028                // For multiline edits, perform a diff of the old and new text so that
 3029                // we can identify the changes more precisely, preserving the locations
 3030                // of any anchors positioned in the unchanged regions.
 3031                if range.end.row > range.start.row {
 3032                    let offset = range.start.to_offset(&snapshot);
 3033                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3034                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3035                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3036                        (
 3037                            snapshot.anchor_after(offset + range.start)
 3038                                ..snapshot.anchor_before(offset + range.end),
 3039                            replacement,
 3040                        )
 3041                    }));
 3042                } else if range.end == range.start {
 3043                    let anchor = snapshot.anchor_after(range.start);
 3044                    edits.push((anchor..anchor, new_text.into()));
 3045                } else {
 3046                    let edit_start = snapshot.anchor_after(range.start);
 3047                    let edit_end = snapshot.anchor_before(range.end);
 3048                    edits.push((edit_start..edit_end, new_text.into()));
 3049                }
 3050            }
 3051
 3052            Ok(edits)
 3053        })
 3054    }
 3055
 3056    pub(crate) async fn deserialize_workspace_edit(
 3057        this: Entity<LspStore>,
 3058        edit: lsp::WorkspaceEdit,
 3059        push_to_history: bool,
 3060        language_server: Arc<LanguageServer>,
 3061        cx: &mut AsyncApp,
 3062    ) -> Result<ProjectTransaction> {
 3063        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 3064
 3065        let mut operations = Vec::new();
 3066        if let Some(document_changes) = edit.document_changes {
 3067            match document_changes {
 3068                lsp::DocumentChanges::Edits(edits) => {
 3069                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3070                }
 3071                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3072            }
 3073        } else if let Some(changes) = edit.changes {
 3074            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3075                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3076                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3077                        uri,
 3078                        version: None,
 3079                    },
 3080                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3081                })
 3082            }));
 3083        }
 3084
 3085        let mut project_transaction = ProjectTransaction::default();
 3086        for operation in operations {
 3087            match operation {
 3088                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3089                    let abs_path = op
 3090                        .uri
 3091                        .to_file_path()
 3092                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3093
 3094                    if let Some(parent_path) = abs_path.parent() {
 3095                        fs.create_dir(parent_path).await?;
 3096                    }
 3097                    if abs_path.ends_with("/") {
 3098                        fs.create_dir(&abs_path).await?;
 3099                    } else {
 3100                        fs.create_file(
 3101                            &abs_path,
 3102                            op.options
 3103                                .map(|options| fs::CreateOptions {
 3104                                    overwrite: options.overwrite.unwrap_or(false),
 3105                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3106                                })
 3107                                .unwrap_or_default(),
 3108                        )
 3109                        .await?;
 3110                    }
 3111                }
 3112
 3113                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3114                    let source_abs_path = op
 3115                        .old_uri
 3116                        .to_file_path()
 3117                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3118                    let target_abs_path = op
 3119                        .new_uri
 3120                        .to_file_path()
 3121                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3122
 3123                    let options = fs::RenameOptions {
 3124                        overwrite: op
 3125                            .options
 3126                            .as_ref()
 3127                            .and_then(|options| options.overwrite)
 3128                            .unwrap_or(false),
 3129                        ignore_if_exists: op
 3130                            .options
 3131                            .as_ref()
 3132                            .and_then(|options| options.ignore_if_exists)
 3133                            .unwrap_or(false),
 3134                        create_parents: true,
 3135                    };
 3136
 3137                    fs.rename(&source_abs_path, &target_abs_path, options)
 3138                        .await?;
 3139                }
 3140
 3141                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3142                    let abs_path = op
 3143                        .uri
 3144                        .to_file_path()
 3145                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3146                    let options = op
 3147                        .options
 3148                        .map(|options| fs::RemoveOptions {
 3149                            recursive: options.recursive.unwrap_or(false),
 3150                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3151                        })
 3152                        .unwrap_or_default();
 3153                    if abs_path.ends_with("/") {
 3154                        fs.remove_dir(&abs_path, options).await?;
 3155                    } else {
 3156                        fs.remove_file(&abs_path, options).await?;
 3157                    }
 3158                }
 3159
 3160                lsp::DocumentChangeOperation::Edit(op) => {
 3161                    let buffer_to_edit = this
 3162                        .update(cx, |this, cx| {
 3163                            this.open_local_buffer_via_lsp(
 3164                                op.text_document.uri.clone(),
 3165                                language_server.server_id(),
 3166                                cx,
 3167                            )
 3168                        })?
 3169                        .await?;
 3170
 3171                    let edits = this
 3172                        .update(cx, |this, cx| {
 3173                            let path = buffer_to_edit.read(cx).project_path(cx);
 3174                            let active_entry = this.active_entry;
 3175                            let is_active_entry = path.is_some_and(|project_path| {
 3176                                this.worktree_store
 3177                                    .read(cx)
 3178                                    .entry_for_path(&project_path, cx)
 3179                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3180                            });
 3181                            let local = this.as_local_mut().unwrap();
 3182
 3183                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3184                            for edit in op.edits {
 3185                                match edit {
 3186                                    Edit::Plain(edit) => {
 3187                                        if !edits.contains(&edit) {
 3188                                            edits.push(edit)
 3189                                        }
 3190                                    }
 3191                                    Edit::Annotated(edit) => {
 3192                                        if !edits.contains(&edit.text_edit) {
 3193                                            edits.push(edit.text_edit)
 3194                                        }
 3195                                    }
 3196                                    Edit::Snippet(edit) => {
 3197                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3198                                        else {
 3199                                            continue;
 3200                                        };
 3201
 3202                                        if is_active_entry {
 3203                                            snippet_edits.push((edit.range, snippet));
 3204                                        } else {
 3205                                            // Since this buffer is not focused, apply a normal edit.
 3206                                            let new_edit = TextEdit {
 3207                                                range: edit.range,
 3208                                                new_text: snippet.text,
 3209                                            };
 3210                                            if !edits.contains(&new_edit) {
 3211                                                edits.push(new_edit);
 3212                                            }
 3213                                        }
 3214                                    }
 3215                                }
 3216                            }
 3217                            if !snippet_edits.is_empty() {
 3218                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3219                                let version = if let Some(buffer_version) = op.text_document.version
 3220                                {
 3221                                    local
 3222                                        .buffer_snapshot_for_lsp_version(
 3223                                            &buffer_to_edit,
 3224                                            language_server.server_id(),
 3225                                            Some(buffer_version),
 3226                                            cx,
 3227                                        )
 3228                                        .ok()
 3229                                        .map(|snapshot| snapshot.version)
 3230                                } else {
 3231                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3232                                };
 3233
 3234                                let most_recent_edit =
 3235                                    version.and_then(|version| version.most_recent());
 3236                                // Check if the edit that triggered that edit has been made by this participant.
 3237
 3238                                if let Some(most_recent_edit) = most_recent_edit {
 3239                                    cx.emit(LspStoreEvent::SnippetEdit {
 3240                                        buffer_id,
 3241                                        edits: snippet_edits,
 3242                                        most_recent_edit,
 3243                                    });
 3244                                }
 3245                            }
 3246
 3247                            local.edits_from_lsp(
 3248                                &buffer_to_edit,
 3249                                edits,
 3250                                language_server.server_id(),
 3251                                op.text_document.version,
 3252                                cx,
 3253                            )
 3254                        })?
 3255                        .await?;
 3256
 3257                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3258                        buffer.finalize_last_transaction();
 3259                        buffer.start_transaction();
 3260                        for (range, text) in edits {
 3261                            buffer.edit([(range, text)], None, cx);
 3262                        }
 3263
 3264                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3265                            if push_to_history {
 3266                                buffer.finalize_last_transaction();
 3267                                buffer.get_transaction(transaction_id).cloned()
 3268                            } else {
 3269                                buffer.forget_transaction(transaction_id)
 3270                            }
 3271                        })
 3272                    })?;
 3273                    if let Some(transaction) = transaction {
 3274                        project_transaction.0.insert(buffer_to_edit, transaction);
 3275                    }
 3276                }
 3277            }
 3278        }
 3279
 3280        Ok(project_transaction)
 3281    }
 3282
 3283    async fn on_lsp_workspace_edit(
 3284        this: WeakEntity<LspStore>,
 3285        params: lsp::ApplyWorkspaceEditParams,
 3286        server_id: LanguageServerId,
 3287        cx: &mut AsyncApp,
 3288    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3289        let this = this.upgrade().context("project project closed")?;
 3290        let language_server = this
 3291            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3292            .context("language server not found")?;
 3293        let transaction = Self::deserialize_workspace_edit(
 3294            this.clone(),
 3295            params.edit,
 3296            true,
 3297            language_server.clone(),
 3298            cx,
 3299        )
 3300        .await
 3301        .log_err();
 3302        this.update(cx, |this, _| {
 3303            if let Some(transaction) = transaction {
 3304                this.as_local_mut()
 3305                    .unwrap()
 3306                    .last_workspace_edits_by_language_server
 3307                    .insert(server_id, transaction);
 3308            }
 3309        })?;
 3310        Ok(lsp::ApplyWorkspaceEditResponse {
 3311            applied: true,
 3312            failed_change: None,
 3313            failure_reason: None,
 3314        })
 3315    }
 3316
 3317    fn remove_worktree(
 3318        &mut self,
 3319        id_to_remove: WorktreeId,
 3320        cx: &mut Context<LspStore>,
 3321    ) -> Vec<LanguageServerId> {
 3322        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3323        self.diagnostics.remove(&id_to_remove);
 3324        self.prettier_store.update(cx, |prettier_store, cx| {
 3325            prettier_store.remove_worktree(id_to_remove, cx);
 3326        });
 3327
 3328        let mut servers_to_remove = BTreeSet::default();
 3329        let mut servers_to_preserve = HashSet::default();
 3330        for (seed, state) in &self.language_server_ids {
 3331            if seed.worktree_id == id_to_remove {
 3332                servers_to_remove.insert(state.id);
 3333            } else {
 3334                servers_to_preserve.insert(state.id);
 3335            }
 3336        }
 3337        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3338        self.language_server_ids
 3339            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3340        for server_id_to_remove in &servers_to_remove {
 3341            self.language_server_watched_paths
 3342                .remove(server_id_to_remove);
 3343            self.language_server_paths_watched_for_rename
 3344                .remove(server_id_to_remove);
 3345            self.last_workspace_edits_by_language_server
 3346                .remove(server_id_to_remove);
 3347            self.language_servers.remove(server_id_to_remove);
 3348            self.buffer_pull_diagnostics_result_ids
 3349                .remove(server_id_to_remove);
 3350            self.workspace_pull_diagnostics_result_ids
 3351                .remove(server_id_to_remove);
 3352            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3353                buffer_servers.remove(server_id_to_remove);
 3354            }
 3355            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3356        }
 3357        servers_to_remove.into_iter().collect()
 3358    }
 3359
 3360    fn rebuild_watched_paths_inner<'a>(
 3361        &'a self,
 3362        language_server_id: LanguageServerId,
 3363        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3364        cx: &mut Context<LspStore>,
 3365    ) -> LanguageServerWatchedPathsBuilder {
 3366        let worktrees = self
 3367            .worktree_store
 3368            .read(cx)
 3369            .worktrees()
 3370            .filter_map(|worktree| {
 3371                self.language_servers_for_worktree(worktree.read(cx).id())
 3372                    .find(|server| server.server_id() == language_server_id)
 3373                    .map(|_| worktree)
 3374            })
 3375            .collect::<Vec<_>>();
 3376
 3377        let mut worktree_globs = HashMap::default();
 3378        let mut abs_globs = HashMap::default();
 3379        log::trace!(
 3380            "Processing new watcher paths for language server with id {}",
 3381            language_server_id
 3382        );
 3383
 3384        for watcher in watchers {
 3385            if let Some((worktree, literal_prefix, pattern)) =
 3386                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3387            {
 3388                worktree.update(cx, |worktree, _| {
 3389                    if let Some((tree, glob)) =
 3390                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3391                    {
 3392                        tree.add_path_prefix_to_scan(literal_prefix);
 3393                        worktree_globs
 3394                            .entry(tree.id())
 3395                            .or_insert_with(GlobSetBuilder::new)
 3396                            .add(glob);
 3397                    }
 3398                });
 3399            } else {
 3400                let (path, pattern) = match &watcher.glob_pattern {
 3401                    lsp::GlobPattern::String(s) => {
 3402                        let watcher_path = SanitizedPath::new(s);
 3403                        let path = glob_literal_prefix(watcher_path.as_path());
 3404                        let pattern = watcher_path
 3405                            .as_path()
 3406                            .strip_prefix(&path)
 3407                            .map(|p| p.to_string_lossy().into_owned())
 3408                            .unwrap_or_else(|e| {
 3409                                debug_panic!(
 3410                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3411                                    s,
 3412                                    path.display(),
 3413                                    e
 3414                                );
 3415                                watcher_path.as_path().to_string_lossy().into_owned()
 3416                            });
 3417                        (path, pattern)
 3418                    }
 3419                    lsp::GlobPattern::Relative(rp) => {
 3420                        let Ok(mut base_uri) = match &rp.base_uri {
 3421                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3422                            lsp::OneOf::Right(base_uri) => base_uri,
 3423                        }
 3424                        .to_file_path() else {
 3425                            continue;
 3426                        };
 3427
 3428                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3429                        let pattern = Path::new(&rp.pattern)
 3430                            .strip_prefix(&path)
 3431                            .map(|p| p.to_string_lossy().into_owned())
 3432                            .unwrap_or_else(|e| {
 3433                                debug_panic!(
 3434                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3435                                    rp.pattern,
 3436                                    path.display(),
 3437                                    e
 3438                                );
 3439                                rp.pattern.clone()
 3440                            });
 3441                        base_uri.push(path);
 3442                        (base_uri, pattern)
 3443                    }
 3444                };
 3445
 3446                if let Some(glob) = Glob::new(&pattern).log_err() {
 3447                    if !path
 3448                        .components()
 3449                        .any(|c| matches!(c, path::Component::Normal(_)))
 3450                    {
 3451                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3452                        // rather than adding a new watcher for `/`.
 3453                        for worktree in &worktrees {
 3454                            worktree_globs
 3455                                .entry(worktree.read(cx).id())
 3456                                .or_insert_with(GlobSetBuilder::new)
 3457                                .add(glob.clone());
 3458                        }
 3459                    } else {
 3460                        abs_globs
 3461                            .entry(path.into())
 3462                            .or_insert_with(GlobSetBuilder::new)
 3463                            .add(glob);
 3464                    }
 3465                }
 3466            }
 3467        }
 3468
 3469        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3470        for (worktree_id, builder) in worktree_globs {
 3471            if let Ok(globset) = builder.build() {
 3472                watch_builder.watch_worktree(worktree_id, globset);
 3473            }
 3474        }
 3475        for (abs_path, builder) in abs_globs {
 3476            if let Ok(globset) = builder.build() {
 3477                watch_builder.watch_abs_path(abs_path, globset);
 3478            }
 3479        }
 3480        watch_builder
 3481    }
 3482
 3483    fn worktree_and_path_for_file_watcher(
 3484        worktrees: &[Entity<Worktree>],
 3485        watcher: &FileSystemWatcher,
 3486        cx: &App,
 3487    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3488        worktrees.iter().find_map(|worktree| {
 3489            let tree = worktree.read(cx);
 3490            let worktree_root_path = tree.abs_path();
 3491            let path_style = tree.path_style();
 3492            match &watcher.glob_pattern {
 3493                lsp::GlobPattern::String(s) => {
 3494                    let watcher_path = SanitizedPath::new(s);
 3495                    let relative = watcher_path
 3496                        .as_path()
 3497                        .strip_prefix(&worktree_root_path)
 3498                        .ok()?;
 3499                    let literal_prefix = glob_literal_prefix(relative);
 3500                    Some((
 3501                        worktree.clone(),
 3502                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3503                        relative.to_string_lossy().into_owned(),
 3504                    ))
 3505                }
 3506                lsp::GlobPattern::Relative(rp) => {
 3507                    let base_uri = match &rp.base_uri {
 3508                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3509                        lsp::OneOf::Right(base_uri) => base_uri,
 3510                    }
 3511                    .to_file_path()
 3512                    .ok()?;
 3513                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3514                    let mut literal_prefix = relative.to_owned();
 3515                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3516                    Some((
 3517                        worktree.clone(),
 3518                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3519                        rp.pattern.clone(),
 3520                    ))
 3521                }
 3522            }
 3523        })
 3524    }
 3525
 3526    fn rebuild_watched_paths(
 3527        &mut self,
 3528        language_server_id: LanguageServerId,
 3529        cx: &mut Context<LspStore>,
 3530    ) {
 3531        let Some(registrations) = self
 3532            .language_server_dynamic_registrations
 3533            .get(&language_server_id)
 3534        else {
 3535            return;
 3536        };
 3537
 3538        let watch_builder = self.rebuild_watched_paths_inner(
 3539            language_server_id,
 3540            registrations.did_change_watched_files.values().flatten(),
 3541            cx,
 3542        );
 3543        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3544        self.language_server_watched_paths
 3545            .insert(language_server_id, watcher);
 3546
 3547        cx.notify();
 3548    }
 3549
 3550    fn on_lsp_did_change_watched_files(
 3551        &mut self,
 3552        language_server_id: LanguageServerId,
 3553        registration_id: &str,
 3554        params: DidChangeWatchedFilesRegistrationOptions,
 3555        cx: &mut Context<LspStore>,
 3556    ) {
 3557        let registrations = self
 3558            .language_server_dynamic_registrations
 3559            .entry(language_server_id)
 3560            .or_default();
 3561
 3562        registrations
 3563            .did_change_watched_files
 3564            .insert(registration_id.to_string(), params.watchers);
 3565
 3566        self.rebuild_watched_paths(language_server_id, cx);
 3567    }
 3568
 3569    fn on_lsp_unregister_did_change_watched_files(
 3570        &mut self,
 3571        language_server_id: LanguageServerId,
 3572        registration_id: &str,
 3573        cx: &mut Context<LspStore>,
 3574    ) {
 3575        let registrations = self
 3576            .language_server_dynamic_registrations
 3577            .entry(language_server_id)
 3578            .or_default();
 3579
 3580        if registrations
 3581            .did_change_watched_files
 3582            .remove(registration_id)
 3583            .is_some()
 3584        {
 3585            log::info!(
 3586                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3587                language_server_id,
 3588                registration_id
 3589            );
 3590        } else {
 3591            log::warn!(
 3592                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3593                language_server_id,
 3594                registration_id
 3595            );
 3596        }
 3597
 3598        self.rebuild_watched_paths(language_server_id, cx);
 3599    }
 3600
 3601    async fn initialization_options_for_adapter(
 3602        adapter: Arc<dyn LspAdapter>,
 3603        delegate: &Arc<dyn LspAdapterDelegate>,
 3604    ) -> Result<Option<serde_json::Value>> {
 3605        let Some(mut initialization_config) =
 3606            adapter.clone().initialization_options(delegate).await?
 3607        else {
 3608            return Ok(None);
 3609        };
 3610
 3611        for other_adapter in delegate.registered_lsp_adapters() {
 3612            if other_adapter.name() == adapter.name() {
 3613                continue;
 3614            }
 3615            if let Ok(Some(target_config)) = other_adapter
 3616                .clone()
 3617                .additional_initialization_options(adapter.name(), delegate)
 3618                .await
 3619            {
 3620                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3621            }
 3622        }
 3623
 3624        Ok(Some(initialization_config))
 3625    }
 3626
 3627    async fn workspace_configuration_for_adapter(
 3628        adapter: Arc<dyn LspAdapter>,
 3629        delegate: &Arc<dyn LspAdapterDelegate>,
 3630        toolchain: Option<Toolchain>,
 3631        requested_uri: Option<Uri>,
 3632        cx: &mut AsyncApp,
 3633    ) -> Result<serde_json::Value> {
 3634        let mut workspace_config = adapter
 3635            .clone()
 3636            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3637            .await?;
 3638
 3639        for other_adapter in delegate.registered_lsp_adapters() {
 3640            if other_adapter.name() == adapter.name() {
 3641                continue;
 3642            }
 3643            if let Ok(Some(target_config)) = other_adapter
 3644                .clone()
 3645                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3646                .await
 3647            {
 3648                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3649            }
 3650        }
 3651
 3652        Ok(workspace_config)
 3653    }
 3654
 3655    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3656        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3657            Some(server.clone())
 3658        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3659            Some(Arc::clone(server))
 3660        } else {
 3661            None
 3662        }
 3663    }
 3664}
 3665
 3666fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3667    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3668        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3669            language_server_id: server.server_id(),
 3670            name: Some(server.name()),
 3671            message: proto::update_language_server::Variant::MetadataUpdated(
 3672                proto::ServerMetadataUpdated {
 3673                    capabilities: Some(capabilities),
 3674                    binary: Some(proto::LanguageServerBinaryInfo {
 3675                        path: server.binary().path.to_string_lossy().into_owned(),
 3676                        arguments: server
 3677                            .binary()
 3678                            .arguments
 3679                            .iter()
 3680                            .map(|arg| arg.to_string_lossy().into_owned())
 3681                            .collect(),
 3682                    }),
 3683                    configuration: serde_json::to_string(server.configuration()).ok(),
 3684                    workspace_folders: server
 3685                        .workspace_folders()
 3686                        .iter()
 3687                        .map(|uri| uri.to_string())
 3688                        .collect(),
 3689                },
 3690            ),
 3691        });
 3692    }
 3693}
 3694
 3695#[derive(Debug)]
 3696pub struct FormattableBuffer {
 3697    handle: Entity<Buffer>,
 3698    abs_path: Option<PathBuf>,
 3699    env: Option<HashMap<String, String>>,
 3700    ranges: Option<Vec<Range<Anchor>>>,
 3701}
 3702
 3703pub struct RemoteLspStore {
 3704    upstream_client: Option<AnyProtoClient>,
 3705    upstream_project_id: u64,
 3706}
 3707
 3708pub(crate) enum LspStoreMode {
 3709    Local(LocalLspStore),   // ssh host and collab host
 3710    Remote(RemoteLspStore), // collab guest
 3711}
 3712
 3713impl LspStoreMode {
 3714    fn is_local(&self) -> bool {
 3715        matches!(self, LspStoreMode::Local(_))
 3716    }
 3717}
 3718
 3719pub struct LspStore {
 3720    mode: LspStoreMode,
 3721    last_formatting_failure: Option<String>,
 3722    downstream_client: Option<(AnyProtoClient, u64)>,
 3723    nonce: u128,
 3724    buffer_store: Entity<BufferStore>,
 3725    worktree_store: Entity<WorktreeStore>,
 3726    pub languages: Arc<LanguageRegistry>,
 3727    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3728    active_entry: Option<ProjectEntryId>,
 3729    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3730    _maintain_buffer_languages: Task<()>,
 3731    diagnostic_summaries:
 3732        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3733    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3734    lsp_data: HashMap<BufferId, BufferLspData>,
 3735    next_hint_id: Arc<AtomicUsize>,
 3736}
 3737
 3738#[derive(Debug)]
 3739pub struct BufferLspData {
 3740    buffer_version: Global,
 3741    document_colors: Option<DocumentColorData>,
 3742    code_lens: Option<CodeLensData>,
 3743    inlay_hints: BufferInlayHints,
 3744    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3745    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3746}
 3747
 3748#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3749struct LspKey {
 3750    request_type: TypeId,
 3751    server_queried: Option<LanguageServerId>,
 3752}
 3753
 3754impl BufferLspData {
 3755    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3756        Self {
 3757            buffer_version: buffer.read(cx).version(),
 3758            document_colors: None,
 3759            code_lens: None,
 3760            inlay_hints: BufferInlayHints::new(buffer, cx),
 3761            lsp_requests: HashMap::default(),
 3762            chunk_lsp_requests: HashMap::default(),
 3763        }
 3764    }
 3765
 3766    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3767        if let Some(document_colors) = &mut self.document_colors {
 3768            document_colors.colors.remove(&for_server);
 3769            document_colors.cache_version += 1;
 3770        }
 3771
 3772        if let Some(code_lens) = &mut self.code_lens {
 3773            code_lens.lens.remove(&for_server);
 3774        }
 3775
 3776        self.inlay_hints.remove_server_data(for_server);
 3777    }
 3778
 3779    #[cfg(any(test, feature = "test-support"))]
 3780    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3781        &self.inlay_hints
 3782    }
 3783}
 3784
 3785#[derive(Debug, Default, Clone)]
 3786pub struct DocumentColors {
 3787    pub colors: HashSet<DocumentColor>,
 3788    pub cache_version: Option<usize>,
 3789}
 3790
 3791type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3792type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3793
 3794#[derive(Debug, Default)]
 3795struct DocumentColorData {
 3796    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3797    cache_version: usize,
 3798    colors_update: Option<(Global, DocumentColorTask)>,
 3799}
 3800
 3801#[derive(Debug, Default)]
 3802struct CodeLensData {
 3803    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3804    update: Option<(Global, CodeLensTask)>,
 3805}
 3806
 3807#[derive(Debug)]
 3808pub enum LspStoreEvent {
 3809    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3810    LanguageServerRemoved(LanguageServerId),
 3811    LanguageServerUpdate {
 3812        language_server_id: LanguageServerId,
 3813        name: Option<LanguageServerName>,
 3814        message: proto::update_language_server::Variant,
 3815    },
 3816    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3817    LanguageServerPrompt(LanguageServerPromptRequest),
 3818    LanguageDetected {
 3819        buffer: Entity<Buffer>,
 3820        new_language: Option<Arc<Language>>,
 3821    },
 3822    Notification(String),
 3823    RefreshInlayHints {
 3824        server_id: LanguageServerId,
 3825        request_id: Option<usize>,
 3826    },
 3827    RefreshCodeLens,
 3828    DiagnosticsUpdated {
 3829        server_id: LanguageServerId,
 3830        paths: Vec<ProjectPath>,
 3831    },
 3832    DiskBasedDiagnosticsStarted {
 3833        language_server_id: LanguageServerId,
 3834    },
 3835    DiskBasedDiagnosticsFinished {
 3836        language_server_id: LanguageServerId,
 3837    },
 3838    SnippetEdit {
 3839        buffer_id: BufferId,
 3840        edits: Vec<(lsp::Range, Snippet)>,
 3841        most_recent_edit: clock::Lamport,
 3842    },
 3843}
 3844
 3845#[derive(Clone, Debug, Serialize)]
 3846pub struct LanguageServerStatus {
 3847    pub name: LanguageServerName,
 3848    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3849    pub has_pending_diagnostic_updates: bool,
 3850    pub progress_tokens: HashSet<ProgressToken>,
 3851    pub worktree: Option<WorktreeId>,
 3852    pub binary: Option<LanguageServerBinary>,
 3853    pub configuration: Option<Value>,
 3854    pub workspace_folders: BTreeSet<Uri>,
 3855}
 3856
 3857#[derive(Clone, Debug)]
 3858struct CoreSymbol {
 3859    pub language_server_name: LanguageServerName,
 3860    pub source_worktree_id: WorktreeId,
 3861    pub source_language_server_id: LanguageServerId,
 3862    pub path: SymbolLocation,
 3863    pub name: String,
 3864    pub kind: lsp::SymbolKind,
 3865    pub range: Range<Unclipped<PointUtf16>>,
 3866}
 3867
 3868#[derive(Clone, Debug, PartialEq, Eq)]
 3869pub enum SymbolLocation {
 3870    InProject(ProjectPath),
 3871    OutsideProject {
 3872        abs_path: Arc<Path>,
 3873        signature: [u8; 32],
 3874    },
 3875}
 3876
 3877impl SymbolLocation {
 3878    fn file_name(&self) -> Option<&str> {
 3879        match self {
 3880            Self::InProject(path) => path.path.file_name(),
 3881            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3882        }
 3883    }
 3884}
 3885
 3886impl LspStore {
 3887    pub fn init(client: &AnyProtoClient) {
 3888        client.add_entity_request_handler(Self::handle_lsp_query);
 3889        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3890        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3891        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3892        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3893        client.add_entity_message_handler(Self::handle_start_language_server);
 3894        client.add_entity_message_handler(Self::handle_update_language_server);
 3895        client.add_entity_message_handler(Self::handle_language_server_log);
 3896        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3897        client.add_entity_request_handler(Self::handle_format_buffers);
 3898        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3899        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3900        client.add_entity_request_handler(Self::handle_apply_code_action);
 3901        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3902        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3903        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3904        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3905        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3906        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3907        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3908        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3909        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3910        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3911        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3912        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3913        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3914        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3915        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3916        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3917        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3918
 3919        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3920        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3921        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3922        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3923        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3924        client.add_entity_request_handler(
 3925            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3926        );
 3927        client.add_entity_request_handler(
 3928            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3929        );
 3930        client.add_entity_request_handler(
 3931            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3932        );
 3933    }
 3934
 3935    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3936        match &self.mode {
 3937            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3938            _ => None,
 3939        }
 3940    }
 3941
 3942    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3943        match &self.mode {
 3944            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3945            _ => None,
 3946        }
 3947    }
 3948
 3949    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3950        match &mut self.mode {
 3951            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3952            _ => None,
 3953        }
 3954    }
 3955
 3956    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3957        match &self.mode {
 3958            LspStoreMode::Remote(RemoteLspStore {
 3959                upstream_client: Some(upstream_client),
 3960                upstream_project_id,
 3961                ..
 3962            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3963
 3964            LspStoreMode::Remote(RemoteLspStore {
 3965                upstream_client: None,
 3966                ..
 3967            }) => None,
 3968            LspStoreMode::Local(_) => None,
 3969        }
 3970    }
 3971
 3972    pub fn new_local(
 3973        buffer_store: Entity<BufferStore>,
 3974        worktree_store: Entity<WorktreeStore>,
 3975        prettier_store: Entity<PrettierStore>,
 3976        toolchain_store: Entity<LocalToolchainStore>,
 3977        environment: Entity<ProjectEnvironment>,
 3978        manifest_tree: Entity<ManifestTree>,
 3979        languages: Arc<LanguageRegistry>,
 3980        http_client: Arc<dyn HttpClient>,
 3981        fs: Arc<dyn Fs>,
 3982        cx: &mut Context<Self>,
 3983    ) -> Self {
 3984        let yarn = YarnPathStore::new(fs.clone(), cx);
 3985        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3986            .detach();
 3987        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3988            .detach();
 3989        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3990            .detach();
 3991        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3992            .detach();
 3993        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3994            .detach();
 3995        subscribe_to_binary_statuses(&languages, cx).detach();
 3996
 3997        let _maintain_workspace_config = {
 3998            let (sender, receiver) = watch::channel();
 3999            (Self::maintain_workspace_config(receiver, cx), sender)
 4000        };
 4001
 4002        Self {
 4003            mode: LspStoreMode::Local(LocalLspStore {
 4004                weak: cx.weak_entity(),
 4005                worktree_store: worktree_store.clone(),
 4006
 4007                supplementary_language_servers: Default::default(),
 4008                languages: languages.clone(),
 4009                language_server_ids: Default::default(),
 4010                language_servers: Default::default(),
 4011                last_workspace_edits_by_language_server: Default::default(),
 4012                language_server_watched_paths: Default::default(),
 4013                language_server_paths_watched_for_rename: Default::default(),
 4014                language_server_dynamic_registrations: Default::default(),
 4015                buffers_being_formatted: Default::default(),
 4016                buffer_snapshots: Default::default(),
 4017                prettier_store,
 4018                environment,
 4019                http_client,
 4020                fs,
 4021                yarn,
 4022                next_diagnostic_group_id: Default::default(),
 4023                diagnostics: Default::default(),
 4024                _subscription: cx.on_app_quit(|this, cx| {
 4025                    this.as_local_mut()
 4026                        .unwrap()
 4027                        .shutdown_language_servers_on_quit(cx)
 4028                }),
 4029                lsp_tree: LanguageServerTree::new(
 4030                    manifest_tree,
 4031                    languages.clone(),
 4032                    toolchain_store.clone(),
 4033                ),
 4034                toolchain_store,
 4035                registered_buffers: HashMap::default(),
 4036                buffers_opened_in_servers: HashMap::default(),
 4037                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4038                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4039                restricted_worktrees_tasks: HashMap::default(),
 4040                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4041                    .manifest_file_names(),
 4042            }),
 4043            last_formatting_failure: None,
 4044            downstream_client: None,
 4045            buffer_store,
 4046            worktree_store,
 4047            languages: languages.clone(),
 4048            language_server_statuses: Default::default(),
 4049            nonce: StdRng::from_os_rng().random(),
 4050            diagnostic_summaries: HashMap::default(),
 4051            lsp_server_capabilities: HashMap::default(),
 4052            lsp_data: HashMap::default(),
 4053            next_hint_id: Arc::default(),
 4054            active_entry: None,
 4055            _maintain_workspace_config,
 4056            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4057        }
 4058    }
 4059
 4060    fn send_lsp_proto_request<R: LspCommand>(
 4061        &self,
 4062        buffer: Entity<Buffer>,
 4063        client: AnyProtoClient,
 4064        upstream_project_id: u64,
 4065        request: R,
 4066        cx: &mut Context<LspStore>,
 4067    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4068        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4069            return Task::ready(Ok(R::Response::default()));
 4070        }
 4071        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4072        cx.spawn(async move |this, cx| {
 4073            let response = client.request(message).await?;
 4074            let this = this.upgrade().context("project dropped")?;
 4075            request
 4076                .response_from_proto(response, this, buffer, cx.clone())
 4077                .await
 4078        })
 4079    }
 4080
 4081    pub(super) fn new_remote(
 4082        buffer_store: Entity<BufferStore>,
 4083        worktree_store: Entity<WorktreeStore>,
 4084        languages: Arc<LanguageRegistry>,
 4085        upstream_client: AnyProtoClient,
 4086        project_id: u64,
 4087        cx: &mut Context<Self>,
 4088    ) -> Self {
 4089        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4090            .detach();
 4091        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4092            .detach();
 4093        subscribe_to_binary_statuses(&languages, cx).detach();
 4094        let _maintain_workspace_config = {
 4095            let (sender, receiver) = watch::channel();
 4096            (Self::maintain_workspace_config(receiver, cx), sender)
 4097        };
 4098        Self {
 4099            mode: LspStoreMode::Remote(RemoteLspStore {
 4100                upstream_client: Some(upstream_client),
 4101                upstream_project_id: project_id,
 4102            }),
 4103            downstream_client: None,
 4104            last_formatting_failure: None,
 4105            buffer_store,
 4106            worktree_store,
 4107            languages: languages.clone(),
 4108            language_server_statuses: Default::default(),
 4109            nonce: StdRng::from_os_rng().random(),
 4110            diagnostic_summaries: HashMap::default(),
 4111            lsp_server_capabilities: HashMap::default(),
 4112            next_hint_id: Arc::default(),
 4113            lsp_data: HashMap::default(),
 4114            active_entry: None,
 4115
 4116            _maintain_workspace_config,
 4117            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4118        }
 4119    }
 4120
 4121    fn on_buffer_store_event(
 4122        &mut self,
 4123        _: Entity<BufferStore>,
 4124        event: &BufferStoreEvent,
 4125        cx: &mut Context<Self>,
 4126    ) {
 4127        match event {
 4128            BufferStoreEvent::BufferAdded(buffer) => {
 4129                self.on_buffer_added(buffer, cx).log_err();
 4130            }
 4131            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4132                let buffer_id = buffer.read(cx).remote_id();
 4133                if let Some(local) = self.as_local_mut()
 4134                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4135                {
 4136                    local.reset_buffer(buffer, old_file, cx);
 4137
 4138                    if local.registered_buffers.contains_key(&buffer_id) {
 4139                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4140                    }
 4141                }
 4142
 4143                self.detect_language_for_buffer(buffer, cx);
 4144                if let Some(local) = self.as_local_mut() {
 4145                    local.initialize_buffer(buffer, cx);
 4146                    if local.registered_buffers.contains_key(&buffer_id) {
 4147                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4148                    }
 4149                }
 4150            }
 4151            _ => {}
 4152        }
 4153    }
 4154
 4155    fn on_worktree_store_event(
 4156        &mut self,
 4157        _: Entity<WorktreeStore>,
 4158        event: &WorktreeStoreEvent,
 4159        cx: &mut Context<Self>,
 4160    ) {
 4161        match event {
 4162            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4163                if !worktree.read(cx).is_local() {
 4164                    return;
 4165                }
 4166                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4167                    worktree::Event::UpdatedEntries(changes) => {
 4168                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4169                    }
 4170                    worktree::Event::UpdatedGitRepositories(_)
 4171                    | worktree::Event::DeletedEntry(_) => {}
 4172                })
 4173                .detach()
 4174            }
 4175            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4176            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4177                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4178            }
 4179            WorktreeStoreEvent::WorktreeReleased(..)
 4180            | WorktreeStoreEvent::WorktreeOrderChanged
 4181            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4182            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4183            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4184        }
 4185    }
 4186
 4187    fn on_prettier_store_event(
 4188        &mut self,
 4189        _: Entity<PrettierStore>,
 4190        event: &PrettierStoreEvent,
 4191        cx: &mut Context<Self>,
 4192    ) {
 4193        match event {
 4194            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4195                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4196            }
 4197            PrettierStoreEvent::LanguageServerAdded {
 4198                new_server_id,
 4199                name,
 4200                prettier_server,
 4201            } => {
 4202                self.register_supplementary_language_server(
 4203                    *new_server_id,
 4204                    name.clone(),
 4205                    prettier_server.clone(),
 4206                    cx,
 4207                );
 4208            }
 4209        }
 4210    }
 4211
 4212    fn on_toolchain_store_event(
 4213        &mut self,
 4214        _: Entity<LocalToolchainStore>,
 4215        event: &ToolchainStoreEvent,
 4216        _: &mut Context<Self>,
 4217    ) {
 4218        if let ToolchainStoreEvent::ToolchainActivated = event {
 4219            self.request_workspace_config_refresh()
 4220        }
 4221    }
 4222
 4223    fn request_workspace_config_refresh(&mut self) {
 4224        *self._maintain_workspace_config.1.borrow_mut() = ();
 4225    }
 4226
 4227    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4228        self.as_local().map(|local| local.prettier_store.clone())
 4229    }
 4230
 4231    fn on_buffer_event(
 4232        &mut self,
 4233        buffer: Entity<Buffer>,
 4234        event: &language::BufferEvent,
 4235        cx: &mut Context<Self>,
 4236    ) {
 4237        match event {
 4238            language::BufferEvent::Edited => {
 4239                self.on_buffer_edited(buffer, cx);
 4240            }
 4241
 4242            language::BufferEvent::Saved => {
 4243                self.on_buffer_saved(buffer, cx);
 4244            }
 4245
 4246            _ => {}
 4247        }
 4248    }
 4249
 4250    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4251        buffer
 4252            .read(cx)
 4253            .set_language_registry(self.languages.clone());
 4254
 4255        cx.subscribe(buffer, |this, buffer, event, cx| {
 4256            this.on_buffer_event(buffer, event, cx);
 4257        })
 4258        .detach();
 4259
 4260        self.detect_language_for_buffer(buffer, cx);
 4261        if let Some(local) = self.as_local_mut() {
 4262            local.initialize_buffer(buffer, cx);
 4263        }
 4264
 4265        Ok(())
 4266    }
 4267
 4268    pub(crate) fn register_buffer_with_language_servers(
 4269        &mut self,
 4270        buffer: &Entity<Buffer>,
 4271        only_register_servers: HashSet<LanguageServerSelector>,
 4272        ignore_refcounts: bool,
 4273        cx: &mut Context<Self>,
 4274    ) -> OpenLspBufferHandle {
 4275        let buffer_id = buffer.read(cx).remote_id();
 4276        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4277        if let Some(local) = self.as_local_mut() {
 4278            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4279            if !ignore_refcounts {
 4280                *refcount += 1;
 4281            }
 4282
 4283            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4284            // 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
 4285            // 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
 4286            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4287            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4288                return handle;
 4289            };
 4290            if !file.is_local() {
 4291                return handle;
 4292            }
 4293
 4294            if ignore_refcounts || *refcount == 1 {
 4295                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4296            }
 4297            if !ignore_refcounts {
 4298                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4299                    let refcount = {
 4300                        let local = lsp_store.as_local_mut().unwrap();
 4301                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4302                            debug_panic!("bad refcounting");
 4303                            return;
 4304                        };
 4305
 4306                        *refcount -= 1;
 4307                        *refcount
 4308                    };
 4309                    if refcount == 0 {
 4310                        lsp_store.lsp_data.remove(&buffer_id);
 4311                        let local = lsp_store.as_local_mut().unwrap();
 4312                        local.registered_buffers.remove(&buffer_id);
 4313
 4314                        local.buffers_opened_in_servers.remove(&buffer_id);
 4315                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4316                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4317
 4318                            let buffer_abs_path = file.abs_path(cx);
 4319                            for (_, buffer_pull_diagnostics_result_ids) in
 4320                                &mut local.buffer_pull_diagnostics_result_ids
 4321                            {
 4322                                buffer_pull_diagnostics_result_ids.retain(
 4323                                    |_, buffer_result_ids| {
 4324                                        buffer_result_ids.remove(&buffer_abs_path);
 4325                                        !buffer_result_ids.is_empty()
 4326                                    },
 4327                                );
 4328                            }
 4329
 4330                            let diagnostic_updates = local
 4331                                .language_servers
 4332                                .keys()
 4333                                .cloned()
 4334                                .map(|server_id| DocumentDiagnosticsUpdate {
 4335                                    diagnostics: DocumentDiagnostics {
 4336                                        document_abs_path: buffer_abs_path.clone(),
 4337                                        version: None,
 4338                                        diagnostics: Vec::new(),
 4339                                    },
 4340                                    result_id: None,
 4341                                    registration_id: None,
 4342                                    server_id: server_id,
 4343                                    disk_based_sources: Cow::Borrowed(&[]),
 4344                                })
 4345                                .collect::<Vec<_>>();
 4346
 4347                            lsp_store
 4348                                .merge_diagnostic_entries(
 4349                                    diagnostic_updates,
 4350                                    |_, diagnostic, _| {
 4351                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4352                                    },
 4353                                    cx,
 4354                                )
 4355                                .context("Clearing diagnostics for the closed buffer")
 4356                                .log_err();
 4357                        }
 4358                    }
 4359                })
 4360                .detach();
 4361            }
 4362        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4363            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4364            cx.background_spawn(async move {
 4365                upstream_client
 4366                    .request(proto::RegisterBufferWithLanguageServers {
 4367                        project_id: upstream_project_id,
 4368                        buffer_id,
 4369                        only_servers: only_register_servers
 4370                            .into_iter()
 4371                            .map(|selector| {
 4372                                let selector = match selector {
 4373                                    LanguageServerSelector::Id(language_server_id) => {
 4374                                        proto::language_server_selector::Selector::ServerId(
 4375                                            language_server_id.to_proto(),
 4376                                        )
 4377                                    }
 4378                                    LanguageServerSelector::Name(language_server_name) => {
 4379                                        proto::language_server_selector::Selector::Name(
 4380                                            language_server_name.to_string(),
 4381                                        )
 4382                                    }
 4383                                };
 4384                                proto::LanguageServerSelector {
 4385                                    selector: Some(selector),
 4386                                }
 4387                            })
 4388                            .collect(),
 4389                    })
 4390                    .await
 4391            })
 4392            .detach();
 4393        } else {
 4394            // Our remote connection got closed
 4395        }
 4396        handle
 4397    }
 4398
 4399    fn maintain_buffer_languages(
 4400        languages: Arc<LanguageRegistry>,
 4401        cx: &mut Context<Self>,
 4402    ) -> Task<()> {
 4403        let mut subscription = languages.subscribe();
 4404        let mut prev_reload_count = languages.reload_count();
 4405        cx.spawn(async move |this, cx| {
 4406            while let Some(()) = subscription.next().await {
 4407                if let Some(this) = this.upgrade() {
 4408                    // If the language registry has been reloaded, then remove and
 4409                    // re-assign the languages on all open buffers.
 4410                    let reload_count = languages.reload_count();
 4411                    if reload_count > prev_reload_count {
 4412                        prev_reload_count = reload_count;
 4413                        this.update(cx, |this, cx| {
 4414                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4415                                for buffer in buffer_store.buffers() {
 4416                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4417                                    {
 4418                                        buffer.update(cx, |buffer, cx| {
 4419                                            buffer.set_language_async(None, cx)
 4420                                        });
 4421                                        if let Some(local) = this.as_local_mut() {
 4422                                            local.reset_buffer(&buffer, &f, cx);
 4423
 4424                                            if local
 4425                                                .registered_buffers
 4426                                                .contains_key(&buffer.read(cx).remote_id())
 4427                                                && let Some(file_url) =
 4428                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4429                                            {
 4430                                                local.unregister_buffer_from_language_servers(
 4431                                                    &buffer, &file_url, cx,
 4432                                                );
 4433                                            }
 4434                                        }
 4435                                    }
 4436                                }
 4437                            });
 4438                        })
 4439                        .ok();
 4440                    }
 4441
 4442                    this.update(cx, |this, cx| {
 4443                        let mut plain_text_buffers = Vec::new();
 4444                        let mut buffers_with_unknown_injections = Vec::new();
 4445                        for handle in this.buffer_store.read(cx).buffers() {
 4446                            let buffer = handle.read(cx);
 4447                            if buffer.language().is_none()
 4448                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4449                            {
 4450                                plain_text_buffers.push(handle);
 4451                            } else if buffer.contains_unknown_injections() {
 4452                                buffers_with_unknown_injections.push(handle);
 4453                            }
 4454                        }
 4455
 4456                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4457                        // and reused later in the invisible worktrees.
 4458                        plain_text_buffers.sort_by_key(|buffer| {
 4459                            Reverse(
 4460                                File::from_dyn(buffer.read(cx).file())
 4461                                    .map(|file| file.worktree.read(cx).is_visible()),
 4462                            )
 4463                        });
 4464
 4465                        for buffer in plain_text_buffers {
 4466                            this.detect_language_for_buffer(&buffer, cx);
 4467                            if let Some(local) = this.as_local_mut() {
 4468                                local.initialize_buffer(&buffer, cx);
 4469                                if local
 4470                                    .registered_buffers
 4471                                    .contains_key(&buffer.read(cx).remote_id())
 4472                                {
 4473                                    local.register_buffer_with_language_servers(
 4474                                        &buffer,
 4475                                        HashSet::default(),
 4476                                        cx,
 4477                                    );
 4478                                }
 4479                            }
 4480                        }
 4481
 4482                        for buffer in buffers_with_unknown_injections {
 4483                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4484                        }
 4485                    })
 4486                    .ok();
 4487                }
 4488            }
 4489        })
 4490    }
 4491
 4492    fn detect_language_for_buffer(
 4493        &mut self,
 4494        buffer_handle: &Entity<Buffer>,
 4495        cx: &mut Context<Self>,
 4496    ) -> Option<language::AvailableLanguage> {
 4497        // If the buffer has a language, set it and start the language server if we haven't already.
 4498        let buffer = buffer_handle.read(cx);
 4499        let file = buffer.file()?;
 4500
 4501        let content = buffer.as_rope();
 4502        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4503        if let Some(available_language) = &available_language {
 4504            if let Some(Ok(Ok(new_language))) = self
 4505                .languages
 4506                .load_language(available_language)
 4507                .now_or_never()
 4508            {
 4509                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4510            }
 4511        } else {
 4512            cx.emit(LspStoreEvent::LanguageDetected {
 4513                buffer: buffer_handle.clone(),
 4514                new_language: None,
 4515            });
 4516        }
 4517
 4518        available_language
 4519    }
 4520
 4521    pub(crate) fn set_language_for_buffer(
 4522        &mut self,
 4523        buffer_entity: &Entity<Buffer>,
 4524        new_language: Arc<Language>,
 4525        cx: &mut Context<Self>,
 4526    ) {
 4527        let buffer = buffer_entity.read(cx);
 4528        let buffer_file = buffer.file().cloned();
 4529        let buffer_id = buffer.remote_id();
 4530        if let Some(local_store) = self.as_local_mut()
 4531            && local_store.registered_buffers.contains_key(&buffer_id)
 4532            && let Some(abs_path) =
 4533                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4534            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4535        {
 4536            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4537        }
 4538        buffer_entity.update(cx, |buffer, cx| {
 4539            if buffer
 4540                .language()
 4541                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4542            {
 4543                buffer.set_language_async(Some(new_language.clone()), cx);
 4544            }
 4545        });
 4546
 4547        let settings =
 4548            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4549        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4550
 4551        let worktree_id = if let Some(file) = buffer_file {
 4552            let worktree = file.worktree.clone();
 4553
 4554            if let Some(local) = self.as_local_mut()
 4555                && local.registered_buffers.contains_key(&buffer_id)
 4556            {
 4557                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4558            }
 4559            Some(worktree.read(cx).id())
 4560        } else {
 4561            None
 4562        };
 4563
 4564        if settings.prettier.allowed
 4565            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4566        {
 4567            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4568            if let Some(prettier_store) = prettier_store {
 4569                prettier_store.update(cx, |prettier_store, cx| {
 4570                    prettier_store.install_default_prettier(
 4571                        worktree_id,
 4572                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4573                        cx,
 4574                    )
 4575                })
 4576            }
 4577        }
 4578
 4579        cx.emit(LspStoreEvent::LanguageDetected {
 4580            buffer: buffer_entity.clone(),
 4581            new_language: Some(new_language),
 4582        })
 4583    }
 4584
 4585    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4586        self.buffer_store.clone()
 4587    }
 4588
 4589    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4590        self.active_entry = active_entry;
 4591    }
 4592
 4593    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4594        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4595            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4596        {
 4597            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4598                summaries
 4599                    .iter()
 4600                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4601            });
 4602            if let Some(summary) = summaries.next() {
 4603                client
 4604                    .send(proto::UpdateDiagnosticSummary {
 4605                        project_id: downstream_project_id,
 4606                        worktree_id: worktree.id().to_proto(),
 4607                        summary: Some(summary),
 4608                        more_summaries: summaries.collect(),
 4609                    })
 4610                    .log_err();
 4611            }
 4612        }
 4613    }
 4614
 4615    fn is_capable_for_proto_request<R>(
 4616        &self,
 4617        buffer: &Entity<Buffer>,
 4618        request: &R,
 4619        cx: &App,
 4620    ) -> bool
 4621    where
 4622        R: LspCommand,
 4623    {
 4624        self.check_if_capable_for_proto_request(
 4625            buffer,
 4626            |capabilities| {
 4627                request.check_capabilities(AdapterServerCapabilities {
 4628                    server_capabilities: capabilities.clone(),
 4629                    code_action_kinds: None,
 4630                })
 4631            },
 4632            cx,
 4633        )
 4634    }
 4635
 4636    fn check_if_capable_for_proto_request<F>(
 4637        &self,
 4638        buffer: &Entity<Buffer>,
 4639        check: F,
 4640        cx: &App,
 4641    ) -> bool
 4642    where
 4643        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4644    {
 4645        let Some(language) = buffer.read(cx).language().cloned() else {
 4646            return false;
 4647        };
 4648        let relevant_language_servers = self
 4649            .languages
 4650            .lsp_adapters(&language.name())
 4651            .into_iter()
 4652            .map(|lsp_adapter| lsp_adapter.name())
 4653            .collect::<HashSet<_>>();
 4654        self.language_server_statuses
 4655            .iter()
 4656            .filter_map(|(server_id, server_status)| {
 4657                relevant_language_servers
 4658                    .contains(&server_status.name)
 4659                    .then_some(server_id)
 4660            })
 4661            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4662            .any(check)
 4663    }
 4664
 4665    fn all_capable_for_proto_request<F>(
 4666        &self,
 4667        buffer: &Entity<Buffer>,
 4668        mut check: F,
 4669        cx: &App,
 4670    ) -> Vec<lsp::LanguageServerId>
 4671    where
 4672        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4673    {
 4674        let Some(language) = buffer.read(cx).language().cloned() else {
 4675            return Vec::default();
 4676        };
 4677        let relevant_language_servers = self
 4678            .languages
 4679            .lsp_adapters(&language.name())
 4680            .into_iter()
 4681            .map(|lsp_adapter| lsp_adapter.name())
 4682            .collect::<HashSet<_>>();
 4683        self.language_server_statuses
 4684            .iter()
 4685            .filter_map(|(server_id, server_status)| {
 4686                relevant_language_servers
 4687                    .contains(&server_status.name)
 4688                    .then_some((server_id, &server_status.name))
 4689            })
 4690            .filter_map(|(server_id, server_name)| {
 4691                self.lsp_server_capabilities
 4692                    .get(server_id)
 4693                    .map(|c| (server_id, server_name, c))
 4694            })
 4695            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4696            .map(|(server_id, _, _)| *server_id)
 4697            .collect()
 4698    }
 4699
 4700    pub fn request_lsp<R>(
 4701        &mut self,
 4702        buffer: Entity<Buffer>,
 4703        server: LanguageServerToQuery,
 4704        request: R,
 4705        cx: &mut Context<Self>,
 4706    ) -> Task<Result<R::Response>>
 4707    where
 4708        R: LspCommand,
 4709        <R::LspRequest as lsp::request::Request>::Result: Send,
 4710        <R::LspRequest as lsp::request::Request>::Params: Send,
 4711    {
 4712        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4713            return self.send_lsp_proto_request(
 4714                buffer,
 4715                upstream_client,
 4716                upstream_project_id,
 4717                request,
 4718                cx,
 4719            );
 4720        }
 4721
 4722        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4723            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4724                local
 4725                    .language_servers_for_buffer(buffer, cx)
 4726                    .find(|(_, server)| {
 4727                        request.check_capabilities(server.adapter_server_capabilities())
 4728                    })
 4729                    .map(|(_, server)| server.clone())
 4730            }),
 4731            LanguageServerToQuery::Other(id) => self
 4732                .language_server_for_local_buffer(buffer, id, cx)
 4733                .and_then(|(_, server)| {
 4734                    request
 4735                        .check_capabilities(server.adapter_server_capabilities())
 4736                        .then(|| Arc::clone(server))
 4737                }),
 4738        }) else {
 4739            return Task::ready(Ok(Default::default()));
 4740        };
 4741
 4742        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4743
 4744        let Some(file) = file else {
 4745            return Task::ready(Ok(Default::default()));
 4746        };
 4747
 4748        let lsp_params = match request.to_lsp_params_or_response(
 4749            &file.abs_path(cx),
 4750            buffer.read(cx),
 4751            &language_server,
 4752            cx,
 4753        ) {
 4754            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4755            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4756            Err(err) => {
 4757                let message = format!(
 4758                    "{} via {} failed: {}",
 4759                    request.display_name(),
 4760                    language_server.name(),
 4761                    err
 4762                );
 4763                // rust-analyzer likes to error with this when its still loading up
 4764                if !message.ends_with("content modified") {
 4765                    log::warn!("{message}");
 4766                }
 4767                return Task::ready(Err(anyhow!(message)));
 4768            }
 4769        };
 4770
 4771        let status = request.status();
 4772        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4773            return Task::ready(Ok(Default::default()));
 4774        }
 4775        cx.spawn(async move |this, cx| {
 4776            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4777
 4778            let id = lsp_request.id();
 4779            let _cleanup = if status.is_some() {
 4780                cx.update(|cx| {
 4781                    this.update(cx, |this, cx| {
 4782                        this.on_lsp_work_start(
 4783                            language_server.server_id(),
 4784                            ProgressToken::Number(id),
 4785                            LanguageServerProgress {
 4786                                is_disk_based_diagnostics_progress: false,
 4787                                is_cancellable: false,
 4788                                title: None,
 4789                                message: status.clone(),
 4790                                percentage: None,
 4791                                last_update_at: cx.background_executor().now(),
 4792                            },
 4793                            cx,
 4794                        );
 4795                    })
 4796                })
 4797                .log_err();
 4798
 4799                Some(defer(|| {
 4800                    cx.update(|cx| {
 4801                        this.update(cx, |this, cx| {
 4802                            this.on_lsp_work_end(
 4803                                language_server.server_id(),
 4804                                ProgressToken::Number(id),
 4805                                cx,
 4806                            );
 4807                        })
 4808                    })
 4809                    .log_err();
 4810                }))
 4811            } else {
 4812                None
 4813            };
 4814
 4815            let result = lsp_request.await.into_response();
 4816
 4817            let response = result.map_err(|err| {
 4818                let message = format!(
 4819                    "{} via {} failed: {}",
 4820                    request.display_name(),
 4821                    language_server.name(),
 4822                    err
 4823                );
 4824                // rust-analyzer likes to error with this when its still loading up
 4825                if !message.ends_with("content modified") {
 4826                    log::warn!("{message}");
 4827                }
 4828                anyhow::anyhow!(message)
 4829            })?;
 4830
 4831            request
 4832                .response_from_lsp(
 4833                    response,
 4834                    this.upgrade().context("no app context")?,
 4835                    buffer,
 4836                    language_server.server_id(),
 4837                    cx.clone(),
 4838                )
 4839                .await
 4840        })
 4841    }
 4842
 4843    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4844        let mut language_formatters_to_check = Vec::new();
 4845        for buffer in self.buffer_store.read(cx).buffers() {
 4846            let buffer = buffer.read(cx);
 4847            let buffer_file = File::from_dyn(buffer.file());
 4848            let buffer_language = buffer.language();
 4849            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4850            if buffer_language.is_some() {
 4851                language_formatters_to_check.push((
 4852                    buffer_file.map(|f| f.worktree_id(cx)),
 4853                    settings.into_owned(),
 4854                ));
 4855            }
 4856        }
 4857
 4858        self.request_workspace_config_refresh();
 4859
 4860        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4861            prettier_store.update(cx, |prettier_store, cx| {
 4862                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4863            })
 4864        }
 4865
 4866        cx.notify();
 4867    }
 4868
 4869    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4870        let buffer_store = self.buffer_store.clone();
 4871        let Some(local) = self.as_local_mut() else {
 4872            return;
 4873        };
 4874        let mut adapters = BTreeMap::default();
 4875        let get_adapter = {
 4876            let languages = local.languages.clone();
 4877            let environment = local.environment.clone();
 4878            let weak = local.weak.clone();
 4879            let worktree_store = local.worktree_store.clone();
 4880            let http_client = local.http_client.clone();
 4881            let fs = local.fs.clone();
 4882            move |worktree_id, cx: &mut App| {
 4883                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4884                Some(LocalLspAdapterDelegate::new(
 4885                    languages.clone(),
 4886                    &environment,
 4887                    weak.clone(),
 4888                    &worktree,
 4889                    http_client.clone(),
 4890                    fs.clone(),
 4891                    cx,
 4892                ))
 4893            }
 4894        };
 4895
 4896        let mut messages_to_report = Vec::new();
 4897        let (new_tree, to_stop) = {
 4898            let mut rebase = local.lsp_tree.rebase();
 4899            let buffers = buffer_store
 4900                .read(cx)
 4901                .buffers()
 4902                .filter_map(|buffer| {
 4903                    let raw_buffer = buffer.read(cx);
 4904                    if !local
 4905                        .registered_buffers
 4906                        .contains_key(&raw_buffer.remote_id())
 4907                    {
 4908                        return None;
 4909                    }
 4910                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4911                    let language = raw_buffer.language().cloned()?;
 4912                    Some((file, language, raw_buffer.remote_id()))
 4913                })
 4914                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4915            for (file, language, buffer_id) in buffers {
 4916                let worktree_id = file.worktree_id(cx);
 4917                let Some(worktree) = local
 4918                    .worktree_store
 4919                    .read(cx)
 4920                    .worktree_for_id(worktree_id, cx)
 4921                else {
 4922                    continue;
 4923                };
 4924
 4925                if let Some((_, apply)) = local.reuse_existing_language_server(
 4926                    rebase.server_tree(),
 4927                    &worktree,
 4928                    &language.name(),
 4929                    cx,
 4930                ) {
 4931                    (apply)(rebase.server_tree());
 4932                } else if let Some(lsp_delegate) = adapters
 4933                    .entry(worktree_id)
 4934                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4935                    .clone()
 4936                {
 4937                    let delegate =
 4938                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4939                    let path = file
 4940                        .path()
 4941                        .parent()
 4942                        .map(Arc::from)
 4943                        .unwrap_or_else(|| file.path().clone());
 4944                    let worktree_path = ProjectPath { worktree_id, path };
 4945                    let abs_path = file.abs_path(cx);
 4946                    let nodes = rebase
 4947                        .walk(
 4948                            worktree_path,
 4949                            language.name(),
 4950                            language.manifest(),
 4951                            delegate.clone(),
 4952                            cx,
 4953                        )
 4954                        .collect::<Vec<_>>();
 4955                    for node in nodes {
 4956                        let server_id = node.server_id_or_init(|disposition| {
 4957                            let path = &disposition.path;
 4958                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4959                            let key = LanguageServerSeed {
 4960                                worktree_id,
 4961                                name: disposition.server_name.clone(),
 4962                                settings: disposition.settings.clone(),
 4963                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4964                                    path.worktree_id,
 4965                                    &path.path,
 4966                                    language.name(),
 4967                                ),
 4968                            };
 4969                            local.language_server_ids.remove(&key);
 4970
 4971                            let server_id = local.get_or_insert_language_server(
 4972                                &worktree,
 4973                                lsp_delegate.clone(),
 4974                                disposition,
 4975                                &language.name(),
 4976                                cx,
 4977                            );
 4978                            if let Some(state) = local.language_servers.get(&server_id)
 4979                                && let Ok(uri) = uri
 4980                            {
 4981                                state.add_workspace_folder(uri);
 4982                            };
 4983                            server_id
 4984                        });
 4985
 4986                        if let Some(language_server_id) = server_id {
 4987                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4988                                language_server_id,
 4989                                name: node.name(),
 4990                                message:
 4991                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4992                                        proto::RegisteredForBuffer {
 4993                                            buffer_abs_path: abs_path
 4994                                                .to_string_lossy()
 4995                                                .into_owned(),
 4996                                            buffer_id: buffer_id.to_proto(),
 4997                                        },
 4998                                    ),
 4999                            });
 5000                        }
 5001                    }
 5002                } else {
 5003                    continue;
 5004                }
 5005            }
 5006            rebase.finish()
 5007        };
 5008        for message in messages_to_report {
 5009            cx.emit(message);
 5010        }
 5011        local.lsp_tree = new_tree;
 5012        for (id, _) in to_stop {
 5013            self.stop_local_language_server(id, cx).detach();
 5014        }
 5015    }
 5016
 5017    pub fn apply_code_action(
 5018        &self,
 5019        buffer_handle: Entity<Buffer>,
 5020        mut action: CodeAction,
 5021        push_to_history: bool,
 5022        cx: &mut Context<Self>,
 5023    ) -> Task<Result<ProjectTransaction>> {
 5024        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5025            let request = proto::ApplyCodeAction {
 5026                project_id,
 5027                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5028                action: Some(Self::serialize_code_action(&action)),
 5029            };
 5030            let buffer_store = self.buffer_store();
 5031            cx.spawn(async move |_, cx| {
 5032                let response = upstream_client
 5033                    .request(request)
 5034                    .await?
 5035                    .transaction
 5036                    .context("missing transaction")?;
 5037
 5038                buffer_store
 5039                    .update(cx, |buffer_store, cx| {
 5040                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5041                    })?
 5042                    .await
 5043            })
 5044        } else if self.mode.is_local() {
 5045            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 5046                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5047                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 5048            }) else {
 5049                return Task::ready(Ok(ProjectTransaction::default()));
 5050            };
 5051            cx.spawn(async move |this,  cx| {
 5052                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 5053                    .await
 5054                    .context("resolving a code action")?;
 5055                if let Some(edit) = action.lsp_action.edit()
 5056                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5057                        return LocalLspStore::deserialize_workspace_edit(
 5058                            this.upgrade().context("no app present")?,
 5059                            edit.clone(),
 5060                            push_to_history,
 5061
 5062                            lang_server.clone(),
 5063                            cx,
 5064                        )
 5065                        .await;
 5066                    }
 5067
 5068                if let Some(command) = action.lsp_action.command() {
 5069                    let server_capabilities = lang_server.capabilities();
 5070                    let available_commands = server_capabilities
 5071                        .execute_command_provider
 5072                        .as_ref()
 5073                        .map(|options| options.commands.as_slice())
 5074                        .unwrap_or_default();
 5075                    if available_commands.contains(&command.command) {
 5076                        this.update(cx, |this, _| {
 5077                            this.as_local_mut()
 5078                                .unwrap()
 5079                                .last_workspace_edits_by_language_server
 5080                                .remove(&lang_server.server_id());
 5081                        })?;
 5082
 5083                        let _result = lang_server
 5084                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5085                                command: command.command.clone(),
 5086                                arguments: command.arguments.clone().unwrap_or_default(),
 5087                                ..lsp::ExecuteCommandParams::default()
 5088                            })
 5089                            .await.into_response()
 5090                            .context("execute command")?;
 5091
 5092                        return this.update(cx, |this, _| {
 5093                            this.as_local_mut()
 5094                                .unwrap()
 5095                                .last_workspace_edits_by_language_server
 5096                                .remove(&lang_server.server_id())
 5097                                .unwrap_or_default()
 5098                        });
 5099                    } else {
 5100                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5101                    }
 5102                }
 5103
 5104                Ok(ProjectTransaction::default())
 5105            })
 5106        } else {
 5107            Task::ready(Err(anyhow!("no upstream client and not local")))
 5108        }
 5109    }
 5110
 5111    pub fn apply_code_action_kind(
 5112        &mut self,
 5113        buffers: HashSet<Entity<Buffer>>,
 5114        kind: CodeActionKind,
 5115        push_to_history: bool,
 5116        cx: &mut Context<Self>,
 5117    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5118        if self.as_local().is_some() {
 5119            cx.spawn(async move |lsp_store, cx| {
 5120                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5121                let result = LocalLspStore::execute_code_action_kind_locally(
 5122                    lsp_store.clone(),
 5123                    buffers,
 5124                    kind,
 5125                    push_to_history,
 5126                    cx,
 5127                )
 5128                .await;
 5129                lsp_store.update(cx, |lsp_store, _| {
 5130                    lsp_store.update_last_formatting_failure(&result);
 5131                })?;
 5132                result
 5133            })
 5134        } else if let Some((client, project_id)) = self.upstream_client() {
 5135            let buffer_store = self.buffer_store();
 5136            cx.spawn(async move |lsp_store, cx| {
 5137                let result = client
 5138                    .request(proto::ApplyCodeActionKind {
 5139                        project_id,
 5140                        kind: kind.as_str().to_owned(),
 5141                        buffer_ids: buffers
 5142                            .iter()
 5143                            .map(|buffer| {
 5144                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5145                            })
 5146                            .collect::<Result<_>>()?,
 5147                    })
 5148                    .await
 5149                    .and_then(|result| result.transaction.context("missing transaction"));
 5150                lsp_store.update(cx, |lsp_store, _| {
 5151                    lsp_store.update_last_formatting_failure(&result);
 5152                })?;
 5153
 5154                let transaction_response = result?;
 5155                buffer_store
 5156                    .update(cx, |buffer_store, cx| {
 5157                        buffer_store.deserialize_project_transaction(
 5158                            transaction_response,
 5159                            push_to_history,
 5160                            cx,
 5161                        )
 5162                    })?
 5163                    .await
 5164            })
 5165        } else {
 5166            Task::ready(Ok(ProjectTransaction::default()))
 5167        }
 5168    }
 5169
 5170    pub fn resolved_hint(
 5171        &mut self,
 5172        buffer_id: BufferId,
 5173        id: InlayId,
 5174        cx: &mut Context<Self>,
 5175    ) -> Option<ResolvedHint> {
 5176        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5177
 5178        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5179        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5180        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5181        let (server_id, resolve_data) = match &hint.resolve_state {
 5182            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5183            ResolveState::Resolving => {
 5184                return Some(ResolvedHint::Resolving(
 5185                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5186                ));
 5187            }
 5188            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5189        };
 5190
 5191        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5192        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5193        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5194            id,
 5195            cx.spawn(async move |lsp_store, cx| {
 5196                let resolved_hint = resolve_task.await;
 5197                lsp_store
 5198                    .update(cx, |lsp_store, _| {
 5199                        if let Some(old_inlay_hint) = lsp_store
 5200                            .lsp_data
 5201                            .get_mut(&buffer_id)
 5202                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5203                        {
 5204                            match resolved_hint {
 5205                                Ok(resolved_hint) => {
 5206                                    *old_inlay_hint = resolved_hint;
 5207                                }
 5208                                Err(e) => {
 5209                                    old_inlay_hint.resolve_state =
 5210                                        ResolveState::CanResolve(server_id, resolve_data);
 5211                                    log::error!("Inlay hint resolve failed: {e:#}");
 5212                                }
 5213                            }
 5214                        }
 5215                    })
 5216                    .ok();
 5217            })
 5218            .shared(),
 5219        );
 5220        debug_assert!(
 5221            previous_task.is_none(),
 5222            "Did not change hint's resolve state after spawning its resolve"
 5223        );
 5224        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5225        None
 5226    }
 5227
 5228    fn resolve_inlay_hint(
 5229        &self,
 5230        mut hint: InlayHint,
 5231        buffer: Entity<Buffer>,
 5232        server_id: LanguageServerId,
 5233        cx: &mut Context<Self>,
 5234    ) -> Task<anyhow::Result<InlayHint>> {
 5235        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5236            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5237            {
 5238                hint.resolve_state = ResolveState::Resolved;
 5239                return Task::ready(Ok(hint));
 5240            }
 5241            let request = proto::ResolveInlayHint {
 5242                project_id,
 5243                buffer_id: buffer.read(cx).remote_id().into(),
 5244                language_server_id: server_id.0 as u64,
 5245                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5246            };
 5247            cx.background_spawn(async move {
 5248                let response = upstream_client
 5249                    .request(request)
 5250                    .await
 5251                    .context("inlay hints proto request")?;
 5252                match response.hint {
 5253                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5254                        .context("inlay hints proto resolve response conversion"),
 5255                    None => Ok(hint),
 5256                }
 5257            })
 5258        } else {
 5259            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5260                self.language_server_for_local_buffer(buffer, server_id, cx)
 5261                    .map(|(_, server)| server.clone())
 5262            }) else {
 5263                return Task::ready(Ok(hint));
 5264            };
 5265            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5266                return Task::ready(Ok(hint));
 5267            }
 5268            let buffer_snapshot = buffer.read(cx).snapshot();
 5269            cx.spawn(async move |_, cx| {
 5270                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5271                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5272                );
 5273                let resolved_hint = resolve_task
 5274                    .await
 5275                    .into_response()
 5276                    .context("inlay hint resolve LSP request")?;
 5277                let resolved_hint = InlayHints::lsp_to_project_hint(
 5278                    resolved_hint,
 5279                    &buffer,
 5280                    server_id,
 5281                    ResolveState::Resolved,
 5282                    false,
 5283                    cx,
 5284                )
 5285                .await?;
 5286                Ok(resolved_hint)
 5287            })
 5288        }
 5289    }
 5290
 5291    pub fn resolve_color_presentation(
 5292        &mut self,
 5293        mut color: DocumentColor,
 5294        buffer: Entity<Buffer>,
 5295        server_id: LanguageServerId,
 5296        cx: &mut Context<Self>,
 5297    ) -> Task<Result<DocumentColor>> {
 5298        if color.resolved {
 5299            return Task::ready(Ok(color));
 5300        }
 5301
 5302        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5303            let start = color.lsp_range.start;
 5304            let end = color.lsp_range.end;
 5305            let request = proto::GetColorPresentation {
 5306                project_id,
 5307                server_id: server_id.to_proto(),
 5308                buffer_id: buffer.read(cx).remote_id().into(),
 5309                color: Some(proto::ColorInformation {
 5310                    red: color.color.red,
 5311                    green: color.color.green,
 5312                    blue: color.color.blue,
 5313                    alpha: color.color.alpha,
 5314                    lsp_range_start: Some(proto::PointUtf16 {
 5315                        row: start.line,
 5316                        column: start.character,
 5317                    }),
 5318                    lsp_range_end: Some(proto::PointUtf16 {
 5319                        row: end.line,
 5320                        column: end.character,
 5321                    }),
 5322                }),
 5323            };
 5324            cx.background_spawn(async move {
 5325                let response = upstream_client
 5326                    .request(request)
 5327                    .await
 5328                    .context("color presentation proto request")?;
 5329                color.resolved = true;
 5330                color.color_presentations = response
 5331                    .presentations
 5332                    .into_iter()
 5333                    .map(|presentation| ColorPresentation {
 5334                        label: SharedString::from(presentation.label),
 5335                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5336                        additional_text_edits: presentation
 5337                            .additional_text_edits
 5338                            .into_iter()
 5339                            .filter_map(deserialize_lsp_edit)
 5340                            .collect(),
 5341                    })
 5342                    .collect();
 5343                Ok(color)
 5344            })
 5345        } else {
 5346            let path = match buffer
 5347                .update(cx, |buffer, cx| {
 5348                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5349                })
 5350                .context("buffer with the missing path")
 5351            {
 5352                Ok(path) => path,
 5353                Err(e) => return Task::ready(Err(e)),
 5354            };
 5355            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5356                self.language_server_for_local_buffer(buffer, server_id, cx)
 5357                    .map(|(_, server)| server.clone())
 5358            }) else {
 5359                return Task::ready(Ok(color));
 5360            };
 5361            cx.background_spawn(async move {
 5362                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5363                    lsp::ColorPresentationParams {
 5364                        text_document: make_text_document_identifier(&path)?,
 5365                        color: color.color,
 5366                        range: color.lsp_range,
 5367                        work_done_progress_params: Default::default(),
 5368                        partial_result_params: Default::default(),
 5369                    },
 5370                );
 5371                color.color_presentations = resolve_task
 5372                    .await
 5373                    .into_response()
 5374                    .context("color presentation resolve LSP request")?
 5375                    .into_iter()
 5376                    .map(|presentation| ColorPresentation {
 5377                        label: SharedString::from(presentation.label),
 5378                        text_edit: presentation.text_edit,
 5379                        additional_text_edits: presentation
 5380                            .additional_text_edits
 5381                            .unwrap_or_default(),
 5382                    })
 5383                    .collect();
 5384                color.resolved = true;
 5385                Ok(color)
 5386            })
 5387        }
 5388    }
 5389
 5390    pub(crate) fn linked_edits(
 5391        &mut self,
 5392        buffer: &Entity<Buffer>,
 5393        position: Anchor,
 5394        cx: &mut Context<Self>,
 5395    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5396        let snapshot = buffer.read(cx).snapshot();
 5397        let scope = snapshot.language_scope_at(position);
 5398        let Some(server_id) = self
 5399            .as_local()
 5400            .and_then(|local| {
 5401                buffer.update(cx, |buffer, cx| {
 5402                    local
 5403                        .language_servers_for_buffer(buffer, cx)
 5404                        .filter(|(_, server)| {
 5405                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5406                        })
 5407                        .filter(|(adapter, _)| {
 5408                            scope
 5409                                .as_ref()
 5410                                .map(|scope| scope.language_allowed(&adapter.name))
 5411                                .unwrap_or(true)
 5412                        })
 5413                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5414                        .next()
 5415                })
 5416            })
 5417            .or_else(|| {
 5418                self.upstream_client()
 5419                    .is_some()
 5420                    .then_some(LanguageServerToQuery::FirstCapable)
 5421            })
 5422            .filter(|_| {
 5423                maybe!({
 5424                    let language = buffer.read(cx).language_at(position)?;
 5425                    Some(
 5426                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5427                            .linked_edits,
 5428                    )
 5429                }) == Some(true)
 5430            })
 5431        else {
 5432            return Task::ready(Ok(Vec::new()));
 5433        };
 5434
 5435        self.request_lsp(
 5436            buffer.clone(),
 5437            server_id,
 5438            LinkedEditingRange { position },
 5439            cx,
 5440        )
 5441    }
 5442
 5443    fn apply_on_type_formatting(
 5444        &mut self,
 5445        buffer: Entity<Buffer>,
 5446        position: Anchor,
 5447        trigger: String,
 5448        cx: &mut Context<Self>,
 5449    ) -> Task<Result<Option<Transaction>>> {
 5450        if let Some((client, project_id)) = self.upstream_client() {
 5451            if !self.check_if_capable_for_proto_request(
 5452                &buffer,
 5453                |capabilities| {
 5454                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5455                },
 5456                cx,
 5457            ) {
 5458                return Task::ready(Ok(None));
 5459            }
 5460            let request = proto::OnTypeFormatting {
 5461                project_id,
 5462                buffer_id: buffer.read(cx).remote_id().into(),
 5463                position: Some(serialize_anchor(&position)),
 5464                trigger,
 5465                version: serialize_version(&buffer.read(cx).version()),
 5466            };
 5467            cx.background_spawn(async move {
 5468                client
 5469                    .request(request)
 5470                    .await?
 5471                    .transaction
 5472                    .map(language::proto::deserialize_transaction)
 5473                    .transpose()
 5474            })
 5475        } else if let Some(local) = self.as_local_mut() {
 5476            let buffer_id = buffer.read(cx).remote_id();
 5477            local.buffers_being_formatted.insert(buffer_id);
 5478            cx.spawn(async move |this, cx| {
 5479                let _cleanup = defer({
 5480                    let this = this.clone();
 5481                    let mut cx = cx.clone();
 5482                    move || {
 5483                        this.update(&mut cx, |this, _| {
 5484                            if let Some(local) = this.as_local_mut() {
 5485                                local.buffers_being_formatted.remove(&buffer_id);
 5486                            }
 5487                        })
 5488                        .ok();
 5489                    }
 5490                });
 5491
 5492                buffer
 5493                    .update(cx, |buffer, _| {
 5494                        buffer.wait_for_edits(Some(position.timestamp))
 5495                    })?
 5496                    .await?;
 5497                this.update(cx, |this, cx| {
 5498                    let position = position.to_point_utf16(buffer.read(cx));
 5499                    this.on_type_format(buffer, position, trigger, false, cx)
 5500                })?
 5501                .await
 5502            })
 5503        } else {
 5504            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5505        }
 5506    }
 5507
 5508    pub fn on_type_format<T: ToPointUtf16>(
 5509        &mut self,
 5510        buffer: Entity<Buffer>,
 5511        position: T,
 5512        trigger: String,
 5513        push_to_history: bool,
 5514        cx: &mut Context<Self>,
 5515    ) -> Task<Result<Option<Transaction>>> {
 5516        let position = position.to_point_utf16(buffer.read(cx));
 5517        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5518    }
 5519
 5520    fn on_type_format_impl(
 5521        &mut self,
 5522        buffer: Entity<Buffer>,
 5523        position: PointUtf16,
 5524        trigger: String,
 5525        push_to_history: bool,
 5526        cx: &mut Context<Self>,
 5527    ) -> Task<Result<Option<Transaction>>> {
 5528        let options = buffer.update(cx, |buffer, cx| {
 5529            lsp_command::lsp_formatting_options(
 5530                language_settings(
 5531                    buffer.language_at(position).map(|l| l.name()),
 5532                    buffer.file(),
 5533                    cx,
 5534                )
 5535                .as_ref(),
 5536            )
 5537        });
 5538
 5539        cx.spawn(async move |this, cx| {
 5540            if let Some(waiter) =
 5541                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5542            {
 5543                waiter.await?;
 5544            }
 5545            cx.update(|cx| {
 5546                this.update(cx, |this, cx| {
 5547                    this.request_lsp(
 5548                        buffer.clone(),
 5549                        LanguageServerToQuery::FirstCapable,
 5550                        OnTypeFormatting {
 5551                            position,
 5552                            trigger,
 5553                            options,
 5554                            push_to_history,
 5555                        },
 5556                        cx,
 5557                    )
 5558                })
 5559            })??
 5560            .await
 5561        })
 5562    }
 5563
 5564    pub fn definitions(
 5565        &mut self,
 5566        buffer: &Entity<Buffer>,
 5567        position: PointUtf16,
 5568        cx: &mut Context<Self>,
 5569    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5570        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5571            let request = GetDefinitions { position };
 5572            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5573                return Task::ready(Ok(None));
 5574            }
 5575            let request_task = upstream_client.request_lsp(
 5576                project_id,
 5577                None,
 5578                LSP_REQUEST_TIMEOUT,
 5579                cx.background_executor().clone(),
 5580                request.to_proto(project_id, buffer.read(cx)),
 5581            );
 5582            let buffer = buffer.clone();
 5583            cx.spawn(async move |weak_lsp_store, cx| {
 5584                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5585                    return Ok(None);
 5586                };
 5587                let Some(responses) = request_task.await? else {
 5588                    return Ok(None);
 5589                };
 5590                let actions = join_all(responses.payload.into_iter().map(|response| {
 5591                    GetDefinitions { position }.response_from_proto(
 5592                        response.response,
 5593                        lsp_store.clone(),
 5594                        buffer.clone(),
 5595                        cx.clone(),
 5596                    )
 5597                }))
 5598                .await;
 5599
 5600                Ok(Some(
 5601                    actions
 5602                        .into_iter()
 5603                        .collect::<Result<Vec<Vec<_>>>>()?
 5604                        .into_iter()
 5605                        .flatten()
 5606                        .dedup()
 5607                        .collect(),
 5608                ))
 5609            })
 5610        } else {
 5611            let definitions_task = self.request_multiple_lsp_locally(
 5612                buffer,
 5613                Some(position),
 5614                GetDefinitions { position },
 5615                cx,
 5616            );
 5617            cx.background_spawn(async move {
 5618                Ok(Some(
 5619                    definitions_task
 5620                        .await
 5621                        .into_iter()
 5622                        .flat_map(|(_, definitions)| definitions)
 5623                        .dedup()
 5624                        .collect(),
 5625                ))
 5626            })
 5627        }
 5628    }
 5629
 5630    pub fn declarations(
 5631        &mut self,
 5632        buffer: &Entity<Buffer>,
 5633        position: PointUtf16,
 5634        cx: &mut Context<Self>,
 5635    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5636        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5637            let request = GetDeclarations { position };
 5638            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5639                return Task::ready(Ok(None));
 5640            }
 5641            let request_task = upstream_client.request_lsp(
 5642                project_id,
 5643                None,
 5644                LSP_REQUEST_TIMEOUT,
 5645                cx.background_executor().clone(),
 5646                request.to_proto(project_id, buffer.read(cx)),
 5647            );
 5648            let buffer = buffer.clone();
 5649            cx.spawn(async move |weak_lsp_store, cx| {
 5650                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5651                    return Ok(None);
 5652                };
 5653                let Some(responses) = request_task.await? else {
 5654                    return Ok(None);
 5655                };
 5656                let actions = join_all(responses.payload.into_iter().map(|response| {
 5657                    GetDeclarations { position }.response_from_proto(
 5658                        response.response,
 5659                        lsp_store.clone(),
 5660                        buffer.clone(),
 5661                        cx.clone(),
 5662                    )
 5663                }))
 5664                .await;
 5665
 5666                Ok(Some(
 5667                    actions
 5668                        .into_iter()
 5669                        .collect::<Result<Vec<Vec<_>>>>()?
 5670                        .into_iter()
 5671                        .flatten()
 5672                        .dedup()
 5673                        .collect(),
 5674                ))
 5675            })
 5676        } else {
 5677            let declarations_task = self.request_multiple_lsp_locally(
 5678                buffer,
 5679                Some(position),
 5680                GetDeclarations { position },
 5681                cx,
 5682            );
 5683            cx.background_spawn(async move {
 5684                Ok(Some(
 5685                    declarations_task
 5686                        .await
 5687                        .into_iter()
 5688                        .flat_map(|(_, declarations)| declarations)
 5689                        .dedup()
 5690                        .collect(),
 5691                ))
 5692            })
 5693        }
 5694    }
 5695
 5696    pub fn type_definitions(
 5697        &mut self,
 5698        buffer: &Entity<Buffer>,
 5699        position: PointUtf16,
 5700        cx: &mut Context<Self>,
 5701    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5702        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5703            let request = GetTypeDefinitions { position };
 5704            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5705                return Task::ready(Ok(None));
 5706            }
 5707            let request_task = upstream_client.request_lsp(
 5708                project_id,
 5709                None,
 5710                LSP_REQUEST_TIMEOUT,
 5711                cx.background_executor().clone(),
 5712                request.to_proto(project_id, buffer.read(cx)),
 5713            );
 5714            let buffer = buffer.clone();
 5715            cx.spawn(async move |weak_lsp_store, cx| {
 5716                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5717                    return Ok(None);
 5718                };
 5719                let Some(responses) = request_task.await? else {
 5720                    return Ok(None);
 5721                };
 5722                let actions = join_all(responses.payload.into_iter().map(|response| {
 5723                    GetTypeDefinitions { position }.response_from_proto(
 5724                        response.response,
 5725                        lsp_store.clone(),
 5726                        buffer.clone(),
 5727                        cx.clone(),
 5728                    )
 5729                }))
 5730                .await;
 5731
 5732                Ok(Some(
 5733                    actions
 5734                        .into_iter()
 5735                        .collect::<Result<Vec<Vec<_>>>>()?
 5736                        .into_iter()
 5737                        .flatten()
 5738                        .dedup()
 5739                        .collect(),
 5740                ))
 5741            })
 5742        } else {
 5743            let type_definitions_task = self.request_multiple_lsp_locally(
 5744                buffer,
 5745                Some(position),
 5746                GetTypeDefinitions { position },
 5747                cx,
 5748            );
 5749            cx.background_spawn(async move {
 5750                Ok(Some(
 5751                    type_definitions_task
 5752                        .await
 5753                        .into_iter()
 5754                        .flat_map(|(_, type_definitions)| type_definitions)
 5755                        .dedup()
 5756                        .collect(),
 5757                ))
 5758            })
 5759        }
 5760    }
 5761
 5762    pub fn implementations(
 5763        &mut self,
 5764        buffer: &Entity<Buffer>,
 5765        position: PointUtf16,
 5766        cx: &mut Context<Self>,
 5767    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5768        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5769            let request = GetImplementations { position };
 5770            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5771                return Task::ready(Ok(None));
 5772            }
 5773            let request_task = upstream_client.request_lsp(
 5774                project_id,
 5775                None,
 5776                LSP_REQUEST_TIMEOUT,
 5777                cx.background_executor().clone(),
 5778                request.to_proto(project_id, buffer.read(cx)),
 5779            );
 5780            let buffer = buffer.clone();
 5781            cx.spawn(async move |weak_lsp_store, cx| {
 5782                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5783                    return Ok(None);
 5784                };
 5785                let Some(responses) = request_task.await? else {
 5786                    return Ok(None);
 5787                };
 5788                let actions = join_all(responses.payload.into_iter().map(|response| {
 5789                    GetImplementations { position }.response_from_proto(
 5790                        response.response,
 5791                        lsp_store.clone(),
 5792                        buffer.clone(),
 5793                        cx.clone(),
 5794                    )
 5795                }))
 5796                .await;
 5797
 5798                Ok(Some(
 5799                    actions
 5800                        .into_iter()
 5801                        .collect::<Result<Vec<Vec<_>>>>()?
 5802                        .into_iter()
 5803                        .flatten()
 5804                        .dedup()
 5805                        .collect(),
 5806                ))
 5807            })
 5808        } else {
 5809            let implementations_task = self.request_multiple_lsp_locally(
 5810                buffer,
 5811                Some(position),
 5812                GetImplementations { position },
 5813                cx,
 5814            );
 5815            cx.background_spawn(async move {
 5816                Ok(Some(
 5817                    implementations_task
 5818                        .await
 5819                        .into_iter()
 5820                        .flat_map(|(_, implementations)| implementations)
 5821                        .dedup()
 5822                        .collect(),
 5823                ))
 5824            })
 5825        }
 5826    }
 5827
 5828    pub fn references(
 5829        &mut self,
 5830        buffer: &Entity<Buffer>,
 5831        position: PointUtf16,
 5832        cx: &mut Context<Self>,
 5833    ) -> Task<Result<Option<Vec<Location>>>> {
 5834        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5835            let request = GetReferences { position };
 5836            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5837                return Task::ready(Ok(None));
 5838            }
 5839
 5840            let request_task = upstream_client.request_lsp(
 5841                project_id,
 5842                None,
 5843                LSP_REQUEST_TIMEOUT,
 5844                cx.background_executor().clone(),
 5845                request.to_proto(project_id, buffer.read(cx)),
 5846            );
 5847            let buffer = buffer.clone();
 5848            cx.spawn(async move |weak_lsp_store, cx| {
 5849                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5850                    return Ok(None);
 5851                };
 5852                let Some(responses) = request_task.await? else {
 5853                    return Ok(None);
 5854                };
 5855
 5856                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5857                    GetReferences { position }.response_from_proto(
 5858                        lsp_response.response,
 5859                        lsp_store.clone(),
 5860                        buffer.clone(),
 5861                        cx.clone(),
 5862                    )
 5863                }))
 5864                .await
 5865                .into_iter()
 5866                .collect::<Result<Vec<Vec<_>>>>()?
 5867                .into_iter()
 5868                .flatten()
 5869                .dedup()
 5870                .collect();
 5871                Ok(Some(locations))
 5872            })
 5873        } else {
 5874            let references_task = self.request_multiple_lsp_locally(
 5875                buffer,
 5876                Some(position),
 5877                GetReferences { position },
 5878                cx,
 5879            );
 5880            cx.background_spawn(async move {
 5881                Ok(Some(
 5882                    references_task
 5883                        .await
 5884                        .into_iter()
 5885                        .flat_map(|(_, references)| references)
 5886                        .dedup()
 5887                        .collect(),
 5888                ))
 5889            })
 5890        }
 5891    }
 5892
 5893    pub fn code_actions(
 5894        &mut self,
 5895        buffer: &Entity<Buffer>,
 5896        range: Range<Anchor>,
 5897        kinds: Option<Vec<CodeActionKind>>,
 5898        cx: &mut Context<Self>,
 5899    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5900        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5901            let request = GetCodeActions {
 5902                range: range.clone(),
 5903                kinds: kinds.clone(),
 5904            };
 5905            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5906                return Task::ready(Ok(None));
 5907            }
 5908            let request_task = upstream_client.request_lsp(
 5909                project_id,
 5910                None,
 5911                LSP_REQUEST_TIMEOUT,
 5912                cx.background_executor().clone(),
 5913                request.to_proto(project_id, buffer.read(cx)),
 5914            );
 5915            let buffer = buffer.clone();
 5916            cx.spawn(async move |weak_lsp_store, cx| {
 5917                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5918                    return Ok(None);
 5919                };
 5920                let Some(responses) = request_task.await? else {
 5921                    return Ok(None);
 5922                };
 5923                let actions = join_all(responses.payload.into_iter().map(|response| {
 5924                    GetCodeActions {
 5925                        range: range.clone(),
 5926                        kinds: kinds.clone(),
 5927                    }
 5928                    .response_from_proto(
 5929                        response.response,
 5930                        lsp_store.clone(),
 5931                        buffer.clone(),
 5932                        cx.clone(),
 5933                    )
 5934                }))
 5935                .await;
 5936
 5937                Ok(Some(
 5938                    actions
 5939                        .into_iter()
 5940                        .collect::<Result<Vec<Vec<_>>>>()?
 5941                        .into_iter()
 5942                        .flatten()
 5943                        .collect(),
 5944                ))
 5945            })
 5946        } else {
 5947            let all_actions_task = self.request_multiple_lsp_locally(
 5948                buffer,
 5949                Some(range.start),
 5950                GetCodeActions { range, kinds },
 5951                cx,
 5952            );
 5953            cx.background_spawn(async move {
 5954                Ok(Some(
 5955                    all_actions_task
 5956                        .await
 5957                        .into_iter()
 5958                        .flat_map(|(_, actions)| actions)
 5959                        .collect(),
 5960                ))
 5961            })
 5962        }
 5963    }
 5964
 5965    pub fn code_lens_actions(
 5966        &mut self,
 5967        buffer: &Entity<Buffer>,
 5968        cx: &mut Context<Self>,
 5969    ) -> CodeLensTask {
 5970        let version_queried_for = buffer.read(cx).version();
 5971        let buffer_id = buffer.read(cx).remote_id();
 5972        let existing_servers = self.as_local().map(|local| {
 5973            local
 5974                .buffers_opened_in_servers
 5975                .get(&buffer_id)
 5976                .cloned()
 5977                .unwrap_or_default()
 5978        });
 5979
 5980        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 5981            if let Some(cached_lens) = &lsp_data.code_lens {
 5982                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 5983                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 5984                        existing_servers != cached_lens.lens.keys().copied().collect()
 5985                    });
 5986                    if !has_different_servers {
 5987                        return Task::ready(Ok(Some(
 5988                            cached_lens.lens.values().flatten().cloned().collect(),
 5989                        )))
 5990                        .shared();
 5991                    }
 5992                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 5993                    if !version_queried_for.changed_since(updating_for) {
 5994                        return running_update.clone();
 5995                    }
 5996                }
 5997            }
 5998        }
 5999
 6000        let lens_lsp_data = self
 6001            .latest_lsp_data(buffer, cx)
 6002            .code_lens
 6003            .get_or_insert_default();
 6004        let buffer = buffer.clone();
 6005        let query_version_queried_for = version_queried_for.clone();
 6006        let new_task = cx
 6007            .spawn(async move |lsp_store, cx| {
 6008                cx.background_executor()
 6009                    .timer(Duration::from_millis(30))
 6010                    .await;
 6011                let fetched_lens = lsp_store
 6012                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 6013                    .map_err(Arc::new)?
 6014                    .await
 6015                    .context("fetching code lens")
 6016                    .map_err(Arc::new);
 6017                let fetched_lens = match fetched_lens {
 6018                    Ok(fetched_lens) => fetched_lens,
 6019                    Err(e) => {
 6020                        lsp_store
 6021                            .update(cx, |lsp_store, _| {
 6022                                if let Some(lens_lsp_data) = lsp_store
 6023                                    .lsp_data
 6024                                    .get_mut(&buffer_id)
 6025                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 6026                                {
 6027                                    lens_lsp_data.update = None;
 6028                                }
 6029                            })
 6030                            .ok();
 6031                        return Err(e);
 6032                    }
 6033                };
 6034
 6035                lsp_store
 6036                    .update(cx, |lsp_store, _| {
 6037                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 6038                        let code_lens = lsp_data.code_lens.as_mut()?;
 6039                        if let Some(fetched_lens) = fetched_lens {
 6040                            if lsp_data.buffer_version == query_version_queried_for {
 6041                                code_lens.lens.extend(fetched_lens);
 6042                            } else if !lsp_data
 6043                                .buffer_version
 6044                                .changed_since(&query_version_queried_for)
 6045                            {
 6046                                lsp_data.buffer_version = query_version_queried_for;
 6047                                code_lens.lens = fetched_lens;
 6048                            }
 6049                        }
 6050                        code_lens.update = None;
 6051                        Some(code_lens.lens.values().flatten().cloned().collect())
 6052                    })
 6053                    .map_err(Arc::new)
 6054            })
 6055            .shared();
 6056        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 6057        new_task
 6058    }
 6059
 6060    fn fetch_code_lens(
 6061        &mut self,
 6062        buffer: &Entity<Buffer>,
 6063        cx: &mut Context<Self>,
 6064    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 6065        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6066            let request = GetCodeLens;
 6067            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6068                return Task::ready(Ok(None));
 6069            }
 6070            let request_task = upstream_client.request_lsp(
 6071                project_id,
 6072                None,
 6073                LSP_REQUEST_TIMEOUT,
 6074                cx.background_executor().clone(),
 6075                request.to_proto(project_id, buffer.read(cx)),
 6076            );
 6077            let buffer = buffer.clone();
 6078            cx.spawn(async move |weak_lsp_store, cx| {
 6079                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6080                    return Ok(None);
 6081                };
 6082                let Some(responses) = request_task.await? else {
 6083                    return Ok(None);
 6084                };
 6085
 6086                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 6087                    let lsp_store = lsp_store.clone();
 6088                    let buffer = buffer.clone();
 6089                    let cx = cx.clone();
 6090                    async move {
 6091                        (
 6092                            LanguageServerId::from_proto(response.server_id),
 6093                            GetCodeLens
 6094                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6095                                .await,
 6096                        )
 6097                    }
 6098                }))
 6099                .await;
 6100
 6101                let mut has_errors = false;
 6102                let code_lens_actions = code_lens_actions
 6103                    .into_iter()
 6104                    .filter_map(|(server_id, code_lens)| match code_lens {
 6105                        Ok(code_lens) => Some((server_id, code_lens)),
 6106                        Err(e) => {
 6107                            has_errors = true;
 6108                            log::error!("{e:#}");
 6109                            None
 6110                        }
 6111                    })
 6112                    .collect::<HashMap<_, _>>();
 6113                anyhow::ensure!(
 6114                    !has_errors || !code_lens_actions.is_empty(),
 6115                    "Failed to fetch code lens"
 6116                );
 6117                Ok(Some(code_lens_actions))
 6118            })
 6119        } else {
 6120            let code_lens_actions_task =
 6121                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 6122            cx.background_spawn(async move {
 6123                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 6124            })
 6125        }
 6126    }
 6127
 6128    #[inline(never)]
 6129    pub fn completions(
 6130        &self,
 6131        buffer: &Entity<Buffer>,
 6132        position: PointUtf16,
 6133        context: CompletionContext,
 6134        cx: &mut Context<Self>,
 6135    ) -> Task<Result<Vec<CompletionResponse>>> {
 6136        let language_registry = self.languages.clone();
 6137
 6138        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6139            let snapshot = buffer.read(cx).snapshot();
 6140            let offset = position.to_offset(&snapshot);
 6141            let scope = snapshot.language_scope_at(offset);
 6142            let capable_lsps = self.all_capable_for_proto_request(
 6143                buffer,
 6144                |server_name, capabilities| {
 6145                    capabilities.completion_provider.is_some()
 6146                        && scope
 6147                            .as_ref()
 6148                            .map(|scope| scope.language_allowed(server_name))
 6149                            .unwrap_or(true)
 6150                },
 6151                cx,
 6152            );
 6153            if capable_lsps.is_empty() {
 6154                return Task::ready(Ok(Vec::new()));
 6155            }
 6156
 6157            let language = buffer.read(cx).language().cloned();
 6158
 6159            // In the future, we should provide project guests with the names of LSP adapters,
 6160            // so that they can use the correct LSP adapter when computing labels. For now,
 6161            // guests just use the first LSP adapter associated with the buffer's language.
 6162            let lsp_adapter = language.as_ref().and_then(|language| {
 6163                language_registry
 6164                    .lsp_adapters(&language.name())
 6165                    .first()
 6166                    .cloned()
 6167            });
 6168
 6169            let buffer = buffer.clone();
 6170
 6171            cx.spawn(async move |this, cx| {
 6172                let requests = join_all(
 6173                    capable_lsps
 6174                        .into_iter()
 6175                        .map(|id| {
 6176                            let request = GetCompletions {
 6177                                position,
 6178                                context: context.clone(),
 6179                                server_id: Some(id),
 6180                            };
 6181                            let buffer = buffer.clone();
 6182                            let language = language.clone();
 6183                            let lsp_adapter = lsp_adapter.clone();
 6184                            let upstream_client = upstream_client.clone();
 6185                            let response = this
 6186                                .update(cx, |this, cx| {
 6187                                    this.send_lsp_proto_request(
 6188                                        buffer,
 6189                                        upstream_client,
 6190                                        project_id,
 6191                                        request,
 6192                                        cx,
 6193                                    )
 6194                                })
 6195                                .log_err();
 6196                            async move {
 6197                                let response = response?.await.log_err()?;
 6198
 6199                                let completions = populate_labels_for_completions(
 6200                                    response.completions,
 6201                                    language,
 6202                                    lsp_adapter,
 6203                                )
 6204                                .await;
 6205
 6206                                Some(CompletionResponse {
 6207                                    completions,
 6208                                    display_options: CompletionDisplayOptions::default(),
 6209                                    is_incomplete: response.is_incomplete,
 6210                                })
 6211                            }
 6212                        })
 6213                        .collect::<Vec<_>>(),
 6214                );
 6215                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6216            })
 6217        } else if let Some(local) = self.as_local() {
 6218            let snapshot = buffer.read(cx).snapshot();
 6219            let offset = position.to_offset(&snapshot);
 6220            let scope = snapshot.language_scope_at(offset);
 6221            let language = snapshot.language().cloned();
 6222            let completion_settings = language_settings(
 6223                language.as_ref().map(|language| language.name()),
 6224                buffer.read(cx).file(),
 6225                cx,
 6226            )
 6227            .completions
 6228            .clone();
 6229            if !completion_settings.lsp {
 6230                return Task::ready(Ok(Vec::new()));
 6231            }
 6232
 6233            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6234                local
 6235                    .language_servers_for_buffer(buffer, cx)
 6236                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6237                    .filter(|(adapter, _)| {
 6238                        scope
 6239                            .as_ref()
 6240                            .map(|scope| scope.language_allowed(&adapter.name))
 6241                            .unwrap_or(true)
 6242                    })
 6243                    .map(|(_, server)| server.server_id())
 6244                    .collect()
 6245            });
 6246
 6247            let buffer = buffer.clone();
 6248            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6249            let lsp_timeout = if lsp_timeout > 0 {
 6250                Some(Duration::from_millis(lsp_timeout))
 6251            } else {
 6252                None
 6253            };
 6254            cx.spawn(async move |this,  cx| {
 6255                let mut tasks = Vec::with_capacity(server_ids.len());
 6256                this.update(cx, |lsp_store, cx| {
 6257                    for server_id in server_ids {
 6258                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6259                        let lsp_timeout = lsp_timeout
 6260                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6261                        let mut timeout = cx.background_spawn(async move {
 6262                            match lsp_timeout {
 6263                                Some(lsp_timeout) => {
 6264                                    lsp_timeout.await;
 6265                                    true
 6266                                },
 6267                                None => false,
 6268                            }
 6269                        }).fuse();
 6270                        let mut lsp_request = lsp_store.request_lsp(
 6271                            buffer.clone(),
 6272                            LanguageServerToQuery::Other(server_id),
 6273                            GetCompletions {
 6274                                position,
 6275                                context: context.clone(),
 6276                                server_id: Some(server_id),
 6277                            },
 6278                            cx,
 6279                        ).fuse();
 6280                        let new_task = cx.background_spawn(async move {
 6281                            select_biased! {
 6282                                response = lsp_request => anyhow::Ok(Some(response?)),
 6283                                timeout_happened = timeout => {
 6284                                    if timeout_happened {
 6285                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6286                                        Ok(None)
 6287                                    } else {
 6288                                        let completions = lsp_request.await?;
 6289                                        Ok(Some(completions))
 6290                                    }
 6291                                },
 6292                            }
 6293                        });
 6294                        tasks.push((lsp_adapter, new_task));
 6295                    }
 6296                })?;
 6297
 6298                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6299                    let completion_response = task.await.ok()??;
 6300                    let completions = populate_labels_for_completions(
 6301                            completion_response.completions,
 6302                            language.clone(),
 6303                            lsp_adapter,
 6304                        )
 6305                        .await;
 6306                    Some(CompletionResponse {
 6307                        completions,
 6308                        display_options: CompletionDisplayOptions::default(),
 6309                        is_incomplete: completion_response.is_incomplete,
 6310                    })
 6311                });
 6312
 6313                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6314
 6315                Ok(responses.into_iter().flatten().collect())
 6316            })
 6317        } else {
 6318            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6319        }
 6320    }
 6321
 6322    pub fn resolve_completions(
 6323        &self,
 6324        buffer: Entity<Buffer>,
 6325        completion_indices: Vec<usize>,
 6326        completions: Rc<RefCell<Box<[Completion]>>>,
 6327        cx: &mut Context<Self>,
 6328    ) -> Task<Result<bool>> {
 6329        let client = self.upstream_client();
 6330        let buffer_id = buffer.read(cx).remote_id();
 6331        let buffer_snapshot = buffer.read(cx).snapshot();
 6332
 6333        if !self.check_if_capable_for_proto_request(
 6334            &buffer,
 6335            GetCompletions::can_resolve_completions,
 6336            cx,
 6337        ) {
 6338            return Task::ready(Ok(false));
 6339        }
 6340        cx.spawn(async move |lsp_store, cx| {
 6341            let mut did_resolve = false;
 6342            if let Some((client, project_id)) = client {
 6343                for completion_index in completion_indices {
 6344                    let server_id = {
 6345                        let completion = &completions.borrow()[completion_index];
 6346                        completion.source.server_id()
 6347                    };
 6348                    if let Some(server_id) = server_id {
 6349                        if Self::resolve_completion_remote(
 6350                            project_id,
 6351                            server_id,
 6352                            buffer_id,
 6353                            completions.clone(),
 6354                            completion_index,
 6355                            client.clone(),
 6356                        )
 6357                        .await
 6358                        .log_err()
 6359                        .is_some()
 6360                        {
 6361                            did_resolve = true;
 6362                        }
 6363                    } else {
 6364                        resolve_word_completion(
 6365                            &buffer_snapshot,
 6366                            &mut completions.borrow_mut()[completion_index],
 6367                        );
 6368                    }
 6369                }
 6370            } else {
 6371                for completion_index in completion_indices {
 6372                    let server_id = {
 6373                        let completion = &completions.borrow()[completion_index];
 6374                        completion.source.server_id()
 6375                    };
 6376                    if let Some(server_id) = server_id {
 6377                        let server_and_adapter = lsp_store
 6378                            .read_with(cx, |lsp_store, _| {
 6379                                let server = lsp_store.language_server_for_id(server_id)?;
 6380                                let adapter =
 6381                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6382                                Some((server, adapter))
 6383                            })
 6384                            .ok()
 6385                            .flatten();
 6386                        let Some((server, adapter)) = server_and_adapter else {
 6387                            continue;
 6388                        };
 6389
 6390                        let resolved = Self::resolve_completion_local(
 6391                            server,
 6392                            completions.clone(),
 6393                            completion_index,
 6394                        )
 6395                        .await
 6396                        .log_err()
 6397                        .is_some();
 6398                        if resolved {
 6399                            Self::regenerate_completion_labels(
 6400                                adapter,
 6401                                &buffer_snapshot,
 6402                                completions.clone(),
 6403                                completion_index,
 6404                            )
 6405                            .await
 6406                            .log_err();
 6407                            did_resolve = true;
 6408                        }
 6409                    } else {
 6410                        resolve_word_completion(
 6411                            &buffer_snapshot,
 6412                            &mut completions.borrow_mut()[completion_index],
 6413                        );
 6414                    }
 6415                }
 6416            }
 6417
 6418            Ok(did_resolve)
 6419        })
 6420    }
 6421
 6422    async fn resolve_completion_local(
 6423        server: Arc<lsp::LanguageServer>,
 6424        completions: Rc<RefCell<Box<[Completion]>>>,
 6425        completion_index: usize,
 6426    ) -> Result<()> {
 6427        let server_id = server.server_id();
 6428        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6429            return Ok(());
 6430        }
 6431
 6432        let request = {
 6433            let completion = &completions.borrow()[completion_index];
 6434            match &completion.source {
 6435                CompletionSource::Lsp {
 6436                    lsp_completion,
 6437                    resolved,
 6438                    server_id: completion_server_id,
 6439                    ..
 6440                } => {
 6441                    if *resolved {
 6442                        return Ok(());
 6443                    }
 6444                    anyhow::ensure!(
 6445                        server_id == *completion_server_id,
 6446                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6447                    );
 6448                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6449                }
 6450                CompletionSource::BufferWord { .. }
 6451                | CompletionSource::Dap { .. }
 6452                | CompletionSource::Custom => {
 6453                    return Ok(());
 6454                }
 6455            }
 6456        };
 6457        let resolved_completion = request
 6458            .await
 6459            .into_response()
 6460            .context("resolve completion")?;
 6461
 6462        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6463        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6464
 6465        let mut completions = completions.borrow_mut();
 6466        let completion = &mut completions[completion_index];
 6467        if let CompletionSource::Lsp {
 6468            lsp_completion,
 6469            resolved,
 6470            server_id: completion_server_id,
 6471            ..
 6472        } = &mut completion.source
 6473        {
 6474            if *resolved {
 6475                return Ok(());
 6476            }
 6477            anyhow::ensure!(
 6478                server_id == *completion_server_id,
 6479                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6480            );
 6481            **lsp_completion = resolved_completion;
 6482            *resolved = true;
 6483        }
 6484        Ok(())
 6485    }
 6486
 6487    async fn regenerate_completion_labels(
 6488        adapter: Arc<CachedLspAdapter>,
 6489        snapshot: &BufferSnapshot,
 6490        completions: Rc<RefCell<Box<[Completion]>>>,
 6491        completion_index: usize,
 6492    ) -> Result<()> {
 6493        let completion_item = completions.borrow()[completion_index]
 6494            .source
 6495            .lsp_completion(true)
 6496            .map(Cow::into_owned);
 6497        if let Some(lsp_documentation) = completion_item
 6498            .as_ref()
 6499            .and_then(|completion_item| completion_item.documentation.clone())
 6500        {
 6501            let mut completions = completions.borrow_mut();
 6502            let completion = &mut completions[completion_index];
 6503            completion.documentation = Some(lsp_documentation.into());
 6504        } else {
 6505            let mut completions = completions.borrow_mut();
 6506            let completion = &mut completions[completion_index];
 6507            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6508        }
 6509
 6510        let mut new_label = match completion_item {
 6511            Some(completion_item) => {
 6512                // 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
 6513                // So we have to update the label here anyway...
 6514                let language = snapshot.language();
 6515                match language {
 6516                    Some(language) => {
 6517                        adapter
 6518                            .labels_for_completions(
 6519                                std::slice::from_ref(&completion_item),
 6520                                language,
 6521                            )
 6522                            .await?
 6523                    }
 6524                    None => Vec::new(),
 6525                }
 6526                .pop()
 6527                .flatten()
 6528                .unwrap_or_else(|| {
 6529                    CodeLabel::fallback_for_completion(
 6530                        &completion_item,
 6531                        language.map(|language| language.as_ref()),
 6532                    )
 6533                })
 6534            }
 6535            None => CodeLabel::plain(
 6536                completions.borrow()[completion_index].new_text.clone(),
 6537                None,
 6538            ),
 6539        };
 6540        ensure_uniform_list_compatible_label(&mut new_label);
 6541
 6542        let mut completions = completions.borrow_mut();
 6543        let completion = &mut completions[completion_index];
 6544        if completion.label.filter_text() == new_label.filter_text() {
 6545            completion.label = new_label;
 6546        } else {
 6547            log::error!(
 6548                "Resolved completion changed display label from {} to {}. \
 6549                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6550                completion.label.text(),
 6551                new_label.text(),
 6552                completion.label.filter_text(),
 6553                new_label.filter_text()
 6554            );
 6555        }
 6556
 6557        Ok(())
 6558    }
 6559
 6560    async fn resolve_completion_remote(
 6561        project_id: u64,
 6562        server_id: LanguageServerId,
 6563        buffer_id: BufferId,
 6564        completions: Rc<RefCell<Box<[Completion]>>>,
 6565        completion_index: usize,
 6566        client: AnyProtoClient,
 6567    ) -> Result<()> {
 6568        let lsp_completion = {
 6569            let completion = &completions.borrow()[completion_index];
 6570            match &completion.source {
 6571                CompletionSource::Lsp {
 6572                    lsp_completion,
 6573                    resolved,
 6574                    server_id: completion_server_id,
 6575                    ..
 6576                } => {
 6577                    anyhow::ensure!(
 6578                        server_id == *completion_server_id,
 6579                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6580                    );
 6581                    if *resolved {
 6582                        return Ok(());
 6583                    }
 6584                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6585                }
 6586                CompletionSource::Custom
 6587                | CompletionSource::Dap { .. }
 6588                | CompletionSource::BufferWord { .. } => {
 6589                    return Ok(());
 6590                }
 6591            }
 6592        };
 6593        let request = proto::ResolveCompletionDocumentation {
 6594            project_id,
 6595            language_server_id: server_id.0 as u64,
 6596            lsp_completion,
 6597            buffer_id: buffer_id.into(),
 6598        };
 6599
 6600        let response = client
 6601            .request(request)
 6602            .await
 6603            .context("completion documentation resolve proto request")?;
 6604        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6605
 6606        let documentation = if response.documentation.is_empty() {
 6607            CompletionDocumentation::Undocumented
 6608        } else if response.documentation_is_markdown {
 6609            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6610        } else if response.documentation.lines().count() <= 1 {
 6611            CompletionDocumentation::SingleLine(response.documentation.into())
 6612        } else {
 6613            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6614        };
 6615
 6616        let mut completions = completions.borrow_mut();
 6617        let completion = &mut completions[completion_index];
 6618        completion.documentation = Some(documentation);
 6619        if let CompletionSource::Lsp {
 6620            insert_range,
 6621            lsp_completion,
 6622            resolved,
 6623            server_id: completion_server_id,
 6624            lsp_defaults: _,
 6625        } = &mut completion.source
 6626        {
 6627            let completion_insert_range = response
 6628                .old_insert_start
 6629                .and_then(deserialize_anchor)
 6630                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6631            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6632
 6633            if *resolved {
 6634                return Ok(());
 6635            }
 6636            anyhow::ensure!(
 6637                server_id == *completion_server_id,
 6638                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6639            );
 6640            **lsp_completion = resolved_lsp_completion;
 6641            *resolved = true;
 6642        }
 6643
 6644        let replace_range = response
 6645            .old_replace_start
 6646            .and_then(deserialize_anchor)
 6647            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6648        if let Some((old_replace_start, old_replace_end)) = replace_range
 6649            && !response.new_text.is_empty()
 6650        {
 6651            completion.new_text = response.new_text;
 6652            completion.replace_range = old_replace_start..old_replace_end;
 6653        }
 6654
 6655        Ok(())
 6656    }
 6657
 6658    pub fn apply_additional_edits_for_completion(
 6659        &self,
 6660        buffer_handle: Entity<Buffer>,
 6661        completions: Rc<RefCell<Box<[Completion]>>>,
 6662        completion_index: usize,
 6663        push_to_history: bool,
 6664        cx: &mut Context<Self>,
 6665    ) -> Task<Result<Option<Transaction>>> {
 6666        if let Some((client, project_id)) = self.upstream_client() {
 6667            let buffer = buffer_handle.read(cx);
 6668            let buffer_id = buffer.remote_id();
 6669            cx.spawn(async move |_, cx| {
 6670                let request = {
 6671                    let completion = completions.borrow()[completion_index].clone();
 6672                    proto::ApplyCompletionAdditionalEdits {
 6673                        project_id,
 6674                        buffer_id: buffer_id.into(),
 6675                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6676                            replace_range: completion.replace_range,
 6677                            new_text: completion.new_text,
 6678                            source: completion.source,
 6679                        })),
 6680                    }
 6681                };
 6682
 6683                if let Some(transaction) = client.request(request).await?.transaction {
 6684                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6685                    buffer_handle
 6686                        .update(cx, |buffer, _| {
 6687                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6688                        })?
 6689                        .await?;
 6690                    if push_to_history {
 6691                        buffer_handle.update(cx, |buffer, _| {
 6692                            buffer.push_transaction(transaction.clone(), Instant::now());
 6693                            buffer.finalize_last_transaction();
 6694                        })?;
 6695                    }
 6696                    Ok(Some(transaction))
 6697                } else {
 6698                    Ok(None)
 6699                }
 6700            })
 6701        } else {
 6702            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6703                let completion = &completions.borrow()[completion_index];
 6704                let server_id = completion.source.server_id()?;
 6705                Some(
 6706                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6707                        .1
 6708                        .clone(),
 6709                )
 6710            }) else {
 6711                return Task::ready(Ok(None));
 6712            };
 6713
 6714            cx.spawn(async move |this, cx| {
 6715                Self::resolve_completion_local(
 6716                    server.clone(),
 6717                    completions.clone(),
 6718                    completion_index,
 6719                )
 6720                .await
 6721                .context("resolving completion")?;
 6722                let completion = completions.borrow()[completion_index].clone();
 6723                let additional_text_edits = completion
 6724                    .source
 6725                    .lsp_completion(true)
 6726                    .as_ref()
 6727                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6728                if let Some(edits) = additional_text_edits {
 6729                    let edits = this
 6730                        .update(cx, |this, cx| {
 6731                            this.as_local_mut().unwrap().edits_from_lsp(
 6732                                &buffer_handle,
 6733                                edits,
 6734                                server.server_id(),
 6735                                None,
 6736                                cx,
 6737                            )
 6738                        })?
 6739                        .await?;
 6740
 6741                    buffer_handle.update(cx, |buffer, cx| {
 6742                        buffer.finalize_last_transaction();
 6743                        buffer.start_transaction();
 6744
 6745                        for (range, text) in edits {
 6746                            let primary = &completion.replace_range;
 6747
 6748                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6749                            // and the primary completion is just an insertion (empty range), then this is likely
 6750                            // an auto-import scenario and should not be considered overlapping
 6751                            // https://github.com/zed-industries/zed/issues/26136
 6752                            let is_file_start_auto_import = {
 6753                                let snapshot = buffer.snapshot();
 6754                                let primary_start_point = primary.start.to_point(&snapshot);
 6755                                let range_start_point = range.start.to_point(&snapshot);
 6756
 6757                                let result = primary_start_point.row == 0
 6758                                    && primary_start_point.column == 0
 6759                                    && range_start_point.row == 0
 6760                                    && range_start_point.column == 0;
 6761
 6762                                result
 6763                            };
 6764
 6765                            let has_overlap = if is_file_start_auto_import {
 6766                                false
 6767                            } else {
 6768                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6769                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6770                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6771                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6772                                let result = start_within || end_within;
 6773                                result
 6774                            };
 6775
 6776                            //Skip additional edits which overlap with the primary completion edit
 6777                            //https://github.com/zed-industries/zed/pull/1871
 6778                            if !has_overlap {
 6779                                buffer.edit([(range, text)], None, cx);
 6780                            }
 6781                        }
 6782
 6783                        let transaction = if buffer.end_transaction(cx).is_some() {
 6784                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6785                            if !push_to_history {
 6786                                buffer.forget_transaction(transaction.id);
 6787                            }
 6788                            Some(transaction)
 6789                        } else {
 6790                            None
 6791                        };
 6792                        Ok(transaction)
 6793                    })?
 6794                } else {
 6795                    Ok(None)
 6796                }
 6797            })
 6798        }
 6799    }
 6800
 6801    pub fn pull_diagnostics(
 6802        &mut self,
 6803        buffer: Entity<Buffer>,
 6804        cx: &mut Context<Self>,
 6805    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6806        let buffer_id = buffer.read(cx).remote_id();
 6807
 6808        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6809            let mut suitable_capabilities = None;
 6810            // Are we capable for proto request?
 6811            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6812                &buffer,
 6813                |capabilities| {
 6814                    if let Some(caps) = &capabilities.diagnostic_provider {
 6815                        suitable_capabilities = Some(caps.clone());
 6816                        true
 6817                    } else {
 6818                        false
 6819                    }
 6820                },
 6821                cx,
 6822            );
 6823            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6824            let Some(dynamic_caps) = suitable_capabilities else {
 6825                return Task::ready(Ok(None));
 6826            };
 6827            assert!(any_server_has_diagnostics_provider);
 6828
 6829            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6830            let request = GetDocumentDiagnostics {
 6831                previous_result_id: None,
 6832                identifier,
 6833                registration_id: None,
 6834            };
 6835            let request_task = client.request_lsp(
 6836                upstream_project_id,
 6837                None,
 6838                LSP_REQUEST_TIMEOUT,
 6839                cx.background_executor().clone(),
 6840                request.to_proto(upstream_project_id, buffer.read(cx)),
 6841            );
 6842            cx.background_spawn(async move {
 6843                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6844                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6845                // Do not attempt to further process the dummy responses here.
 6846                let _response = request_task.await?;
 6847                Ok(None)
 6848            })
 6849        } else {
 6850            let servers = buffer.update(cx, |buffer, cx| {
 6851                self.running_language_servers_for_local_buffer(buffer, cx)
 6852                    .map(|(_, server)| server.clone())
 6853                    .collect::<Vec<_>>()
 6854            });
 6855
 6856            let pull_diagnostics = servers
 6857                .into_iter()
 6858                .flat_map(|server| {
 6859                    let result = maybe!({
 6860                        let local = self.as_local()?;
 6861                        let server_id = server.server_id();
 6862                        let providers_with_identifiers = local
 6863                            .language_server_dynamic_registrations
 6864                            .get(&server_id)
 6865                            .into_iter()
 6866                            .flat_map(|registrations| registrations.diagnostics.clone())
 6867                            .collect::<Vec<_>>();
 6868                        Some(
 6869                            providers_with_identifiers
 6870                                .into_iter()
 6871                                .map(|(registration_id, dynamic_caps)| {
 6872                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6873                                    let registration_id = registration_id.map(SharedString::from);
 6874                                    let result_id = self.result_id_for_buffer_pull(
 6875                                        server_id,
 6876                                        buffer_id,
 6877                                        &registration_id,
 6878                                        cx,
 6879                                    );
 6880                                    self.request_lsp(
 6881                                        buffer.clone(),
 6882                                        LanguageServerToQuery::Other(server_id),
 6883                                        GetDocumentDiagnostics {
 6884                                            previous_result_id: result_id,
 6885                                            registration_id,
 6886                                            identifier,
 6887                                        },
 6888                                        cx,
 6889                                    )
 6890                                })
 6891                                .collect::<Vec<_>>(),
 6892                        )
 6893                    });
 6894
 6895                    result.unwrap_or_default()
 6896                })
 6897                .collect::<Vec<_>>();
 6898
 6899            cx.background_spawn(async move {
 6900                let mut responses = Vec::new();
 6901                for diagnostics in join_all(pull_diagnostics).await {
 6902                    responses.extend(diagnostics?);
 6903                }
 6904                Ok(Some(responses))
 6905            })
 6906        }
 6907    }
 6908
 6909    pub fn applicable_inlay_chunks(
 6910        &mut self,
 6911        buffer: &Entity<Buffer>,
 6912        ranges: &[Range<text::Anchor>],
 6913        cx: &mut Context<Self>,
 6914    ) -> Vec<Range<BufferRow>> {
 6915        let buffer_snapshot = buffer.read(cx).snapshot();
 6916        let ranges = ranges
 6917            .iter()
 6918            .map(|range| range.to_point(&buffer_snapshot))
 6919            .collect::<Vec<_>>();
 6920
 6921        self.latest_lsp_data(buffer, cx)
 6922            .inlay_hints
 6923            .applicable_chunks(ranges.as_slice())
 6924            .map(|chunk| chunk.row_range())
 6925            .collect()
 6926    }
 6927
 6928    pub fn invalidate_inlay_hints<'a>(
 6929        &'a mut self,
 6930        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6931    ) {
 6932        for buffer_id in for_buffers {
 6933            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6934                lsp_data.inlay_hints.clear();
 6935            }
 6936        }
 6937    }
 6938
 6939    pub fn inlay_hints(
 6940        &mut self,
 6941        invalidate: InvalidationStrategy,
 6942        buffer: Entity<Buffer>,
 6943        ranges: Vec<Range<text::Anchor>>,
 6944        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6945        cx: &mut Context<Self>,
 6946    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6947        let next_hint_id = self.next_hint_id.clone();
 6948        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6949        let query_version = lsp_data.buffer_version.clone();
 6950        let mut lsp_refresh_requested = false;
 6951        let for_server = if let InvalidationStrategy::RefreshRequested {
 6952            server_id,
 6953            request_id,
 6954        } = invalidate
 6955        {
 6956            let invalidated = lsp_data
 6957                .inlay_hints
 6958                .invalidate_for_server_refresh(server_id, request_id);
 6959            lsp_refresh_requested = invalidated;
 6960            Some(server_id)
 6961        } else {
 6962            None
 6963        };
 6964        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6965        let known_chunks = known_chunks
 6966            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6967            .map(|(_, known_chunks)| known_chunks)
 6968            .unwrap_or_default();
 6969
 6970        let buffer_snapshot = buffer.read(cx).snapshot();
 6971        let ranges = ranges
 6972            .iter()
 6973            .map(|range| range.to_point(&buffer_snapshot))
 6974            .collect::<Vec<_>>();
 6975
 6976        let mut hint_fetch_tasks = Vec::new();
 6977        let mut cached_inlay_hints = None;
 6978        let mut ranges_to_query = None;
 6979        let applicable_chunks = existing_inlay_hints
 6980            .applicable_chunks(ranges.as_slice())
 6981            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 6982            .collect::<Vec<_>>();
 6983        if applicable_chunks.is_empty() {
 6984            return HashMap::default();
 6985        }
 6986
 6987        for row_chunk in applicable_chunks {
 6988            match (
 6989                existing_inlay_hints
 6990                    .cached_hints(&row_chunk)
 6991                    .filter(|_| !lsp_refresh_requested)
 6992                    .cloned(),
 6993                existing_inlay_hints
 6994                    .fetched_hints(&row_chunk)
 6995                    .as_ref()
 6996                    .filter(|_| !lsp_refresh_requested)
 6997                    .cloned(),
 6998            ) {
 6999                (None, None) => {
 7000                    let chunk_range = row_chunk.anchor_range();
 7001                    ranges_to_query
 7002                        .get_or_insert_with(Vec::new)
 7003                        .push((row_chunk, chunk_range));
 7004                }
 7005                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7006                (Some(cached_hints), None) => {
 7007                    for (server_id, cached_hints) in cached_hints {
 7008                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7009                            cached_inlay_hints
 7010                                .get_or_insert_with(HashMap::default)
 7011                                .entry(row_chunk.row_range())
 7012                                .or_insert_with(HashMap::default)
 7013                                .entry(server_id)
 7014                                .or_insert_with(Vec::new)
 7015                                .extend(cached_hints);
 7016                        }
 7017                    }
 7018                }
 7019                (Some(cached_hints), Some(fetched_hints)) => {
 7020                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7021                    for (server_id, cached_hints) in cached_hints {
 7022                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7023                            cached_inlay_hints
 7024                                .get_or_insert_with(HashMap::default)
 7025                                .entry(row_chunk.row_range())
 7026                                .or_insert_with(HashMap::default)
 7027                                .entry(server_id)
 7028                                .or_insert_with(Vec::new)
 7029                                .extend(cached_hints);
 7030                        }
 7031                    }
 7032                }
 7033            }
 7034        }
 7035
 7036        if hint_fetch_tasks.is_empty()
 7037            && ranges_to_query
 7038                .as_ref()
 7039                .is_none_or(|ranges| ranges.is_empty())
 7040            && let Some(cached_inlay_hints) = cached_inlay_hints
 7041        {
 7042            cached_inlay_hints
 7043                .into_iter()
 7044                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7045                .collect()
 7046        } else {
 7047            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7048                let next_hint_id = next_hint_id.clone();
 7049                let buffer = buffer.clone();
 7050                let query_version = query_version.clone();
 7051                let new_inlay_hints = cx
 7052                    .spawn(async move |lsp_store, cx| {
 7053                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7054                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7055                        })?;
 7056                        new_fetch_task
 7057                            .await
 7058                            .and_then(|new_hints_by_server| {
 7059                                lsp_store.update(cx, |lsp_store, cx| {
 7060                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7061                                    let update_cache = lsp_data.buffer_version == query_version;
 7062                                    if new_hints_by_server.is_empty() {
 7063                                        if update_cache {
 7064                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7065                                        }
 7066                                        HashMap::default()
 7067                                    } else {
 7068                                        new_hints_by_server
 7069                                            .into_iter()
 7070                                            .map(|(server_id, new_hints)| {
 7071                                                let new_hints = new_hints
 7072                                                    .into_iter()
 7073                                                    .map(|new_hint| {
 7074                                                        (
 7075                                                            InlayId::Hint(next_hint_id.fetch_add(
 7076                                                                1,
 7077                                                                atomic::Ordering::AcqRel,
 7078                                                            )),
 7079                                                            new_hint,
 7080                                                        )
 7081                                                    })
 7082                                                    .collect::<Vec<_>>();
 7083                                                if update_cache {
 7084                                                    lsp_data.inlay_hints.insert_new_hints(
 7085                                                        chunk,
 7086                                                        server_id,
 7087                                                        new_hints.clone(),
 7088                                                    );
 7089                                                }
 7090                                                (server_id, new_hints)
 7091                                            })
 7092                                            .collect()
 7093                                    }
 7094                                })
 7095                            })
 7096                            .map_err(Arc::new)
 7097                    })
 7098                    .shared();
 7099
 7100                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7101                *fetch_task = Some(new_inlay_hints.clone());
 7102                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7103            }
 7104
 7105            cached_inlay_hints
 7106                .unwrap_or_default()
 7107                .into_iter()
 7108                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7109                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7110                    (
 7111                        chunk.row_range(),
 7112                        cx.spawn(async move |_, _| {
 7113                            hints_fetch.await.map_err(|e| {
 7114                                if e.error_code() != ErrorCode::Internal {
 7115                                    anyhow!(e.error_code())
 7116                                } else {
 7117                                    anyhow!("{e:#}")
 7118                                }
 7119                            })
 7120                        }),
 7121                    )
 7122                }))
 7123                .collect()
 7124        }
 7125    }
 7126
 7127    fn fetch_inlay_hints(
 7128        &mut self,
 7129        for_server: Option<LanguageServerId>,
 7130        buffer: &Entity<Buffer>,
 7131        range: Range<Anchor>,
 7132        cx: &mut Context<Self>,
 7133    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7134        let request = InlayHints {
 7135            range: range.clone(),
 7136        };
 7137        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7138            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7139                return Task::ready(Ok(HashMap::default()));
 7140            }
 7141            let request_task = upstream_client.request_lsp(
 7142                project_id,
 7143                for_server.map(|id| id.to_proto()),
 7144                LSP_REQUEST_TIMEOUT,
 7145                cx.background_executor().clone(),
 7146                request.to_proto(project_id, buffer.read(cx)),
 7147            );
 7148            let buffer = buffer.clone();
 7149            cx.spawn(async move |weak_lsp_store, cx| {
 7150                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7151                    return Ok(HashMap::default());
 7152                };
 7153                let Some(responses) = request_task.await? else {
 7154                    return Ok(HashMap::default());
 7155                };
 7156
 7157                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7158                    let lsp_store = lsp_store.clone();
 7159                    let buffer = buffer.clone();
 7160                    let cx = cx.clone();
 7161                    let request = request.clone();
 7162                    async move {
 7163                        (
 7164                            LanguageServerId::from_proto(response.server_id),
 7165                            request
 7166                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7167                                .await,
 7168                        )
 7169                    }
 7170                }))
 7171                .await;
 7172
 7173                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot())?;
 7174                let mut has_errors = false;
 7175                let inlay_hints = inlay_hints
 7176                    .into_iter()
 7177                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7178                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7179                        Err(e) => {
 7180                            has_errors = true;
 7181                            log::error!("{e:#}");
 7182                            None
 7183                        }
 7184                    })
 7185                    .map(|(server_id, mut new_hints)| {
 7186                        new_hints.retain(|hint| {
 7187                            hint.position.is_valid(&buffer_snapshot)
 7188                                && range.start.is_valid(&buffer_snapshot)
 7189                                && range.end.is_valid(&buffer_snapshot)
 7190                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7191                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7192                        });
 7193                        (server_id, new_hints)
 7194                    })
 7195                    .collect::<HashMap<_, _>>();
 7196                anyhow::ensure!(
 7197                    !has_errors || !inlay_hints.is_empty(),
 7198                    "Failed to fetch inlay hints"
 7199                );
 7200                Ok(inlay_hints)
 7201            })
 7202        } else {
 7203            let inlay_hints_task = match for_server {
 7204                Some(server_id) => {
 7205                    let server_task = self.request_lsp(
 7206                        buffer.clone(),
 7207                        LanguageServerToQuery::Other(server_id),
 7208                        request,
 7209                        cx,
 7210                    );
 7211                    cx.background_spawn(async move {
 7212                        let mut responses = Vec::new();
 7213                        match server_task.await {
 7214                            Ok(response) => responses.push((server_id, response)),
 7215                            // rust-analyzer likes to error with this when its still loading up
 7216                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7217                            Err(e) => log::error!(
 7218                                "Error handling response for inlay hints request: {e:#}"
 7219                            ),
 7220                        }
 7221                        responses
 7222                    })
 7223                }
 7224                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7225            };
 7226            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7227            cx.background_spawn(async move {
 7228                Ok(inlay_hints_task
 7229                    .await
 7230                    .into_iter()
 7231                    .map(|(server_id, mut new_hints)| {
 7232                        new_hints.retain(|hint| {
 7233                            hint.position.is_valid(&buffer_snapshot)
 7234                                && range.start.is_valid(&buffer_snapshot)
 7235                                && range.end.is_valid(&buffer_snapshot)
 7236                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7237                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7238                        });
 7239                        (server_id, new_hints)
 7240                    })
 7241                    .collect())
 7242            })
 7243        }
 7244    }
 7245
 7246    pub fn pull_diagnostics_for_buffer(
 7247        &mut self,
 7248        buffer: Entity<Buffer>,
 7249        cx: &mut Context<Self>,
 7250    ) -> Task<anyhow::Result<()>> {
 7251        let diagnostics = self.pull_diagnostics(buffer, cx);
 7252        cx.spawn(async move |lsp_store, cx| {
 7253            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7254                return Ok(());
 7255            };
 7256            lsp_store.update(cx, |lsp_store, cx| {
 7257                if lsp_store.as_local().is_none() {
 7258                    return;
 7259                }
 7260
 7261                let mut unchanged_buffers = HashMap::default();
 7262                let server_diagnostics_updates = diagnostics
 7263                    .into_iter()
 7264                    .filter_map(|diagnostics_set| match diagnostics_set {
 7265                        LspPullDiagnostics::Response {
 7266                            server_id,
 7267                            uri,
 7268                            diagnostics,
 7269                            registration_id,
 7270                        } => Some((server_id, uri, diagnostics, registration_id)),
 7271                        LspPullDiagnostics::Default => None,
 7272                    })
 7273                    .fold(
 7274                        HashMap::default(),
 7275                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7276                            let (result_id, diagnostics) = match diagnostics {
 7277                                PulledDiagnostics::Unchanged { result_id } => {
 7278                                    unchanged_buffers
 7279                                        .entry(new_registration_id.clone())
 7280                                        .or_insert_with(HashSet::default)
 7281                                        .insert(uri.clone());
 7282                                    (Some(result_id), Vec::new())
 7283                                }
 7284                                PulledDiagnostics::Changed {
 7285                                    result_id,
 7286                                    diagnostics,
 7287                                } => (result_id, diagnostics),
 7288                            };
 7289                            let disk_based_sources = Cow::Owned(
 7290                                lsp_store
 7291                                    .language_server_adapter_for_id(server_id)
 7292                                    .as_ref()
 7293                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7294                                    .unwrap_or(&[])
 7295                                    .to_vec(),
 7296                            );
 7297                            acc.entry(server_id)
 7298                                .or_insert_with(HashMap::default)
 7299                                .entry(new_registration_id.clone())
 7300                                .or_insert_with(Vec::new)
 7301                                .push(DocumentDiagnosticsUpdate {
 7302                                    server_id,
 7303                                    diagnostics: lsp::PublishDiagnosticsParams {
 7304                                        uri,
 7305                                        diagnostics,
 7306                                        version: None,
 7307                                    },
 7308                                    result_id,
 7309                                    disk_based_sources,
 7310                                    registration_id: new_registration_id,
 7311                                });
 7312                            acc
 7313                        },
 7314                    );
 7315
 7316                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7317                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7318                        lsp_store
 7319                            .merge_lsp_diagnostics(
 7320                                DiagnosticSourceKind::Pulled,
 7321                                diagnostic_updates,
 7322                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7323                                    DiagnosticSourceKind::Pulled => {
 7324                                        old_diagnostic.registration_id != registration_id
 7325                                            || unchanged_buffers
 7326                                                .get(&old_diagnostic.registration_id)
 7327                                                .is_some_and(|unchanged_buffers| {
 7328                                                    unchanged_buffers.contains(&document_uri)
 7329                                                })
 7330                                    }
 7331                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7332                                        true
 7333                                    }
 7334                                },
 7335                                cx,
 7336                            )
 7337                            .log_err();
 7338                    }
 7339                }
 7340            })
 7341        })
 7342    }
 7343
 7344    pub fn document_colors(
 7345        &mut self,
 7346        known_cache_version: Option<usize>,
 7347        buffer: Entity<Buffer>,
 7348        cx: &mut Context<Self>,
 7349    ) -> Option<DocumentColorTask> {
 7350        let version_queried_for = buffer.read(cx).version();
 7351        let buffer_id = buffer.read(cx).remote_id();
 7352
 7353        let current_language_servers = self.as_local().map(|local| {
 7354            local
 7355                .buffers_opened_in_servers
 7356                .get(&buffer_id)
 7357                .cloned()
 7358                .unwrap_or_default()
 7359        });
 7360
 7361        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7362            if let Some(cached_colors) = &lsp_data.document_colors {
 7363                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7364                    let has_different_servers =
 7365                        current_language_servers.is_some_and(|current_language_servers| {
 7366                            current_language_servers
 7367                                != cached_colors.colors.keys().copied().collect()
 7368                        });
 7369                    if !has_different_servers {
 7370                        let cache_version = cached_colors.cache_version;
 7371                        if Some(cache_version) == known_cache_version {
 7372                            return None;
 7373                        } else {
 7374                            return Some(
 7375                                Task::ready(Ok(DocumentColors {
 7376                                    colors: cached_colors
 7377                                        .colors
 7378                                        .values()
 7379                                        .flatten()
 7380                                        .cloned()
 7381                                        .collect(),
 7382                                    cache_version: Some(cache_version),
 7383                                }))
 7384                                .shared(),
 7385                            );
 7386                        }
 7387                    }
 7388                }
 7389            }
 7390        }
 7391
 7392        let color_lsp_data = self
 7393            .latest_lsp_data(&buffer, cx)
 7394            .document_colors
 7395            .get_or_insert_default();
 7396        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7397            && !version_queried_for.changed_since(updating_for)
 7398        {
 7399            return Some(running_update.clone());
 7400        }
 7401        let buffer_version_queried_for = version_queried_for.clone();
 7402        let new_task = cx
 7403            .spawn(async move |lsp_store, cx| {
 7404                cx.background_executor()
 7405                    .timer(Duration::from_millis(30))
 7406                    .await;
 7407                let fetched_colors = lsp_store
 7408                    .update(cx, |lsp_store, cx| {
 7409                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7410                    })?
 7411                    .await
 7412                    .context("fetching document colors")
 7413                    .map_err(Arc::new);
 7414                let fetched_colors = match fetched_colors {
 7415                    Ok(fetched_colors) => {
 7416                        if Some(true)
 7417                            == buffer
 7418                                .update(cx, |buffer, _| {
 7419                                    buffer.version() != buffer_version_queried_for
 7420                                })
 7421                                .ok()
 7422                        {
 7423                            return Ok(DocumentColors::default());
 7424                        }
 7425                        fetched_colors
 7426                    }
 7427                    Err(e) => {
 7428                        lsp_store
 7429                            .update(cx, |lsp_store, _| {
 7430                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7431                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7432                                        document_colors.colors_update = None;
 7433                                    }
 7434                                }
 7435                            })
 7436                            .ok();
 7437                        return Err(e);
 7438                    }
 7439                };
 7440
 7441                lsp_store
 7442                    .update(cx, |lsp_store, cx| {
 7443                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7444                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7445
 7446                        if let Some(fetched_colors) = fetched_colors {
 7447                            if lsp_data.buffer_version == buffer_version_queried_for {
 7448                                lsp_colors.colors.extend(fetched_colors);
 7449                                lsp_colors.cache_version += 1;
 7450                            } else if !lsp_data
 7451                                .buffer_version
 7452                                .changed_since(&buffer_version_queried_for)
 7453                            {
 7454                                lsp_data.buffer_version = buffer_version_queried_for;
 7455                                lsp_colors.colors = fetched_colors;
 7456                                lsp_colors.cache_version += 1;
 7457                            }
 7458                        }
 7459                        lsp_colors.colors_update = None;
 7460                        let colors = lsp_colors
 7461                            .colors
 7462                            .values()
 7463                            .flatten()
 7464                            .cloned()
 7465                            .collect::<HashSet<_>>();
 7466                        DocumentColors {
 7467                            colors,
 7468                            cache_version: Some(lsp_colors.cache_version),
 7469                        }
 7470                    })
 7471                    .map_err(Arc::new)
 7472            })
 7473            .shared();
 7474        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7475        Some(new_task)
 7476    }
 7477
 7478    fn fetch_document_colors_for_buffer(
 7479        &mut self,
 7480        buffer: &Entity<Buffer>,
 7481        cx: &mut Context<Self>,
 7482    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7483        if let Some((client, project_id)) = self.upstream_client() {
 7484            let request = GetDocumentColor {};
 7485            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7486                return Task::ready(Ok(None));
 7487            }
 7488
 7489            let request_task = client.request_lsp(
 7490                project_id,
 7491                None,
 7492                LSP_REQUEST_TIMEOUT,
 7493                cx.background_executor().clone(),
 7494                request.to_proto(project_id, buffer.read(cx)),
 7495            );
 7496            let buffer = buffer.clone();
 7497            cx.spawn(async move |lsp_store, cx| {
 7498                let Some(lsp_store) = lsp_store.upgrade() else {
 7499                    return Ok(None);
 7500                };
 7501                let colors = join_all(
 7502                    request_task
 7503                        .await
 7504                        .log_err()
 7505                        .flatten()
 7506                        .map(|response| response.payload)
 7507                        .unwrap_or_default()
 7508                        .into_iter()
 7509                        .map(|color_response| {
 7510                            let response = request.response_from_proto(
 7511                                color_response.response,
 7512                                lsp_store.clone(),
 7513                                buffer.clone(),
 7514                                cx.clone(),
 7515                            );
 7516                            async move {
 7517                                (
 7518                                    LanguageServerId::from_proto(color_response.server_id),
 7519                                    response.await.log_err().unwrap_or_default(),
 7520                                )
 7521                            }
 7522                        }),
 7523                )
 7524                .await
 7525                .into_iter()
 7526                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7527                    acc.entry(server_id)
 7528                        .or_insert_with(HashSet::default)
 7529                        .extend(colors);
 7530                    acc
 7531                });
 7532                Ok(Some(colors))
 7533            })
 7534        } else {
 7535            let document_colors_task =
 7536                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7537            cx.background_spawn(async move {
 7538                Ok(Some(
 7539                    document_colors_task
 7540                        .await
 7541                        .into_iter()
 7542                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7543                            acc.entry(server_id)
 7544                                .or_insert_with(HashSet::default)
 7545                                .extend(colors);
 7546                            acc
 7547                        })
 7548                        .into_iter()
 7549                        .collect(),
 7550                ))
 7551            })
 7552        }
 7553    }
 7554
 7555    pub fn signature_help<T: ToPointUtf16>(
 7556        &mut self,
 7557        buffer: &Entity<Buffer>,
 7558        position: T,
 7559        cx: &mut Context<Self>,
 7560    ) -> Task<Option<Vec<SignatureHelp>>> {
 7561        let position = position.to_point_utf16(buffer.read(cx));
 7562
 7563        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7564            let request = GetSignatureHelp { position };
 7565            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7566                return Task::ready(None);
 7567            }
 7568            let request_task = client.request_lsp(
 7569                upstream_project_id,
 7570                None,
 7571                LSP_REQUEST_TIMEOUT,
 7572                cx.background_executor().clone(),
 7573                request.to_proto(upstream_project_id, buffer.read(cx)),
 7574            );
 7575            let buffer = buffer.clone();
 7576            cx.spawn(async move |weak_lsp_store, cx| {
 7577                let lsp_store = weak_lsp_store.upgrade()?;
 7578                let signatures = join_all(
 7579                    request_task
 7580                        .await
 7581                        .log_err()
 7582                        .flatten()
 7583                        .map(|response| response.payload)
 7584                        .unwrap_or_default()
 7585                        .into_iter()
 7586                        .map(|response| {
 7587                            let response = GetSignatureHelp { position }.response_from_proto(
 7588                                response.response,
 7589                                lsp_store.clone(),
 7590                                buffer.clone(),
 7591                                cx.clone(),
 7592                            );
 7593                            async move { response.await.log_err().flatten() }
 7594                        }),
 7595                )
 7596                .await
 7597                .into_iter()
 7598                .flatten()
 7599                .collect();
 7600                Some(signatures)
 7601            })
 7602        } else {
 7603            let all_actions_task = self.request_multiple_lsp_locally(
 7604                buffer,
 7605                Some(position),
 7606                GetSignatureHelp { position },
 7607                cx,
 7608            );
 7609            cx.background_spawn(async move {
 7610                Some(
 7611                    all_actions_task
 7612                        .await
 7613                        .into_iter()
 7614                        .flat_map(|(_, actions)| actions)
 7615                        .collect::<Vec<_>>(),
 7616                )
 7617            })
 7618        }
 7619    }
 7620
 7621    pub fn hover(
 7622        &mut self,
 7623        buffer: &Entity<Buffer>,
 7624        position: PointUtf16,
 7625        cx: &mut Context<Self>,
 7626    ) -> Task<Option<Vec<Hover>>> {
 7627        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7628            let request = GetHover { position };
 7629            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7630                return Task::ready(None);
 7631            }
 7632            let request_task = client.request_lsp(
 7633                upstream_project_id,
 7634                None,
 7635                LSP_REQUEST_TIMEOUT,
 7636                cx.background_executor().clone(),
 7637                request.to_proto(upstream_project_id, buffer.read(cx)),
 7638            );
 7639            let buffer = buffer.clone();
 7640            cx.spawn(async move |weak_lsp_store, cx| {
 7641                let lsp_store = weak_lsp_store.upgrade()?;
 7642                let hovers = join_all(
 7643                    request_task
 7644                        .await
 7645                        .log_err()
 7646                        .flatten()
 7647                        .map(|response| response.payload)
 7648                        .unwrap_or_default()
 7649                        .into_iter()
 7650                        .map(|response| {
 7651                            let response = GetHover { position }.response_from_proto(
 7652                                response.response,
 7653                                lsp_store.clone(),
 7654                                buffer.clone(),
 7655                                cx.clone(),
 7656                            );
 7657                            async move {
 7658                                response
 7659                                    .await
 7660                                    .log_err()
 7661                                    .flatten()
 7662                                    .and_then(remove_empty_hover_blocks)
 7663                            }
 7664                        }),
 7665                )
 7666                .await
 7667                .into_iter()
 7668                .flatten()
 7669                .collect();
 7670                Some(hovers)
 7671            })
 7672        } else {
 7673            let all_actions_task = self.request_multiple_lsp_locally(
 7674                buffer,
 7675                Some(position),
 7676                GetHover { position },
 7677                cx,
 7678            );
 7679            cx.background_spawn(async move {
 7680                Some(
 7681                    all_actions_task
 7682                        .await
 7683                        .into_iter()
 7684                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7685                        .collect::<Vec<Hover>>(),
 7686                )
 7687            })
 7688        }
 7689    }
 7690
 7691    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7692        let language_registry = self.languages.clone();
 7693
 7694        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7695            let request = upstream_client.request(proto::GetProjectSymbols {
 7696                project_id: *project_id,
 7697                query: query.to_string(),
 7698            });
 7699            cx.foreground_executor().spawn(async move {
 7700                let response = request.await?;
 7701                let mut symbols = Vec::new();
 7702                let core_symbols = response
 7703                    .symbols
 7704                    .into_iter()
 7705                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7706                    .collect::<Vec<_>>();
 7707                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7708                    .await;
 7709                Ok(symbols)
 7710            })
 7711        } else if let Some(local) = self.as_local() {
 7712            struct WorkspaceSymbolsResult {
 7713                server_id: LanguageServerId,
 7714                lsp_adapter: Arc<CachedLspAdapter>,
 7715                worktree: WeakEntity<Worktree>,
 7716                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7717            }
 7718
 7719            let mut requests = Vec::new();
 7720            let mut requested_servers = BTreeSet::new();
 7721            for (seed, state) in local.language_server_ids.iter() {
 7722                let Some(worktree_handle) = self
 7723                    .worktree_store
 7724                    .read(cx)
 7725                    .worktree_for_id(seed.worktree_id, cx)
 7726                else {
 7727                    continue;
 7728                };
 7729                let worktree = worktree_handle.read(cx);
 7730                if !worktree.is_visible() {
 7731                    continue;
 7732                }
 7733
 7734                if !requested_servers.insert(state.id) {
 7735                    continue;
 7736                }
 7737
 7738                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7739                    Some(LanguageServerState::Running {
 7740                        adapter, server, ..
 7741                    }) => (adapter.clone(), server),
 7742
 7743                    _ => continue,
 7744                };
 7745                let supports_workspace_symbol_request =
 7746                    match server.capabilities().workspace_symbol_provider {
 7747                        Some(OneOf::Left(supported)) => supported,
 7748                        Some(OneOf::Right(_)) => true,
 7749                        None => false,
 7750                    };
 7751                if !supports_workspace_symbol_request {
 7752                    continue;
 7753                }
 7754                let worktree_handle = worktree_handle.clone();
 7755                let server_id = server.server_id();
 7756                requests.push(
 7757                        server
 7758                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7759                                lsp::WorkspaceSymbolParams {
 7760                                    query: query.to_string(),
 7761                                    ..Default::default()
 7762                                },
 7763                            )
 7764                            .map(move |response| {
 7765                                let lsp_symbols = response.into_response()
 7766                                    .context("workspace symbols request")
 7767                                    .log_err()
 7768                                    .flatten()
 7769                                    .map(|symbol_response| match symbol_response {
 7770                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7771                                            flat_responses.into_iter().map(|lsp_symbol| {
 7772                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7773                                            }).collect::<Vec<_>>()
 7774                                        }
 7775                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7776                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7777                                                let location = match lsp_symbol.location {
 7778                                                    OneOf::Left(location) => location,
 7779                                                    OneOf::Right(_) => {
 7780                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7781                                                        return None
 7782                                                    }
 7783                                                };
 7784                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7785                                            }).collect::<Vec<_>>()
 7786                                        }
 7787                                    }).unwrap_or_default();
 7788
 7789                                WorkspaceSymbolsResult {
 7790                                    server_id,
 7791                                    lsp_adapter,
 7792                                    worktree: worktree_handle.downgrade(),
 7793                                    lsp_symbols,
 7794                                }
 7795                            }),
 7796                    );
 7797            }
 7798
 7799            cx.spawn(async move |this, cx| {
 7800                let responses = futures::future::join_all(requests).await;
 7801                let this = match this.upgrade() {
 7802                    Some(this) => this,
 7803                    None => return Ok(Vec::new()),
 7804                };
 7805
 7806                let mut symbols = Vec::new();
 7807                for result in responses {
 7808                    let core_symbols = this.update(cx, |this, cx| {
 7809                        result
 7810                            .lsp_symbols
 7811                            .into_iter()
 7812                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7813                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7814                                let source_worktree = result.worktree.upgrade()?;
 7815                                let source_worktree_id = source_worktree.read(cx).id();
 7816
 7817                                let path = if let Some((tree, rel_path)) =
 7818                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7819                                {
 7820                                    let worktree_id = tree.read(cx).id();
 7821                                    SymbolLocation::InProject(ProjectPath {
 7822                                        worktree_id,
 7823                                        path: rel_path,
 7824                                    })
 7825                                } else {
 7826                                    SymbolLocation::OutsideProject {
 7827                                        signature: this.symbol_signature(&abs_path),
 7828                                        abs_path: abs_path.into(),
 7829                                    }
 7830                                };
 7831
 7832                                Some(CoreSymbol {
 7833                                    source_language_server_id: result.server_id,
 7834                                    language_server_name: result.lsp_adapter.name.clone(),
 7835                                    source_worktree_id,
 7836                                    path,
 7837                                    kind: symbol_kind,
 7838                                    name: symbol_name,
 7839                                    range: range_from_lsp(symbol_location.range),
 7840                                })
 7841                            })
 7842                            .collect()
 7843                    })?;
 7844
 7845                    populate_labels_for_symbols(
 7846                        core_symbols,
 7847                        &language_registry,
 7848                        Some(result.lsp_adapter),
 7849                        &mut symbols,
 7850                    )
 7851                    .await;
 7852                }
 7853
 7854                Ok(symbols)
 7855            })
 7856        } else {
 7857            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7858        }
 7859    }
 7860
 7861    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7862        let mut summary = DiagnosticSummary::default();
 7863        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7864            summary.error_count += path_summary.error_count;
 7865            summary.warning_count += path_summary.warning_count;
 7866        }
 7867        summary
 7868    }
 7869
 7870    /// Returns the diagnostic summary for a specific project path.
 7871    pub fn diagnostic_summary_for_path(
 7872        &self,
 7873        project_path: &ProjectPath,
 7874        _: &App,
 7875    ) -> DiagnosticSummary {
 7876        if let Some(summaries) = self
 7877            .diagnostic_summaries
 7878            .get(&project_path.worktree_id)
 7879            .and_then(|map| map.get(&project_path.path))
 7880        {
 7881            let (error_count, warning_count) = summaries.iter().fold(
 7882                (0, 0),
 7883                |(error_count, warning_count), (_language_server_id, summary)| {
 7884                    (
 7885                        error_count + summary.error_count,
 7886                        warning_count + summary.warning_count,
 7887                    )
 7888                },
 7889            );
 7890
 7891            DiagnosticSummary {
 7892                error_count,
 7893                warning_count,
 7894            }
 7895        } else {
 7896            DiagnosticSummary::default()
 7897        }
 7898    }
 7899
 7900    pub fn diagnostic_summaries<'a>(
 7901        &'a self,
 7902        include_ignored: bool,
 7903        cx: &'a App,
 7904    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7905        self.worktree_store
 7906            .read(cx)
 7907            .visible_worktrees(cx)
 7908            .filter_map(|worktree| {
 7909                let worktree = worktree.read(cx);
 7910                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7911            })
 7912            .flat_map(move |(worktree, summaries)| {
 7913                let worktree_id = worktree.id();
 7914                summaries
 7915                    .iter()
 7916                    .filter(move |(path, _)| {
 7917                        include_ignored
 7918                            || worktree
 7919                                .entry_for_path(path.as_ref())
 7920                                .is_some_and(|entry| !entry.is_ignored)
 7921                    })
 7922                    .flat_map(move |(path, summaries)| {
 7923                        summaries.iter().map(move |(server_id, summary)| {
 7924                            (
 7925                                ProjectPath {
 7926                                    worktree_id,
 7927                                    path: path.clone(),
 7928                                },
 7929                                *server_id,
 7930                                *summary,
 7931                            )
 7932                        })
 7933                    })
 7934            })
 7935    }
 7936
 7937    pub fn on_buffer_edited(
 7938        &mut self,
 7939        buffer: Entity<Buffer>,
 7940        cx: &mut Context<Self>,
 7941    ) -> Option<()> {
 7942        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7943            Some(
 7944                self.as_local()?
 7945                    .language_servers_for_buffer(buffer, cx)
 7946                    .map(|i| i.1.clone())
 7947                    .collect(),
 7948            )
 7949        })?;
 7950
 7951        let buffer = buffer.read(cx);
 7952        let file = File::from_dyn(buffer.file())?;
 7953        let abs_path = file.as_local()?.abs_path(cx);
 7954        let uri = lsp::Uri::from_file_path(&abs_path)
 7955            .ok()
 7956            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7957            .log_err()?;
 7958        let next_snapshot = buffer.text_snapshot();
 7959        for language_server in language_servers {
 7960            let language_server = language_server.clone();
 7961
 7962            let buffer_snapshots = self
 7963                .as_local_mut()?
 7964                .buffer_snapshots
 7965                .get_mut(&buffer.remote_id())
 7966                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7967            let previous_snapshot = buffer_snapshots.last()?;
 7968
 7969            let build_incremental_change = || {
 7970                buffer
 7971                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7972                        previous_snapshot.snapshot.version(),
 7973                    )
 7974                    .map(|edit| {
 7975                        let edit_start = edit.new.start.0;
 7976                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7977                        let new_text = next_snapshot
 7978                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7979                            .collect();
 7980                        lsp::TextDocumentContentChangeEvent {
 7981                            range: Some(lsp::Range::new(
 7982                                point_to_lsp(edit_start),
 7983                                point_to_lsp(edit_end),
 7984                            )),
 7985                            range_length: None,
 7986                            text: new_text,
 7987                        }
 7988                    })
 7989                    .collect()
 7990            };
 7991
 7992            let document_sync_kind = language_server
 7993                .capabilities()
 7994                .text_document_sync
 7995                .as_ref()
 7996                .and_then(|sync| match sync {
 7997                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7998                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7999                });
 8000
 8001            let content_changes: Vec<_> = match document_sync_kind {
 8002                Some(lsp::TextDocumentSyncKind::FULL) => {
 8003                    vec![lsp::TextDocumentContentChangeEvent {
 8004                        range: None,
 8005                        range_length: None,
 8006                        text: next_snapshot.text(),
 8007                    }]
 8008                }
 8009                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8010                _ => {
 8011                    #[cfg(any(test, feature = "test-support"))]
 8012                    {
 8013                        build_incremental_change()
 8014                    }
 8015
 8016                    #[cfg(not(any(test, feature = "test-support")))]
 8017                    {
 8018                        continue;
 8019                    }
 8020                }
 8021            };
 8022
 8023            let next_version = previous_snapshot.version + 1;
 8024            buffer_snapshots.push(LspBufferSnapshot {
 8025                version: next_version,
 8026                snapshot: next_snapshot.clone(),
 8027            });
 8028
 8029            language_server
 8030                .notify::<lsp::notification::DidChangeTextDocument>(
 8031                    lsp::DidChangeTextDocumentParams {
 8032                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8033                            uri.clone(),
 8034                            next_version,
 8035                        ),
 8036                        content_changes,
 8037                    },
 8038                )
 8039                .ok();
 8040            self.pull_workspace_diagnostics(language_server.server_id());
 8041        }
 8042
 8043        None
 8044    }
 8045
 8046    pub fn on_buffer_saved(
 8047        &mut self,
 8048        buffer: Entity<Buffer>,
 8049        cx: &mut Context<Self>,
 8050    ) -> Option<()> {
 8051        let file = File::from_dyn(buffer.read(cx).file())?;
 8052        let worktree_id = file.worktree_id(cx);
 8053        let abs_path = file.as_local()?.abs_path(cx);
 8054        let text_document = lsp::TextDocumentIdentifier {
 8055            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8056        };
 8057        let local = self.as_local()?;
 8058
 8059        for server in local.language_servers_for_worktree(worktree_id) {
 8060            if let Some(include_text) = include_text(server.as_ref()) {
 8061                let text = if include_text {
 8062                    Some(buffer.read(cx).text())
 8063                } else {
 8064                    None
 8065                };
 8066                server
 8067                    .notify::<lsp::notification::DidSaveTextDocument>(
 8068                        lsp::DidSaveTextDocumentParams {
 8069                            text_document: text_document.clone(),
 8070                            text,
 8071                        },
 8072                    )
 8073                    .ok();
 8074            }
 8075        }
 8076
 8077        let language_servers = buffer.update(cx, |buffer, cx| {
 8078            local.language_server_ids_for_buffer(buffer, cx)
 8079        });
 8080        for language_server_id in language_servers {
 8081            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8082        }
 8083
 8084        None
 8085    }
 8086
 8087    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8088        maybe!(async move {
 8089            let mut refreshed_servers = HashSet::default();
 8090            let servers = lsp_store
 8091                .update(cx, |lsp_store, cx| {
 8092                    let local = lsp_store.as_local()?;
 8093
 8094                    let servers = local
 8095                        .language_server_ids
 8096                        .iter()
 8097                        .filter_map(|(seed, state)| {
 8098                            let worktree = lsp_store
 8099                                .worktree_store
 8100                                .read(cx)
 8101                                .worktree_for_id(seed.worktree_id, cx);
 8102                            let delegate: Arc<dyn LspAdapterDelegate> =
 8103                                worktree.map(|worktree| {
 8104                                    LocalLspAdapterDelegate::new(
 8105                                        local.languages.clone(),
 8106                                        &local.environment,
 8107                                        cx.weak_entity(),
 8108                                        &worktree,
 8109                                        local.http_client.clone(),
 8110                                        local.fs.clone(),
 8111                                        cx,
 8112                                    )
 8113                                })?;
 8114                            let server_id = state.id;
 8115
 8116                            let states = local.language_servers.get(&server_id)?;
 8117
 8118                            match states {
 8119                                LanguageServerState::Starting { .. } => None,
 8120                                LanguageServerState::Running {
 8121                                    adapter, server, ..
 8122                                } => {
 8123                                    let adapter = adapter.clone();
 8124                                    let server = server.clone();
 8125                                    refreshed_servers.insert(server.name());
 8126                                    let toolchain = seed.toolchain.clone();
 8127                                    Some(cx.spawn(async move |_, cx| {
 8128                                        let settings =
 8129                                            LocalLspStore::workspace_configuration_for_adapter(
 8130                                                adapter.adapter.clone(),
 8131                                                &delegate,
 8132                                                toolchain,
 8133                                                None,
 8134                                                cx,
 8135                                            )
 8136                                            .await
 8137                                            .ok()?;
 8138                                        server
 8139                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8140                                                lsp::DidChangeConfigurationParams { settings },
 8141                                            )
 8142                                            .ok()?;
 8143                                        Some(())
 8144                                    }))
 8145                                }
 8146                            }
 8147                        })
 8148                        .collect::<Vec<_>>();
 8149
 8150                    Some(servers)
 8151                })
 8152                .ok()
 8153                .flatten()?;
 8154
 8155            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8156            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8157            // to stop and unregister its language server wrapper.
 8158            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8159            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8160            let _: Vec<Option<()>> = join_all(servers).await;
 8161
 8162            Some(())
 8163        })
 8164        .await;
 8165    }
 8166
 8167    fn maintain_workspace_config(
 8168        external_refresh_requests: watch::Receiver<()>,
 8169        cx: &mut Context<Self>,
 8170    ) -> Task<Result<()>> {
 8171        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8172        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8173
 8174        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8175            *settings_changed_tx.borrow_mut() = ();
 8176        });
 8177
 8178        let mut joint_future =
 8179            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8180        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8181        // - 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).
 8182        // - 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.
 8183        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8184        // - 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,
 8185        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8186        cx.spawn(async move |this, cx| {
 8187            while let Some(()) = joint_future.next().await {
 8188                this.update(cx, |this, cx| {
 8189                    this.refresh_server_tree(cx);
 8190                })
 8191                .ok();
 8192
 8193                Self::refresh_workspace_configurations(&this, cx).await;
 8194            }
 8195
 8196            drop(settings_observation);
 8197            anyhow::Ok(())
 8198        })
 8199    }
 8200
 8201    pub fn running_language_servers_for_local_buffer<'a>(
 8202        &'a self,
 8203        buffer: &Buffer,
 8204        cx: &mut App,
 8205    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8206        let local = self.as_local();
 8207        let language_server_ids = local
 8208            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8209            .unwrap_or_default();
 8210
 8211        language_server_ids
 8212            .into_iter()
 8213            .filter_map(
 8214                move |server_id| match local?.language_servers.get(&server_id)? {
 8215                    LanguageServerState::Running {
 8216                        adapter, server, ..
 8217                    } => Some((adapter, server)),
 8218                    _ => None,
 8219                },
 8220            )
 8221    }
 8222
 8223    pub fn language_servers_for_local_buffer(
 8224        &self,
 8225        buffer: &Buffer,
 8226        cx: &mut App,
 8227    ) -> Vec<LanguageServerId> {
 8228        let local = self.as_local();
 8229        local
 8230            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8231            .unwrap_or_default()
 8232    }
 8233
 8234    pub fn language_server_for_local_buffer<'a>(
 8235        &'a self,
 8236        buffer: &'a Buffer,
 8237        server_id: LanguageServerId,
 8238        cx: &'a mut App,
 8239    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8240        self.as_local()?
 8241            .language_servers_for_buffer(buffer, cx)
 8242            .find(|(_, s)| s.server_id() == server_id)
 8243    }
 8244
 8245    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8246        self.diagnostic_summaries.remove(&id_to_remove);
 8247        if let Some(local) = self.as_local_mut() {
 8248            let to_remove = local.remove_worktree(id_to_remove, cx);
 8249            for server in to_remove {
 8250                self.language_server_statuses.remove(&server);
 8251            }
 8252        }
 8253    }
 8254
 8255    pub fn shared(
 8256        &mut self,
 8257        project_id: u64,
 8258        downstream_client: AnyProtoClient,
 8259        _: &mut Context<Self>,
 8260    ) {
 8261        self.downstream_client = Some((downstream_client.clone(), project_id));
 8262
 8263        for (server_id, status) in &self.language_server_statuses {
 8264            if let Some(server) = self.language_server_for_id(*server_id) {
 8265                downstream_client
 8266                    .send(proto::StartLanguageServer {
 8267                        project_id,
 8268                        server: Some(proto::LanguageServer {
 8269                            id: server_id.to_proto(),
 8270                            name: status.name.to_string(),
 8271                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8272                        }),
 8273                        capabilities: serde_json::to_string(&server.capabilities())
 8274                            .expect("serializing server LSP capabilities"),
 8275                    })
 8276                    .log_err();
 8277            }
 8278        }
 8279    }
 8280
 8281    pub fn disconnected_from_host(&mut self) {
 8282        self.downstream_client.take();
 8283    }
 8284
 8285    pub fn disconnected_from_ssh_remote(&mut self) {
 8286        if let LspStoreMode::Remote(RemoteLspStore {
 8287            upstream_client, ..
 8288        }) = &mut self.mode
 8289        {
 8290            upstream_client.take();
 8291        }
 8292    }
 8293
 8294    pub(crate) fn set_language_server_statuses_from_proto(
 8295        &mut self,
 8296        project: WeakEntity<Project>,
 8297        language_servers: Vec<proto::LanguageServer>,
 8298        server_capabilities: Vec<String>,
 8299        cx: &mut Context<Self>,
 8300    ) {
 8301        let lsp_logs = cx
 8302            .try_global::<GlobalLogStore>()
 8303            .map(|lsp_store| lsp_store.0.clone());
 8304
 8305        self.language_server_statuses = language_servers
 8306            .into_iter()
 8307            .zip(server_capabilities)
 8308            .map(|(server, server_capabilities)| {
 8309                let server_id = LanguageServerId(server.id as usize);
 8310                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8311                    self.lsp_server_capabilities
 8312                        .insert(server_id, server_capabilities);
 8313                }
 8314
 8315                let name = LanguageServerName::from_proto(server.name);
 8316                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8317
 8318                if let Some(lsp_logs) = &lsp_logs {
 8319                    lsp_logs.update(cx, |lsp_logs, cx| {
 8320                        lsp_logs.add_language_server(
 8321                            // Only remote clients get their language servers set from proto
 8322                            LanguageServerKind::Remote {
 8323                                project: project.clone(),
 8324                            },
 8325                            server_id,
 8326                            Some(name.clone()),
 8327                            worktree,
 8328                            None,
 8329                            cx,
 8330                        );
 8331                    });
 8332                }
 8333
 8334                (
 8335                    server_id,
 8336                    LanguageServerStatus {
 8337                        name,
 8338                        pending_work: Default::default(),
 8339                        has_pending_diagnostic_updates: false,
 8340                        progress_tokens: Default::default(),
 8341                        worktree,
 8342                        binary: None,
 8343                        configuration: None,
 8344                        workspace_folders: BTreeSet::new(),
 8345                    },
 8346                )
 8347            })
 8348            .collect();
 8349    }
 8350
 8351    #[cfg(test)]
 8352    pub fn update_diagnostic_entries(
 8353        &mut self,
 8354        server_id: LanguageServerId,
 8355        abs_path: PathBuf,
 8356        result_id: Option<SharedString>,
 8357        version: Option<i32>,
 8358        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8359        cx: &mut Context<Self>,
 8360    ) -> anyhow::Result<()> {
 8361        self.merge_diagnostic_entries(
 8362            vec![DocumentDiagnosticsUpdate {
 8363                diagnostics: DocumentDiagnostics {
 8364                    diagnostics,
 8365                    document_abs_path: abs_path,
 8366                    version,
 8367                },
 8368                result_id,
 8369                server_id,
 8370                disk_based_sources: Cow::Borrowed(&[]),
 8371                registration_id: None,
 8372            }],
 8373            |_, _, _| false,
 8374            cx,
 8375        )?;
 8376        Ok(())
 8377    }
 8378
 8379    pub fn merge_diagnostic_entries<'a>(
 8380        &mut self,
 8381        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8382        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8383        cx: &mut Context<Self>,
 8384    ) -> anyhow::Result<()> {
 8385        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8386        let mut updated_diagnostics_paths = HashMap::default();
 8387        for mut update in diagnostic_updates {
 8388            let abs_path = &update.diagnostics.document_abs_path;
 8389            let server_id = update.server_id;
 8390            let Some((worktree, relative_path)) =
 8391                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8392            else {
 8393                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8394                return Ok(());
 8395            };
 8396
 8397            let worktree_id = worktree.read(cx).id();
 8398            let project_path = ProjectPath {
 8399                worktree_id,
 8400                path: relative_path,
 8401            };
 8402
 8403            let document_uri = lsp::Uri::from_file_path(abs_path)
 8404                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8405            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8406                let snapshot = buffer_handle.read(cx).snapshot();
 8407                let buffer = buffer_handle.read(cx);
 8408                let reused_diagnostics = buffer
 8409                    .buffer_diagnostics(Some(server_id))
 8410                    .iter()
 8411                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8412                    .map(|v| {
 8413                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8414                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8415                        DiagnosticEntry {
 8416                            range: start..end,
 8417                            diagnostic: v.diagnostic.clone(),
 8418                        }
 8419                    })
 8420                    .collect::<Vec<_>>();
 8421
 8422                self.as_local_mut()
 8423                    .context("cannot merge diagnostics on a remote LspStore")?
 8424                    .update_buffer_diagnostics(
 8425                        &buffer_handle,
 8426                        server_id,
 8427                        Some(update.registration_id),
 8428                        update.result_id,
 8429                        update.diagnostics.version,
 8430                        update.diagnostics.diagnostics.clone(),
 8431                        reused_diagnostics.clone(),
 8432                        cx,
 8433                    )?;
 8434
 8435                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8436            } else if let Some(local) = self.as_local() {
 8437                let reused_diagnostics = local
 8438                    .diagnostics
 8439                    .get(&worktree_id)
 8440                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8441                    .and_then(|diagnostics_by_server_id| {
 8442                        diagnostics_by_server_id
 8443                            .binary_search_by_key(&server_id, |e| e.0)
 8444                            .ok()
 8445                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8446                    })
 8447                    .into_iter()
 8448                    .flatten()
 8449                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8450
 8451                update
 8452                    .diagnostics
 8453                    .diagnostics
 8454                    .extend(reused_diagnostics.cloned());
 8455            }
 8456
 8457            let updated = worktree.update(cx, |worktree, cx| {
 8458                self.update_worktree_diagnostics(
 8459                    worktree.id(),
 8460                    server_id,
 8461                    project_path.path.clone(),
 8462                    update.diagnostics.diagnostics,
 8463                    cx,
 8464                )
 8465            })?;
 8466            match updated {
 8467                ControlFlow::Continue(new_summary) => {
 8468                    if let Some((project_id, new_summary)) = new_summary {
 8469                        match &mut diagnostics_summary {
 8470                            Some(diagnostics_summary) => {
 8471                                diagnostics_summary
 8472                                    .more_summaries
 8473                                    .push(proto::DiagnosticSummary {
 8474                                        path: project_path.path.as_ref().to_proto(),
 8475                                        language_server_id: server_id.0 as u64,
 8476                                        error_count: new_summary.error_count,
 8477                                        warning_count: new_summary.warning_count,
 8478                                    })
 8479                            }
 8480                            None => {
 8481                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8482                                    project_id,
 8483                                    worktree_id: worktree_id.to_proto(),
 8484                                    summary: Some(proto::DiagnosticSummary {
 8485                                        path: project_path.path.as_ref().to_proto(),
 8486                                        language_server_id: server_id.0 as u64,
 8487                                        error_count: new_summary.error_count,
 8488                                        warning_count: new_summary.warning_count,
 8489                                    }),
 8490                                    more_summaries: Vec::new(),
 8491                                })
 8492                            }
 8493                        }
 8494                    }
 8495                    updated_diagnostics_paths
 8496                        .entry(server_id)
 8497                        .or_insert_with(Vec::new)
 8498                        .push(project_path);
 8499                }
 8500                ControlFlow::Break(()) => {}
 8501            }
 8502        }
 8503
 8504        if let Some((diagnostics_summary, (downstream_client, _))) =
 8505            diagnostics_summary.zip(self.downstream_client.as_ref())
 8506        {
 8507            downstream_client.send(diagnostics_summary).log_err();
 8508        }
 8509        for (server_id, paths) in updated_diagnostics_paths {
 8510            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8511        }
 8512        Ok(())
 8513    }
 8514
 8515    fn update_worktree_diagnostics(
 8516        &mut self,
 8517        worktree_id: WorktreeId,
 8518        server_id: LanguageServerId,
 8519        path_in_worktree: Arc<RelPath>,
 8520        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8521        _: &mut Context<Worktree>,
 8522    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8523        let local = match &mut self.mode {
 8524            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8525            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8526        };
 8527
 8528        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8529        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8530        let summaries_by_server_id = summaries_for_tree
 8531            .entry(path_in_worktree.clone())
 8532            .or_default();
 8533
 8534        let old_summary = summaries_by_server_id
 8535            .remove(&server_id)
 8536            .unwrap_or_default();
 8537
 8538        let new_summary = DiagnosticSummary::new(&diagnostics);
 8539        if diagnostics.is_empty() {
 8540            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8541            {
 8542                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8543                    diagnostics_by_server_id.remove(ix);
 8544                }
 8545                if diagnostics_by_server_id.is_empty() {
 8546                    diagnostics_for_tree.remove(&path_in_worktree);
 8547                }
 8548            }
 8549        } else {
 8550            summaries_by_server_id.insert(server_id, new_summary);
 8551            let diagnostics_by_server_id = diagnostics_for_tree
 8552                .entry(path_in_worktree.clone())
 8553                .or_default();
 8554            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8555                Ok(ix) => {
 8556                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8557                }
 8558                Err(ix) => {
 8559                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8560                }
 8561            }
 8562        }
 8563
 8564        if !old_summary.is_empty() || !new_summary.is_empty() {
 8565            if let Some((_, project_id)) = &self.downstream_client {
 8566                Ok(ControlFlow::Continue(Some((
 8567                    *project_id,
 8568                    proto::DiagnosticSummary {
 8569                        path: path_in_worktree.to_proto(),
 8570                        language_server_id: server_id.0 as u64,
 8571                        error_count: new_summary.error_count as u32,
 8572                        warning_count: new_summary.warning_count as u32,
 8573                    },
 8574                ))))
 8575            } else {
 8576                Ok(ControlFlow::Continue(None))
 8577            }
 8578        } else {
 8579            Ok(ControlFlow::Break(()))
 8580        }
 8581    }
 8582
 8583    pub fn open_buffer_for_symbol(
 8584        &mut self,
 8585        symbol: &Symbol,
 8586        cx: &mut Context<Self>,
 8587    ) -> Task<Result<Entity<Buffer>>> {
 8588        if let Some((client, project_id)) = self.upstream_client() {
 8589            let request = client.request(proto::OpenBufferForSymbol {
 8590                project_id,
 8591                symbol: Some(Self::serialize_symbol(symbol)),
 8592            });
 8593            cx.spawn(async move |this, cx| {
 8594                let response = request.await?;
 8595                let buffer_id = BufferId::new(response.buffer_id)?;
 8596                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8597                    .await
 8598            })
 8599        } else if let Some(local) = self.as_local() {
 8600            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8601                seed.worktree_id == symbol.source_worktree_id
 8602                    && state.id == symbol.source_language_server_id
 8603                    && symbol.language_server_name == seed.name
 8604            });
 8605            if !is_valid {
 8606                return Task::ready(Err(anyhow!(
 8607                    "language server for worktree and language not found"
 8608                )));
 8609            };
 8610
 8611            let symbol_abs_path = match &symbol.path {
 8612                SymbolLocation::InProject(project_path) => self
 8613                    .worktree_store
 8614                    .read(cx)
 8615                    .absolutize(&project_path, cx)
 8616                    .context("no such worktree"),
 8617                SymbolLocation::OutsideProject {
 8618                    abs_path,
 8619                    signature: _,
 8620                } => Ok(abs_path.to_path_buf()),
 8621            };
 8622            let symbol_abs_path = match symbol_abs_path {
 8623                Ok(abs_path) => abs_path,
 8624                Err(err) => return Task::ready(Err(err)),
 8625            };
 8626            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8627                uri
 8628            } else {
 8629                return Task::ready(Err(anyhow!("invalid symbol path")));
 8630            };
 8631
 8632            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8633        } else {
 8634            Task::ready(Err(anyhow!("no upstream client or local store")))
 8635        }
 8636    }
 8637
 8638    pub(crate) fn open_local_buffer_via_lsp(
 8639        &mut self,
 8640        abs_path: lsp::Uri,
 8641        language_server_id: LanguageServerId,
 8642        cx: &mut Context<Self>,
 8643    ) -> Task<Result<Entity<Buffer>>> {
 8644        cx.spawn(async move |lsp_store, cx| {
 8645            // Escape percent-encoded string.
 8646            let current_scheme = abs_path.scheme().to_owned();
 8647            // Uri is immutable, so we can't modify the scheme
 8648
 8649            let abs_path = abs_path
 8650                .to_file_path()
 8651                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8652            let p = abs_path.clone();
 8653            let yarn_worktree = lsp_store
 8654                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8655                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8656                        cx.spawn(async move |this, cx| {
 8657                            let t = this
 8658                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8659                                .ok()?;
 8660                            t.await
 8661                        })
 8662                    }),
 8663                    None => Task::ready(None),
 8664                })?
 8665                .await;
 8666            let (worktree_root_target, known_relative_path) =
 8667                if let Some((zip_root, relative_path)) = yarn_worktree {
 8668                    (zip_root, Some(relative_path))
 8669                } else {
 8670                    (Arc::<Path>::from(abs_path.as_path()), None)
 8671                };
 8672            let (worktree, relative_path) = if let Some(result) =
 8673                lsp_store.update(cx, |lsp_store, cx| {
 8674                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8675                        worktree_store.find_worktree(&worktree_root_target, cx)
 8676                    })
 8677                })? {
 8678                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8679                (result.0, relative_path)
 8680            } else {
 8681                let worktree = lsp_store
 8682                    .update(cx, |lsp_store, cx| {
 8683                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8684                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8685                        })
 8686                    })?
 8687                    .await?;
 8688                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8689                    lsp_store
 8690                        .update(cx, |lsp_store, cx| {
 8691                            if let Some(local) = lsp_store.as_local_mut() {
 8692                                local.register_language_server_for_invisible_worktree(
 8693                                    &worktree,
 8694                                    language_server_id,
 8695                                    cx,
 8696                                )
 8697                            }
 8698                        })
 8699                        .ok();
 8700                }
 8701                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8702                let relative_path = if let Some(known_path) = known_relative_path {
 8703                    known_path
 8704                } else {
 8705                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8706                        .into_arc()
 8707                };
 8708                (worktree, relative_path)
 8709            };
 8710            let project_path = ProjectPath {
 8711                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8712                path: relative_path,
 8713            };
 8714            lsp_store
 8715                .update(cx, |lsp_store, cx| {
 8716                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8717                        buffer_store.open_buffer(project_path, cx)
 8718                    })
 8719                })?
 8720                .await
 8721        })
 8722    }
 8723
 8724    fn request_multiple_lsp_locally<P, R>(
 8725        &mut self,
 8726        buffer: &Entity<Buffer>,
 8727        position: Option<P>,
 8728        request: R,
 8729        cx: &mut Context<Self>,
 8730    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8731    where
 8732        P: ToOffset,
 8733        R: LspCommand + Clone,
 8734        <R::LspRequest as lsp::request::Request>::Result: Send,
 8735        <R::LspRequest as lsp::request::Request>::Params: Send,
 8736    {
 8737        let Some(local) = self.as_local() else {
 8738            return Task::ready(Vec::new());
 8739        };
 8740
 8741        let snapshot = buffer.read(cx).snapshot();
 8742        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8743
 8744        let server_ids = buffer.update(cx, |buffer, cx| {
 8745            local
 8746                .language_servers_for_buffer(buffer, cx)
 8747                .filter(|(adapter, _)| {
 8748                    scope
 8749                        .as_ref()
 8750                        .map(|scope| scope.language_allowed(&adapter.name))
 8751                        .unwrap_or(true)
 8752                })
 8753                .map(|(_, server)| server.server_id())
 8754                .filter(|server_id| {
 8755                    self.as_local().is_none_or(|local| {
 8756                        local
 8757                            .buffers_opened_in_servers
 8758                            .get(&snapshot.remote_id())
 8759                            .is_some_and(|servers| servers.contains(server_id))
 8760                    })
 8761                })
 8762                .collect::<Vec<_>>()
 8763        });
 8764
 8765        let mut response_results = server_ids
 8766            .into_iter()
 8767            .map(|server_id| {
 8768                let task = self.request_lsp(
 8769                    buffer.clone(),
 8770                    LanguageServerToQuery::Other(server_id),
 8771                    request.clone(),
 8772                    cx,
 8773                );
 8774                async move { (server_id, task.await) }
 8775            })
 8776            .collect::<FuturesUnordered<_>>();
 8777
 8778        cx.background_spawn(async move {
 8779            let mut responses = Vec::with_capacity(response_results.len());
 8780            while let Some((server_id, response_result)) = response_results.next().await {
 8781                match response_result {
 8782                    Ok(response) => responses.push((server_id, response)),
 8783                    // rust-analyzer likes to error with this when its still loading up
 8784                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8785                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8786                }
 8787            }
 8788            responses
 8789        })
 8790    }
 8791
 8792    async fn handle_lsp_get_completions(
 8793        this: Entity<Self>,
 8794        envelope: TypedEnvelope<proto::GetCompletions>,
 8795        mut cx: AsyncApp,
 8796    ) -> Result<proto::GetCompletionsResponse> {
 8797        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8798
 8799        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8800        let buffer_handle = this.update(&mut cx, |this, cx| {
 8801            this.buffer_store.read(cx).get_existing(buffer_id)
 8802        })??;
 8803        let request = GetCompletions::from_proto(
 8804            envelope.payload,
 8805            this.clone(),
 8806            buffer_handle.clone(),
 8807            cx.clone(),
 8808        )
 8809        .await?;
 8810
 8811        let server_to_query = match request.server_id {
 8812            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8813            None => LanguageServerToQuery::FirstCapable,
 8814        };
 8815
 8816        let response = this
 8817            .update(&mut cx, |this, cx| {
 8818                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8819            })?
 8820            .await?;
 8821        this.update(&mut cx, |this, cx| {
 8822            Ok(GetCompletions::response_to_proto(
 8823                response,
 8824                this,
 8825                sender_id,
 8826                &buffer_handle.read(cx).version(),
 8827                cx,
 8828            ))
 8829        })?
 8830    }
 8831
 8832    async fn handle_lsp_command<T: LspCommand>(
 8833        this: Entity<Self>,
 8834        envelope: TypedEnvelope<T::ProtoRequest>,
 8835        mut cx: AsyncApp,
 8836    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8837    where
 8838        <T::LspRequest as lsp::request::Request>::Params: Send,
 8839        <T::LspRequest as lsp::request::Request>::Result: Send,
 8840    {
 8841        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8842        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8843        let buffer_handle = this.update(&mut cx, |this, cx| {
 8844            this.buffer_store.read(cx).get_existing(buffer_id)
 8845        })??;
 8846        let request = T::from_proto(
 8847            envelope.payload,
 8848            this.clone(),
 8849            buffer_handle.clone(),
 8850            cx.clone(),
 8851        )
 8852        .await?;
 8853        let response = this
 8854            .update(&mut cx, |this, cx| {
 8855                this.request_lsp(
 8856                    buffer_handle.clone(),
 8857                    LanguageServerToQuery::FirstCapable,
 8858                    request,
 8859                    cx,
 8860                )
 8861            })?
 8862            .await?;
 8863        this.update(&mut cx, |this, cx| {
 8864            Ok(T::response_to_proto(
 8865                response,
 8866                this,
 8867                sender_id,
 8868                &buffer_handle.read(cx).version(),
 8869                cx,
 8870            ))
 8871        })?
 8872    }
 8873
 8874    async fn handle_lsp_query(
 8875        lsp_store: Entity<Self>,
 8876        envelope: TypedEnvelope<proto::LspQuery>,
 8877        mut cx: AsyncApp,
 8878    ) -> Result<proto::Ack> {
 8879        use proto::lsp_query::Request;
 8880        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8881        let lsp_query = envelope.payload;
 8882        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8883        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8884        match lsp_query.request.context("invalid LSP query request")? {
 8885            Request::GetReferences(get_references) => {
 8886                let position = get_references.position.clone().and_then(deserialize_anchor);
 8887                Self::query_lsp_locally::<GetReferences>(
 8888                    lsp_store,
 8889                    server_id,
 8890                    sender_id,
 8891                    lsp_request_id,
 8892                    get_references,
 8893                    position,
 8894                    &mut cx,
 8895                )
 8896                .await?;
 8897            }
 8898            Request::GetDocumentColor(get_document_color) => {
 8899                Self::query_lsp_locally::<GetDocumentColor>(
 8900                    lsp_store,
 8901                    server_id,
 8902                    sender_id,
 8903                    lsp_request_id,
 8904                    get_document_color,
 8905                    None,
 8906                    &mut cx,
 8907                )
 8908                .await?;
 8909            }
 8910            Request::GetHover(get_hover) => {
 8911                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8912                Self::query_lsp_locally::<GetHover>(
 8913                    lsp_store,
 8914                    server_id,
 8915                    sender_id,
 8916                    lsp_request_id,
 8917                    get_hover,
 8918                    position,
 8919                    &mut cx,
 8920                )
 8921                .await?;
 8922            }
 8923            Request::GetCodeActions(get_code_actions) => {
 8924                Self::query_lsp_locally::<GetCodeActions>(
 8925                    lsp_store,
 8926                    server_id,
 8927                    sender_id,
 8928                    lsp_request_id,
 8929                    get_code_actions,
 8930                    None,
 8931                    &mut cx,
 8932                )
 8933                .await?;
 8934            }
 8935            Request::GetSignatureHelp(get_signature_help) => {
 8936                let position = get_signature_help
 8937                    .position
 8938                    .clone()
 8939                    .and_then(deserialize_anchor);
 8940                Self::query_lsp_locally::<GetSignatureHelp>(
 8941                    lsp_store,
 8942                    server_id,
 8943                    sender_id,
 8944                    lsp_request_id,
 8945                    get_signature_help,
 8946                    position,
 8947                    &mut cx,
 8948                )
 8949                .await?;
 8950            }
 8951            Request::GetCodeLens(get_code_lens) => {
 8952                Self::query_lsp_locally::<GetCodeLens>(
 8953                    lsp_store,
 8954                    server_id,
 8955                    sender_id,
 8956                    lsp_request_id,
 8957                    get_code_lens,
 8958                    None,
 8959                    &mut cx,
 8960                )
 8961                .await?;
 8962            }
 8963            Request::GetDefinition(get_definition) => {
 8964                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8965                Self::query_lsp_locally::<GetDefinitions>(
 8966                    lsp_store,
 8967                    server_id,
 8968                    sender_id,
 8969                    lsp_request_id,
 8970                    get_definition,
 8971                    position,
 8972                    &mut cx,
 8973                )
 8974                .await?;
 8975            }
 8976            Request::GetDeclaration(get_declaration) => {
 8977                let position = get_declaration
 8978                    .position
 8979                    .clone()
 8980                    .and_then(deserialize_anchor);
 8981                Self::query_lsp_locally::<GetDeclarations>(
 8982                    lsp_store,
 8983                    server_id,
 8984                    sender_id,
 8985                    lsp_request_id,
 8986                    get_declaration,
 8987                    position,
 8988                    &mut cx,
 8989                )
 8990                .await?;
 8991            }
 8992            Request::GetTypeDefinition(get_type_definition) => {
 8993                let position = get_type_definition
 8994                    .position
 8995                    .clone()
 8996                    .and_then(deserialize_anchor);
 8997                Self::query_lsp_locally::<GetTypeDefinitions>(
 8998                    lsp_store,
 8999                    server_id,
 9000                    sender_id,
 9001                    lsp_request_id,
 9002                    get_type_definition,
 9003                    position,
 9004                    &mut cx,
 9005                )
 9006                .await?;
 9007            }
 9008            Request::GetImplementation(get_implementation) => {
 9009                let position = get_implementation
 9010                    .position
 9011                    .clone()
 9012                    .and_then(deserialize_anchor);
 9013                Self::query_lsp_locally::<GetImplementations>(
 9014                    lsp_store,
 9015                    server_id,
 9016                    sender_id,
 9017                    lsp_request_id,
 9018                    get_implementation,
 9019                    position,
 9020                    &mut cx,
 9021                )
 9022                .await?;
 9023            }
 9024            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9025                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 9026                let version = deserialize_version(get_document_diagnostics.buffer_version());
 9027                let buffer = lsp_store.update(&mut cx, |this, cx| {
 9028                    this.buffer_store.read(cx).get_existing(buffer_id)
 9029                })??;
 9030                buffer
 9031                    .update(&mut cx, |buffer, _| {
 9032                        buffer.wait_for_version(version.clone())
 9033                    })?
 9034                    .await?;
 9035                lsp_store.update(&mut cx, |lsp_store, cx| {
 9036                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9037                    let key = LspKey {
 9038                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9039                        server_queried: server_id,
 9040                    };
 9041                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9042                    ) {
 9043                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9044                            lsp_requests.clear();
 9045                        };
 9046                    }
 9047
 9048                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 9049                    existing_queries.insert(
 9050                        lsp_request_id,
 9051                        cx.spawn(async move |lsp_store, cx| {
 9052                            let diagnostics_pull = lsp_store
 9053                                .update(cx, |lsp_store, cx| {
 9054                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9055                                })
 9056                                .ok();
 9057                            if let Some(diagnostics_pull) = diagnostics_pull {
 9058                                match diagnostics_pull.await {
 9059                                    Ok(()) => {}
 9060                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9061                                };
 9062                            }
 9063                        }),
 9064                    );
 9065                })?;
 9066            }
 9067            Request::InlayHints(inlay_hints) => {
 9068                let query_start = inlay_hints
 9069                    .start
 9070                    .clone()
 9071                    .and_then(deserialize_anchor)
 9072                    .context("invalid inlay hints range start")?;
 9073                let query_end = inlay_hints
 9074                    .end
 9075                    .clone()
 9076                    .and_then(deserialize_anchor)
 9077                    .context("invalid inlay hints range end")?;
 9078                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9079                    &lsp_store,
 9080                    server_id,
 9081                    lsp_request_id,
 9082                    &inlay_hints,
 9083                    query_start..query_end,
 9084                    &mut cx,
 9085                )
 9086                .await
 9087                .context("preparing inlay hints request")?;
 9088                Self::query_lsp_locally::<InlayHints>(
 9089                    lsp_store,
 9090                    server_id,
 9091                    sender_id,
 9092                    lsp_request_id,
 9093                    inlay_hints,
 9094                    None,
 9095                    &mut cx,
 9096                )
 9097                .await
 9098                .context("querying for inlay hints")?
 9099            }
 9100        }
 9101        Ok(proto::Ack {})
 9102    }
 9103
 9104    async fn handle_lsp_query_response(
 9105        lsp_store: Entity<Self>,
 9106        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9107        cx: AsyncApp,
 9108    ) -> Result<()> {
 9109        lsp_store.read_with(&cx, |lsp_store, _| {
 9110            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9111                upstream_client.handle_lsp_response(envelope.clone());
 9112            }
 9113        })?;
 9114        Ok(())
 9115    }
 9116
 9117    async fn handle_apply_code_action(
 9118        this: Entity<Self>,
 9119        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9120        mut cx: AsyncApp,
 9121    ) -> Result<proto::ApplyCodeActionResponse> {
 9122        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9123        let action =
 9124            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9125        let apply_code_action = this.update(&mut cx, |this, cx| {
 9126            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9127            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9128            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9129        })??;
 9130
 9131        let project_transaction = apply_code_action.await?;
 9132        let project_transaction = this.update(&mut cx, |this, cx| {
 9133            this.buffer_store.update(cx, |buffer_store, cx| {
 9134                buffer_store.serialize_project_transaction_for_peer(
 9135                    project_transaction,
 9136                    sender_id,
 9137                    cx,
 9138                )
 9139            })
 9140        })?;
 9141        Ok(proto::ApplyCodeActionResponse {
 9142            transaction: Some(project_transaction),
 9143        })
 9144    }
 9145
 9146    async fn handle_register_buffer_with_language_servers(
 9147        this: Entity<Self>,
 9148        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9149        mut cx: AsyncApp,
 9150    ) -> Result<proto::Ack> {
 9151        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9152        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9153        this.update(&mut cx, |this, cx| {
 9154            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9155                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9156                    project_id: upstream_project_id,
 9157                    buffer_id: buffer_id.to_proto(),
 9158                    only_servers: envelope.payload.only_servers,
 9159                });
 9160            }
 9161
 9162            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9163                anyhow::bail!("buffer is not open");
 9164            };
 9165
 9166            let handle = this.register_buffer_with_language_servers(
 9167                &buffer,
 9168                envelope
 9169                    .payload
 9170                    .only_servers
 9171                    .into_iter()
 9172                    .filter_map(|selector| {
 9173                        Some(match selector.selector? {
 9174                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9175                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9176                            }
 9177                            proto::language_server_selector::Selector::Name(name) => {
 9178                                LanguageServerSelector::Name(LanguageServerName(
 9179                                    SharedString::from(name),
 9180                                ))
 9181                            }
 9182                        })
 9183                    })
 9184                    .collect(),
 9185                false,
 9186                cx,
 9187            );
 9188            this.buffer_store().update(cx, |buffer_store, _| {
 9189                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9190            });
 9191
 9192            Ok(())
 9193        })??;
 9194        Ok(proto::Ack {})
 9195    }
 9196
 9197    async fn handle_rename_project_entry(
 9198        this: Entity<Self>,
 9199        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9200        mut cx: AsyncApp,
 9201    ) -> Result<proto::ProjectEntryResponse> {
 9202        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9203        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9204        let new_path =
 9205            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9206
 9207        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9208            .update(&mut cx, |this, cx| {
 9209                let (worktree, entry) = this
 9210                    .worktree_store
 9211                    .read(cx)
 9212                    .worktree_and_entry_for_id(entry_id, cx)?;
 9213                let new_worktree = this
 9214                    .worktree_store
 9215                    .read(cx)
 9216                    .worktree_for_id(new_worktree_id, cx)?;
 9217                Some((
 9218                    this.worktree_store.clone(),
 9219                    worktree,
 9220                    new_worktree,
 9221                    entry.clone(),
 9222                ))
 9223            })?
 9224            .context("worktree not found")?;
 9225        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9226            (worktree.absolutize(&old_entry.path), worktree.id())
 9227        })?;
 9228        let new_abs_path =
 9229            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 9230
 9231        let _transaction = Self::will_rename_entry(
 9232            this.downgrade(),
 9233            old_worktree_id,
 9234            &old_abs_path,
 9235            &new_abs_path,
 9236            old_entry.is_dir(),
 9237            cx.clone(),
 9238        )
 9239        .await;
 9240        let response = WorktreeStore::handle_rename_project_entry(
 9241            worktree_store,
 9242            envelope.payload,
 9243            cx.clone(),
 9244        )
 9245        .await;
 9246        this.read_with(&cx, |this, _| {
 9247            this.did_rename_entry(
 9248                old_worktree_id,
 9249                &old_abs_path,
 9250                &new_abs_path,
 9251                old_entry.is_dir(),
 9252            );
 9253        })
 9254        .ok();
 9255        response
 9256    }
 9257
 9258    async fn handle_update_diagnostic_summary(
 9259        this: Entity<Self>,
 9260        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9261        mut cx: AsyncApp,
 9262    ) -> Result<()> {
 9263        this.update(&mut cx, |lsp_store, cx| {
 9264            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9265            let mut updated_diagnostics_paths = HashMap::default();
 9266            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9267            for message_summary in envelope
 9268                .payload
 9269                .summary
 9270                .into_iter()
 9271                .chain(envelope.payload.more_summaries)
 9272            {
 9273                let project_path = ProjectPath {
 9274                    worktree_id,
 9275                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9276                };
 9277                let path = project_path.path.clone();
 9278                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9279                let summary = DiagnosticSummary {
 9280                    error_count: message_summary.error_count as usize,
 9281                    warning_count: message_summary.warning_count as usize,
 9282                };
 9283
 9284                if summary.is_empty() {
 9285                    if let Some(worktree_summaries) =
 9286                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9287                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9288                    {
 9289                        summaries.remove(&server_id);
 9290                        if summaries.is_empty() {
 9291                            worktree_summaries.remove(&path);
 9292                        }
 9293                    }
 9294                } else {
 9295                    lsp_store
 9296                        .diagnostic_summaries
 9297                        .entry(worktree_id)
 9298                        .or_default()
 9299                        .entry(path)
 9300                        .or_default()
 9301                        .insert(server_id, summary);
 9302                }
 9303
 9304                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9305                    match &mut diagnostics_summary {
 9306                        Some(diagnostics_summary) => {
 9307                            diagnostics_summary
 9308                                .more_summaries
 9309                                .push(proto::DiagnosticSummary {
 9310                                    path: project_path.path.as_ref().to_proto(),
 9311                                    language_server_id: server_id.0 as u64,
 9312                                    error_count: summary.error_count as u32,
 9313                                    warning_count: summary.warning_count as u32,
 9314                                })
 9315                        }
 9316                        None => {
 9317                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9318                                project_id: *project_id,
 9319                                worktree_id: worktree_id.to_proto(),
 9320                                summary: Some(proto::DiagnosticSummary {
 9321                                    path: project_path.path.as_ref().to_proto(),
 9322                                    language_server_id: server_id.0 as u64,
 9323                                    error_count: summary.error_count as u32,
 9324                                    warning_count: summary.warning_count as u32,
 9325                                }),
 9326                                more_summaries: Vec::new(),
 9327                            })
 9328                        }
 9329                    }
 9330                }
 9331                updated_diagnostics_paths
 9332                    .entry(server_id)
 9333                    .or_insert_with(Vec::new)
 9334                    .push(project_path);
 9335            }
 9336
 9337            if let Some((diagnostics_summary, (downstream_client, _))) =
 9338                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9339            {
 9340                downstream_client.send(diagnostics_summary).log_err();
 9341            }
 9342            for (server_id, paths) in updated_diagnostics_paths {
 9343                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9344            }
 9345            Ok(())
 9346        })?
 9347    }
 9348
 9349    async fn handle_start_language_server(
 9350        lsp_store: Entity<Self>,
 9351        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9352        mut cx: AsyncApp,
 9353    ) -> Result<()> {
 9354        let server = envelope.payload.server.context("invalid server")?;
 9355        let server_capabilities =
 9356            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9357                .with_context(|| {
 9358                    format!(
 9359                        "incorrect server capabilities {}",
 9360                        envelope.payload.capabilities
 9361                    )
 9362                })?;
 9363        lsp_store.update(&mut cx, |lsp_store, cx| {
 9364            let server_id = LanguageServerId(server.id as usize);
 9365            let server_name = LanguageServerName::from_proto(server.name.clone());
 9366            lsp_store
 9367                .lsp_server_capabilities
 9368                .insert(server_id, server_capabilities);
 9369            lsp_store.language_server_statuses.insert(
 9370                server_id,
 9371                LanguageServerStatus {
 9372                    name: server_name.clone(),
 9373                    pending_work: Default::default(),
 9374                    has_pending_diagnostic_updates: false,
 9375                    progress_tokens: Default::default(),
 9376                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9377                    binary: None,
 9378                    configuration: None,
 9379                    workspace_folders: BTreeSet::new(),
 9380                },
 9381            );
 9382            cx.emit(LspStoreEvent::LanguageServerAdded(
 9383                server_id,
 9384                server_name,
 9385                server.worktree_id.map(WorktreeId::from_proto),
 9386            ));
 9387            cx.notify();
 9388        })?;
 9389        Ok(())
 9390    }
 9391
 9392    async fn handle_update_language_server(
 9393        lsp_store: Entity<Self>,
 9394        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9395        mut cx: AsyncApp,
 9396    ) -> Result<()> {
 9397        lsp_store.update(&mut cx, |lsp_store, cx| {
 9398            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9399
 9400            match envelope.payload.variant.context("invalid variant")? {
 9401                proto::update_language_server::Variant::WorkStart(payload) => {
 9402                    lsp_store.on_lsp_work_start(
 9403                        language_server_id,
 9404                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9405                            .context("invalid progress token value")?,
 9406                        LanguageServerProgress {
 9407                            title: payload.title,
 9408                            is_disk_based_diagnostics_progress: false,
 9409                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9410                            message: payload.message,
 9411                            percentage: payload.percentage.map(|p| p as usize),
 9412                            last_update_at: cx.background_executor().now(),
 9413                        },
 9414                        cx,
 9415                    );
 9416                }
 9417                proto::update_language_server::Variant::WorkProgress(payload) => {
 9418                    lsp_store.on_lsp_work_progress(
 9419                        language_server_id,
 9420                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9421                            .context("invalid progress token value")?,
 9422                        LanguageServerProgress {
 9423                            title: None,
 9424                            is_disk_based_diagnostics_progress: false,
 9425                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9426                            message: payload.message,
 9427                            percentage: payload.percentage.map(|p| p as usize),
 9428                            last_update_at: cx.background_executor().now(),
 9429                        },
 9430                        cx,
 9431                    );
 9432                }
 9433
 9434                proto::update_language_server::Variant::WorkEnd(payload) => {
 9435                    lsp_store.on_lsp_work_end(
 9436                        language_server_id,
 9437                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9438                            .context("invalid progress token value")?,
 9439                        cx,
 9440                    );
 9441                }
 9442
 9443                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9444                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9445                }
 9446
 9447                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9448                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9449                }
 9450
 9451                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9452                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9453                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9454                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9455                        language_server_id,
 9456                        name: envelope
 9457                            .payload
 9458                            .server_name
 9459                            .map(SharedString::new)
 9460                            .map(LanguageServerName),
 9461                        message: non_lsp,
 9462                    });
 9463                }
 9464            }
 9465
 9466            Ok(())
 9467        })?
 9468    }
 9469
 9470    async fn handle_language_server_log(
 9471        this: Entity<Self>,
 9472        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9473        mut cx: AsyncApp,
 9474    ) -> Result<()> {
 9475        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9476        let log_type = envelope
 9477            .payload
 9478            .log_type
 9479            .map(LanguageServerLogType::from_proto)
 9480            .context("invalid language server log type")?;
 9481
 9482        let message = envelope.payload.message;
 9483
 9484        this.update(&mut cx, |_, cx| {
 9485            cx.emit(LspStoreEvent::LanguageServerLog(
 9486                language_server_id,
 9487                log_type,
 9488                message,
 9489            ));
 9490        })
 9491    }
 9492
 9493    async fn handle_lsp_ext_cancel_flycheck(
 9494        lsp_store: Entity<Self>,
 9495        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9496        cx: AsyncApp,
 9497    ) -> Result<proto::Ack> {
 9498        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9499        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9500            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9501                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9502            } else {
 9503                None
 9504            }
 9505        })?;
 9506        if let Some(task) = task {
 9507            task.context("handling lsp ext cancel flycheck")?;
 9508        }
 9509
 9510        Ok(proto::Ack {})
 9511    }
 9512
 9513    async fn handle_lsp_ext_run_flycheck(
 9514        lsp_store: Entity<Self>,
 9515        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9516        mut cx: AsyncApp,
 9517    ) -> Result<proto::Ack> {
 9518        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9519        lsp_store.update(&mut cx, |lsp_store, cx| {
 9520            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9521                let text_document = if envelope.payload.current_file_only {
 9522                    let buffer_id = envelope
 9523                        .payload
 9524                        .buffer_id
 9525                        .map(|id| BufferId::new(id))
 9526                        .transpose()?;
 9527                    buffer_id
 9528                        .and_then(|buffer_id| {
 9529                            lsp_store
 9530                                .buffer_store()
 9531                                .read(cx)
 9532                                .get(buffer_id)
 9533                                .and_then(|buffer| {
 9534                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9535                                })
 9536                                .map(|path| make_text_document_identifier(&path))
 9537                        })
 9538                        .transpose()?
 9539                } else {
 9540                    None
 9541                };
 9542                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9543                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9544                )?;
 9545            }
 9546            anyhow::Ok(())
 9547        })??;
 9548
 9549        Ok(proto::Ack {})
 9550    }
 9551
 9552    async fn handle_lsp_ext_clear_flycheck(
 9553        lsp_store: Entity<Self>,
 9554        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9555        cx: AsyncApp,
 9556    ) -> Result<proto::Ack> {
 9557        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9558        lsp_store
 9559            .read_with(&cx, |lsp_store, _| {
 9560                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9561                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9562                } else {
 9563                    None
 9564                }
 9565            })
 9566            .context("handling lsp ext clear flycheck")?;
 9567
 9568        Ok(proto::Ack {})
 9569    }
 9570
 9571    pub fn disk_based_diagnostics_started(
 9572        &mut self,
 9573        language_server_id: LanguageServerId,
 9574        cx: &mut Context<Self>,
 9575    ) {
 9576        if let Some(language_server_status) =
 9577            self.language_server_statuses.get_mut(&language_server_id)
 9578        {
 9579            language_server_status.has_pending_diagnostic_updates = true;
 9580        }
 9581
 9582        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9583        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9584            language_server_id,
 9585            name: self
 9586                .language_server_adapter_for_id(language_server_id)
 9587                .map(|adapter| adapter.name()),
 9588            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9589                Default::default(),
 9590            ),
 9591        })
 9592    }
 9593
 9594    pub fn disk_based_diagnostics_finished(
 9595        &mut self,
 9596        language_server_id: LanguageServerId,
 9597        cx: &mut Context<Self>,
 9598    ) {
 9599        if let Some(language_server_status) =
 9600            self.language_server_statuses.get_mut(&language_server_id)
 9601        {
 9602            language_server_status.has_pending_diagnostic_updates = false;
 9603        }
 9604
 9605        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9606        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9607            language_server_id,
 9608            name: self
 9609                .language_server_adapter_for_id(language_server_id)
 9610                .map(|adapter| adapter.name()),
 9611            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9612                Default::default(),
 9613            ),
 9614        })
 9615    }
 9616
 9617    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9618    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9619    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9620    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9621    // the language server might take some time to publish diagnostics.
 9622    fn simulate_disk_based_diagnostics_events_if_needed(
 9623        &mut self,
 9624        language_server_id: LanguageServerId,
 9625        cx: &mut Context<Self>,
 9626    ) {
 9627        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9628
 9629        let Some(LanguageServerState::Running {
 9630            simulate_disk_based_diagnostics_completion,
 9631            adapter,
 9632            ..
 9633        }) = self
 9634            .as_local_mut()
 9635            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9636        else {
 9637            return;
 9638        };
 9639
 9640        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9641            return;
 9642        }
 9643
 9644        let prev_task =
 9645            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9646                cx.background_executor()
 9647                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9648                    .await;
 9649
 9650                this.update(cx, |this, cx| {
 9651                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9652
 9653                    if let Some(LanguageServerState::Running {
 9654                        simulate_disk_based_diagnostics_completion,
 9655                        ..
 9656                    }) = this.as_local_mut().and_then(|local_store| {
 9657                        local_store.language_servers.get_mut(&language_server_id)
 9658                    }) {
 9659                        *simulate_disk_based_diagnostics_completion = None;
 9660                    }
 9661                })
 9662                .ok();
 9663            }));
 9664
 9665        if prev_task.is_none() {
 9666            self.disk_based_diagnostics_started(language_server_id, cx);
 9667        }
 9668    }
 9669
 9670    pub fn language_server_statuses(
 9671        &self,
 9672    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9673        self.language_server_statuses
 9674            .iter()
 9675            .map(|(key, value)| (*key, value))
 9676    }
 9677
 9678    pub(super) fn did_rename_entry(
 9679        &self,
 9680        worktree_id: WorktreeId,
 9681        old_path: &Path,
 9682        new_path: &Path,
 9683        is_dir: bool,
 9684    ) {
 9685        maybe!({
 9686            let local_store = self.as_local()?;
 9687
 9688            let old_uri = lsp::Uri::from_file_path(old_path)
 9689                .ok()
 9690                .map(|uri| uri.to_string())?;
 9691            let new_uri = lsp::Uri::from_file_path(new_path)
 9692                .ok()
 9693                .map(|uri| uri.to_string())?;
 9694
 9695            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9696                let Some(filter) = local_store
 9697                    .language_server_paths_watched_for_rename
 9698                    .get(&language_server.server_id())
 9699                else {
 9700                    continue;
 9701                };
 9702
 9703                if filter.should_send_did_rename(&old_uri, is_dir) {
 9704                    language_server
 9705                        .notify::<DidRenameFiles>(RenameFilesParams {
 9706                            files: vec![FileRename {
 9707                                old_uri: old_uri.clone(),
 9708                                new_uri: new_uri.clone(),
 9709                            }],
 9710                        })
 9711                        .ok();
 9712                }
 9713            }
 9714            Some(())
 9715        });
 9716    }
 9717
 9718    pub(super) fn will_rename_entry(
 9719        this: WeakEntity<Self>,
 9720        worktree_id: WorktreeId,
 9721        old_path: &Path,
 9722        new_path: &Path,
 9723        is_dir: bool,
 9724        cx: AsyncApp,
 9725    ) -> Task<ProjectTransaction> {
 9726        let old_uri = lsp::Uri::from_file_path(old_path)
 9727            .ok()
 9728            .map(|uri| uri.to_string());
 9729        let new_uri = lsp::Uri::from_file_path(new_path)
 9730            .ok()
 9731            .map(|uri| uri.to_string());
 9732        cx.spawn(async move |cx| {
 9733            let mut tasks = vec![];
 9734            this.update(cx, |this, cx| {
 9735                let local_store = this.as_local()?;
 9736                let old_uri = old_uri?;
 9737                let new_uri = new_uri?;
 9738                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9739                    let Some(filter) = local_store
 9740                        .language_server_paths_watched_for_rename
 9741                        .get(&language_server.server_id())
 9742                    else {
 9743                        continue;
 9744                    };
 9745
 9746                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9747                        let apply_edit = cx.spawn({
 9748                            let old_uri = old_uri.clone();
 9749                            let new_uri = new_uri.clone();
 9750                            let language_server = language_server.clone();
 9751                            async move |this, cx| {
 9752                                let edit = language_server
 9753                                    .request::<WillRenameFiles>(RenameFilesParams {
 9754                                        files: vec![FileRename { old_uri, new_uri }],
 9755                                    })
 9756                                    .await
 9757                                    .into_response()
 9758                                    .context("will rename files")
 9759                                    .log_err()
 9760                                    .flatten()?;
 9761
 9762                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9763                                    this.upgrade()?,
 9764                                    edit,
 9765                                    false,
 9766                                    language_server.clone(),
 9767                                    cx,
 9768                                )
 9769                                .await
 9770                                .ok()?;
 9771                                Some(transaction)
 9772                            }
 9773                        });
 9774                        tasks.push(apply_edit);
 9775                    }
 9776                }
 9777                Some(())
 9778            })
 9779            .ok()
 9780            .flatten();
 9781            let mut merged_transaction = ProjectTransaction::default();
 9782            for task in tasks {
 9783                // Await on tasks sequentially so that the order of application of edits is deterministic
 9784                // (at least with regards to the order of registration of language servers)
 9785                if let Some(transaction) = task.await {
 9786                    for (buffer, buffer_transaction) in transaction.0 {
 9787                        merged_transaction.0.insert(buffer, buffer_transaction);
 9788                    }
 9789                }
 9790            }
 9791            merged_transaction
 9792        })
 9793    }
 9794
 9795    fn lsp_notify_abs_paths_changed(
 9796        &mut self,
 9797        server_id: LanguageServerId,
 9798        changes: Vec<PathEvent>,
 9799    ) {
 9800        maybe!({
 9801            let server = self.language_server_for_id(server_id)?;
 9802            let changes = changes
 9803                .into_iter()
 9804                .filter_map(|event| {
 9805                    let typ = match event.kind? {
 9806                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9807                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9808                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9809                    };
 9810                    Some(lsp::FileEvent {
 9811                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9812                        typ,
 9813                    })
 9814                })
 9815                .collect::<Vec<_>>();
 9816            if !changes.is_empty() {
 9817                server
 9818                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9819                        lsp::DidChangeWatchedFilesParams { changes },
 9820                    )
 9821                    .ok();
 9822            }
 9823            Some(())
 9824        });
 9825    }
 9826
 9827    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9828        self.as_local()?.language_server_for_id(id)
 9829    }
 9830
 9831    fn on_lsp_progress(
 9832        &mut self,
 9833        progress_params: lsp::ProgressParams,
 9834        language_server_id: LanguageServerId,
 9835        disk_based_diagnostics_progress_token: Option<String>,
 9836        cx: &mut Context<Self>,
 9837    ) {
 9838        match progress_params.value {
 9839            lsp::ProgressParamsValue::WorkDone(progress) => {
 9840                self.handle_work_done_progress(
 9841                    progress,
 9842                    language_server_id,
 9843                    disk_based_diagnostics_progress_token,
 9844                    ProgressToken::from_lsp(progress_params.token),
 9845                    cx,
 9846                );
 9847            }
 9848            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9849                let registration_id = match progress_params.token {
 9850                    lsp::NumberOrString::Number(_) => None,
 9851                    lsp::NumberOrString::String(token) => token
 9852                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9853                        .map(|(_, id)| id.to_owned()),
 9854                };
 9855                if let Some(LanguageServerState::Running {
 9856                    workspace_diagnostics_refresh_tasks,
 9857                    ..
 9858                }) = self
 9859                    .as_local_mut()
 9860                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9861                    && let Some(workspace_diagnostics) =
 9862                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9863                {
 9864                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9865                    self.apply_workspace_diagnostic_report(
 9866                        language_server_id,
 9867                        report,
 9868                        registration_id.map(SharedString::from),
 9869                        cx,
 9870                    )
 9871                }
 9872            }
 9873        }
 9874    }
 9875
 9876    fn handle_work_done_progress(
 9877        &mut self,
 9878        progress: lsp::WorkDoneProgress,
 9879        language_server_id: LanguageServerId,
 9880        disk_based_diagnostics_progress_token: Option<String>,
 9881        token: ProgressToken,
 9882        cx: &mut Context<Self>,
 9883    ) {
 9884        let language_server_status =
 9885            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9886                status
 9887            } else {
 9888                return;
 9889            };
 9890
 9891        if !language_server_status.progress_tokens.contains(&token) {
 9892            return;
 9893        }
 9894
 9895        let is_disk_based_diagnostics_progress =
 9896            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9897                (&disk_based_diagnostics_progress_token, &token)
 9898            {
 9899                token.starts_with(disk_based_token)
 9900            } else {
 9901                false
 9902            };
 9903
 9904        match progress {
 9905            lsp::WorkDoneProgress::Begin(report) => {
 9906                if is_disk_based_diagnostics_progress {
 9907                    self.disk_based_diagnostics_started(language_server_id, cx);
 9908                }
 9909                self.on_lsp_work_start(
 9910                    language_server_id,
 9911                    token.clone(),
 9912                    LanguageServerProgress {
 9913                        title: Some(report.title),
 9914                        is_disk_based_diagnostics_progress,
 9915                        is_cancellable: report.cancellable.unwrap_or(false),
 9916                        message: report.message.clone(),
 9917                        percentage: report.percentage.map(|p| p as usize),
 9918                        last_update_at: cx.background_executor().now(),
 9919                    },
 9920                    cx,
 9921                );
 9922            }
 9923            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9924                language_server_id,
 9925                token,
 9926                LanguageServerProgress {
 9927                    title: None,
 9928                    is_disk_based_diagnostics_progress,
 9929                    is_cancellable: report.cancellable.unwrap_or(false),
 9930                    message: report.message,
 9931                    percentage: report.percentage.map(|p| p as usize),
 9932                    last_update_at: cx.background_executor().now(),
 9933                },
 9934                cx,
 9935            ),
 9936            lsp::WorkDoneProgress::End(_) => {
 9937                language_server_status.progress_tokens.remove(&token);
 9938                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9939                if is_disk_based_diagnostics_progress {
 9940                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9941                }
 9942            }
 9943        }
 9944    }
 9945
 9946    fn on_lsp_work_start(
 9947        &mut self,
 9948        language_server_id: LanguageServerId,
 9949        token: ProgressToken,
 9950        progress: LanguageServerProgress,
 9951        cx: &mut Context<Self>,
 9952    ) {
 9953        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9954            status.pending_work.insert(token.clone(), progress.clone());
 9955            cx.notify();
 9956        }
 9957        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9958            language_server_id,
 9959            name: self
 9960                .language_server_adapter_for_id(language_server_id)
 9961                .map(|adapter| adapter.name()),
 9962            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9963                token: Some(token.to_proto()),
 9964                title: progress.title,
 9965                message: progress.message,
 9966                percentage: progress.percentage.map(|p| p as u32),
 9967                is_cancellable: Some(progress.is_cancellable),
 9968            }),
 9969        })
 9970    }
 9971
 9972    fn on_lsp_work_progress(
 9973        &mut self,
 9974        language_server_id: LanguageServerId,
 9975        token: ProgressToken,
 9976        progress: LanguageServerProgress,
 9977        cx: &mut Context<Self>,
 9978    ) {
 9979        let mut did_update = false;
 9980        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9981            match status.pending_work.entry(token.clone()) {
 9982                btree_map::Entry::Vacant(entry) => {
 9983                    entry.insert(progress.clone());
 9984                    did_update = true;
 9985                }
 9986                btree_map::Entry::Occupied(mut entry) => {
 9987                    let entry = entry.get_mut();
 9988                    if (progress.last_update_at - entry.last_update_at)
 9989                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9990                    {
 9991                        entry.last_update_at = progress.last_update_at;
 9992                        if progress.message.is_some() {
 9993                            entry.message = progress.message.clone();
 9994                        }
 9995                        if progress.percentage.is_some() {
 9996                            entry.percentage = progress.percentage;
 9997                        }
 9998                        if progress.is_cancellable != entry.is_cancellable {
 9999                            entry.is_cancellable = progress.is_cancellable;
10000                        }
10001                        did_update = true;
10002                    }
10003                }
10004            }
10005        }
10006
10007        if did_update {
10008            cx.emit(LspStoreEvent::LanguageServerUpdate {
10009                language_server_id,
10010                name: self
10011                    .language_server_adapter_for_id(language_server_id)
10012                    .map(|adapter| adapter.name()),
10013                message: proto::update_language_server::Variant::WorkProgress(
10014                    proto::LspWorkProgress {
10015                        token: Some(token.to_proto()),
10016                        message: progress.message,
10017                        percentage: progress.percentage.map(|p| p as u32),
10018                        is_cancellable: Some(progress.is_cancellable),
10019                    },
10020                ),
10021            })
10022        }
10023    }
10024
10025    fn on_lsp_work_end(
10026        &mut self,
10027        language_server_id: LanguageServerId,
10028        token: ProgressToken,
10029        cx: &mut Context<Self>,
10030    ) {
10031        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10032            if let Some(work) = status.pending_work.remove(&token)
10033                && !work.is_disk_based_diagnostics_progress
10034            {
10035                cx.emit(LspStoreEvent::RefreshInlayHints {
10036                    server_id: language_server_id,
10037                    request_id: None,
10038                });
10039            }
10040            cx.notify();
10041        }
10042
10043        cx.emit(LspStoreEvent::LanguageServerUpdate {
10044            language_server_id,
10045            name: self
10046                .language_server_adapter_for_id(language_server_id)
10047                .map(|adapter| adapter.name()),
10048            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10049                token: Some(token.to_proto()),
10050            }),
10051        })
10052    }
10053
10054    pub async fn handle_resolve_completion_documentation(
10055        this: Entity<Self>,
10056        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10057        mut cx: AsyncApp,
10058    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10059        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10060
10061        let completion = this
10062            .read_with(&cx, |this, cx| {
10063                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10064                let server = this
10065                    .language_server_for_id(id)
10066                    .with_context(|| format!("No language server {id}"))?;
10067
10068                anyhow::Ok(cx.background_spawn(async move {
10069                    let can_resolve = server
10070                        .capabilities()
10071                        .completion_provider
10072                        .as_ref()
10073                        .and_then(|options| options.resolve_provider)
10074                        .unwrap_or(false);
10075                    if can_resolve {
10076                        server
10077                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
10078                            .await
10079                            .into_response()
10080                            .context("resolve completion item")
10081                    } else {
10082                        anyhow::Ok(lsp_completion)
10083                    }
10084                }))
10085            })??
10086            .await?;
10087
10088        let mut documentation_is_markdown = false;
10089        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10090        let documentation = match completion.documentation {
10091            Some(lsp::Documentation::String(text)) => text,
10092
10093            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10094                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10095                value
10096            }
10097
10098            _ => String::new(),
10099        };
10100
10101        // If we have a new buffer_id, that means we're talking to a new client
10102        // and want to check for new text_edits in the completion too.
10103        let mut old_replace_start = None;
10104        let mut old_replace_end = None;
10105        let mut old_insert_start = None;
10106        let mut old_insert_end = None;
10107        let mut new_text = String::default();
10108        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10109            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10110                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10111                anyhow::Ok(buffer.read(cx).snapshot())
10112            })??;
10113
10114            if let Some(text_edit) = completion.text_edit.as_ref() {
10115                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10116
10117                if let Some(mut edit) = edit {
10118                    LineEnding::normalize(&mut edit.new_text);
10119
10120                    new_text = edit.new_text;
10121                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10122                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10123                    if let Some(insert_range) = edit.insert_range {
10124                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10125                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10126                    }
10127                }
10128            }
10129        }
10130
10131        Ok(proto::ResolveCompletionDocumentationResponse {
10132            documentation,
10133            documentation_is_markdown,
10134            old_replace_start,
10135            old_replace_end,
10136            new_text,
10137            lsp_completion,
10138            old_insert_start,
10139            old_insert_end,
10140        })
10141    }
10142
10143    async fn handle_on_type_formatting(
10144        this: Entity<Self>,
10145        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10146        mut cx: AsyncApp,
10147    ) -> Result<proto::OnTypeFormattingResponse> {
10148        let on_type_formatting = this.update(&mut cx, |this, cx| {
10149            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10150            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10151            let position = envelope
10152                .payload
10153                .position
10154                .and_then(deserialize_anchor)
10155                .context("invalid position")?;
10156            anyhow::Ok(this.apply_on_type_formatting(
10157                buffer,
10158                position,
10159                envelope.payload.trigger.clone(),
10160                cx,
10161            ))
10162        })??;
10163
10164        let transaction = on_type_formatting
10165            .await?
10166            .as_ref()
10167            .map(language::proto::serialize_transaction);
10168        Ok(proto::OnTypeFormattingResponse { transaction })
10169    }
10170
10171    async fn handle_refresh_inlay_hints(
10172        lsp_store: Entity<Self>,
10173        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10174        mut cx: AsyncApp,
10175    ) -> Result<proto::Ack> {
10176        lsp_store.update(&mut cx, |_, cx| {
10177            cx.emit(LspStoreEvent::RefreshInlayHints {
10178                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10179                request_id: envelope.payload.request_id.map(|id| id as usize),
10180            });
10181        })?;
10182        Ok(proto::Ack {})
10183    }
10184
10185    async fn handle_pull_workspace_diagnostics(
10186        lsp_store: Entity<Self>,
10187        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10188        mut cx: AsyncApp,
10189    ) -> Result<proto::Ack> {
10190        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10191        lsp_store.update(&mut cx, |lsp_store, _| {
10192            lsp_store.pull_workspace_diagnostics(server_id);
10193        })?;
10194        Ok(proto::Ack {})
10195    }
10196
10197    async fn handle_get_color_presentation(
10198        lsp_store: Entity<Self>,
10199        envelope: TypedEnvelope<proto::GetColorPresentation>,
10200        mut cx: AsyncApp,
10201    ) -> Result<proto::GetColorPresentationResponse> {
10202        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10203        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10204            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10205        })??;
10206
10207        let color = envelope
10208            .payload
10209            .color
10210            .context("invalid color resolve request")?;
10211        let start = color
10212            .lsp_range_start
10213            .context("invalid color resolve request")?;
10214        let end = color
10215            .lsp_range_end
10216            .context("invalid color resolve request")?;
10217
10218        let color = DocumentColor {
10219            lsp_range: lsp::Range {
10220                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10221                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10222            },
10223            color: lsp::Color {
10224                red: color.red,
10225                green: color.green,
10226                blue: color.blue,
10227                alpha: color.alpha,
10228            },
10229            resolved: false,
10230            color_presentations: Vec::new(),
10231        };
10232        let resolved_color = lsp_store
10233            .update(&mut cx, |lsp_store, cx| {
10234                lsp_store.resolve_color_presentation(
10235                    color,
10236                    buffer.clone(),
10237                    LanguageServerId(envelope.payload.server_id as usize),
10238                    cx,
10239                )
10240            })?
10241            .await
10242            .context("resolving color presentation")?;
10243
10244        Ok(proto::GetColorPresentationResponse {
10245            presentations: resolved_color
10246                .color_presentations
10247                .into_iter()
10248                .map(|presentation| proto::ColorPresentation {
10249                    label: presentation.label.to_string(),
10250                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10251                    additional_text_edits: presentation
10252                        .additional_text_edits
10253                        .into_iter()
10254                        .map(serialize_lsp_edit)
10255                        .collect(),
10256                })
10257                .collect(),
10258        })
10259    }
10260
10261    async fn handle_resolve_inlay_hint(
10262        lsp_store: Entity<Self>,
10263        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10264        mut cx: AsyncApp,
10265    ) -> Result<proto::ResolveInlayHintResponse> {
10266        let proto_hint = envelope
10267            .payload
10268            .hint
10269            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10270        let hint = InlayHints::proto_to_project_hint(proto_hint)
10271            .context("resolved proto inlay hint conversion")?;
10272        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10273            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10274            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10275        })??;
10276        let response_hint = lsp_store
10277            .update(&mut cx, |lsp_store, cx| {
10278                lsp_store.resolve_inlay_hint(
10279                    hint,
10280                    buffer,
10281                    LanguageServerId(envelope.payload.language_server_id as usize),
10282                    cx,
10283                )
10284            })?
10285            .await
10286            .context("inlay hints fetch")?;
10287        Ok(proto::ResolveInlayHintResponse {
10288            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10289        })
10290    }
10291
10292    async fn handle_refresh_code_lens(
10293        this: Entity<Self>,
10294        _: TypedEnvelope<proto::RefreshCodeLens>,
10295        mut cx: AsyncApp,
10296    ) -> Result<proto::Ack> {
10297        this.update(&mut cx, |_, cx| {
10298            cx.emit(LspStoreEvent::RefreshCodeLens);
10299        })?;
10300        Ok(proto::Ack {})
10301    }
10302
10303    async fn handle_open_buffer_for_symbol(
10304        this: Entity<Self>,
10305        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10306        mut cx: AsyncApp,
10307    ) -> Result<proto::OpenBufferForSymbolResponse> {
10308        let peer_id = envelope.original_sender_id().unwrap_or_default();
10309        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10310        let symbol = Self::deserialize_symbol(symbol)?;
10311        this.read_with(&cx, |this, _| {
10312            if let SymbolLocation::OutsideProject {
10313                abs_path,
10314                signature,
10315            } = &symbol.path
10316            {
10317                let new_signature = this.symbol_signature(&abs_path);
10318                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10319            }
10320            Ok(())
10321        })??;
10322        let buffer = this
10323            .update(&mut cx, |this, cx| {
10324                this.open_buffer_for_symbol(
10325                    &Symbol {
10326                        language_server_name: symbol.language_server_name,
10327                        source_worktree_id: symbol.source_worktree_id,
10328                        source_language_server_id: symbol.source_language_server_id,
10329                        path: symbol.path,
10330                        name: symbol.name,
10331                        kind: symbol.kind,
10332                        range: symbol.range,
10333                        label: CodeLabel::default(),
10334                    },
10335                    cx,
10336                )
10337            })?
10338            .await?;
10339
10340        this.update(&mut cx, |this, cx| {
10341            let is_private = buffer
10342                .read(cx)
10343                .file()
10344                .map(|f| f.is_private())
10345                .unwrap_or_default();
10346            if is_private {
10347                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10348            } else {
10349                this.buffer_store
10350                    .update(cx, |buffer_store, cx| {
10351                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10352                    })
10353                    .detach_and_log_err(cx);
10354                let buffer_id = buffer.read(cx).remote_id().to_proto();
10355                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10356            }
10357        })?
10358    }
10359
10360    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10361        let mut hasher = Sha256::new();
10362        hasher.update(abs_path.to_string_lossy().as_bytes());
10363        hasher.update(self.nonce.to_be_bytes());
10364        hasher.finalize().as_slice().try_into().unwrap()
10365    }
10366
10367    pub async fn handle_get_project_symbols(
10368        this: Entity<Self>,
10369        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10370        mut cx: AsyncApp,
10371    ) -> Result<proto::GetProjectSymbolsResponse> {
10372        let symbols = this
10373            .update(&mut cx, |this, cx| {
10374                this.symbols(&envelope.payload.query, cx)
10375            })?
10376            .await?;
10377
10378        Ok(proto::GetProjectSymbolsResponse {
10379            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10380        })
10381    }
10382
10383    pub async fn handle_restart_language_servers(
10384        this: Entity<Self>,
10385        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10386        mut cx: AsyncApp,
10387    ) -> Result<proto::Ack> {
10388        this.update(&mut cx, |lsp_store, cx| {
10389            let buffers =
10390                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10391            lsp_store.restart_language_servers_for_buffers(
10392                buffers,
10393                envelope
10394                    .payload
10395                    .only_servers
10396                    .into_iter()
10397                    .filter_map(|selector| {
10398                        Some(match selector.selector? {
10399                            proto::language_server_selector::Selector::ServerId(server_id) => {
10400                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10401                            }
10402                            proto::language_server_selector::Selector::Name(name) => {
10403                                LanguageServerSelector::Name(LanguageServerName(
10404                                    SharedString::from(name),
10405                                ))
10406                            }
10407                        })
10408                    })
10409                    .collect(),
10410                cx,
10411            );
10412        })?;
10413
10414        Ok(proto::Ack {})
10415    }
10416
10417    pub async fn handle_stop_language_servers(
10418        lsp_store: Entity<Self>,
10419        envelope: TypedEnvelope<proto::StopLanguageServers>,
10420        mut cx: AsyncApp,
10421    ) -> Result<proto::Ack> {
10422        lsp_store.update(&mut cx, |lsp_store, cx| {
10423            if envelope.payload.all
10424                && envelope.payload.also_servers.is_empty()
10425                && envelope.payload.buffer_ids.is_empty()
10426            {
10427                lsp_store.stop_all_language_servers(cx);
10428            } else {
10429                let buffers =
10430                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10431                lsp_store
10432                    .stop_language_servers_for_buffers(
10433                        buffers,
10434                        envelope
10435                            .payload
10436                            .also_servers
10437                            .into_iter()
10438                            .filter_map(|selector| {
10439                                Some(match selector.selector? {
10440                                    proto::language_server_selector::Selector::ServerId(
10441                                        server_id,
10442                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10443                                        server_id,
10444                                    )),
10445                                    proto::language_server_selector::Selector::Name(name) => {
10446                                        LanguageServerSelector::Name(LanguageServerName(
10447                                            SharedString::from(name),
10448                                        ))
10449                                    }
10450                                })
10451                            })
10452                            .collect(),
10453                        cx,
10454                    )
10455                    .detach_and_log_err(cx);
10456            }
10457        })?;
10458
10459        Ok(proto::Ack {})
10460    }
10461
10462    pub async fn handle_cancel_language_server_work(
10463        lsp_store: Entity<Self>,
10464        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10465        mut cx: AsyncApp,
10466    ) -> Result<proto::Ack> {
10467        lsp_store.update(&mut cx, |lsp_store, cx| {
10468            if let Some(work) = envelope.payload.work {
10469                match work {
10470                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10471                        let buffers =
10472                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10473                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10474                    }
10475                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10476                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10477                        let token = work
10478                            .token
10479                            .map(|token| {
10480                                ProgressToken::from_proto(token)
10481                                    .context("invalid work progress token")
10482                            })
10483                            .transpose()?;
10484                        lsp_store.cancel_language_server_work(server_id, token, cx);
10485                    }
10486                }
10487            }
10488            anyhow::Ok(())
10489        })??;
10490
10491        Ok(proto::Ack {})
10492    }
10493
10494    fn buffer_ids_to_buffers(
10495        &mut self,
10496        buffer_ids: impl Iterator<Item = u64>,
10497        cx: &mut Context<Self>,
10498    ) -> Vec<Entity<Buffer>> {
10499        buffer_ids
10500            .into_iter()
10501            .flat_map(|buffer_id| {
10502                self.buffer_store
10503                    .read(cx)
10504                    .get(BufferId::new(buffer_id).log_err()?)
10505            })
10506            .collect::<Vec<_>>()
10507    }
10508
10509    async fn handle_apply_additional_edits_for_completion(
10510        this: Entity<Self>,
10511        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10512        mut cx: AsyncApp,
10513    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10514        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10515            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10516            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10517            let completion = Self::deserialize_completion(
10518                envelope.payload.completion.context("invalid completion")?,
10519            )?;
10520            anyhow::Ok((buffer, completion))
10521        })??;
10522
10523        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10524            this.apply_additional_edits_for_completion(
10525                buffer,
10526                Rc::new(RefCell::new(Box::new([Completion {
10527                    replace_range: completion.replace_range,
10528                    new_text: completion.new_text,
10529                    source: completion.source,
10530                    documentation: None,
10531                    label: CodeLabel::default(),
10532                    match_start: None,
10533                    snippet_deduplication_key: None,
10534                    insert_text_mode: None,
10535                    icon_path: None,
10536                    confirm: None,
10537                }]))),
10538                0,
10539                false,
10540                cx,
10541            )
10542        })?;
10543
10544        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10545            transaction: apply_additional_edits
10546                .await?
10547                .as_ref()
10548                .map(language::proto::serialize_transaction),
10549        })
10550    }
10551
10552    pub fn last_formatting_failure(&self) -> Option<&str> {
10553        self.last_formatting_failure.as_deref()
10554    }
10555
10556    pub fn reset_last_formatting_failure(&mut self) {
10557        self.last_formatting_failure = None;
10558    }
10559
10560    pub fn environment_for_buffer(
10561        &self,
10562        buffer: &Entity<Buffer>,
10563        cx: &mut Context<Self>,
10564    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10565        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10566            environment.update(cx, |env, cx| {
10567                env.buffer_environment(buffer, &self.worktree_store, cx)
10568            })
10569        } else {
10570            Task::ready(None).shared()
10571        }
10572    }
10573
10574    pub fn format(
10575        &mut self,
10576        buffers: HashSet<Entity<Buffer>>,
10577        target: LspFormatTarget,
10578        push_to_history: bool,
10579        trigger: FormatTrigger,
10580        cx: &mut Context<Self>,
10581    ) -> Task<anyhow::Result<ProjectTransaction>> {
10582        let logger = zlog::scoped!("format");
10583        if self.as_local().is_some() {
10584            zlog::trace!(logger => "Formatting locally");
10585            let logger = zlog::scoped!(logger => "local");
10586            let buffers = buffers
10587                .into_iter()
10588                .map(|buffer_handle| {
10589                    let buffer = buffer_handle.read(cx);
10590                    let buffer_abs_path = File::from_dyn(buffer.file())
10591                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10592
10593                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10594                })
10595                .collect::<Vec<_>>();
10596
10597            cx.spawn(async move |lsp_store, cx| {
10598                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10599
10600                for (handle, abs_path, id) in buffers {
10601                    let env = lsp_store
10602                        .update(cx, |lsp_store, cx| {
10603                            lsp_store.environment_for_buffer(&handle, cx)
10604                        })?
10605                        .await;
10606
10607                    let ranges = match &target {
10608                        LspFormatTarget::Buffers => None,
10609                        LspFormatTarget::Ranges(ranges) => {
10610                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10611                        }
10612                    };
10613
10614                    formattable_buffers.push(FormattableBuffer {
10615                        handle,
10616                        abs_path,
10617                        env,
10618                        ranges,
10619                    });
10620                }
10621                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10622
10623                let format_timer = zlog::time!(logger => "Formatting buffers");
10624                let result = LocalLspStore::format_locally(
10625                    lsp_store.clone(),
10626                    formattable_buffers,
10627                    push_to_history,
10628                    trigger,
10629                    logger,
10630                    cx,
10631                )
10632                .await;
10633                format_timer.end();
10634
10635                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10636
10637                lsp_store.update(cx, |lsp_store, _| {
10638                    lsp_store.update_last_formatting_failure(&result);
10639                })?;
10640
10641                result
10642            })
10643        } else if let Some((client, project_id)) = self.upstream_client() {
10644            zlog::trace!(logger => "Formatting remotely");
10645            let logger = zlog::scoped!(logger => "remote");
10646            // Don't support formatting ranges via remote
10647            match target {
10648                LspFormatTarget::Buffers => {}
10649                LspFormatTarget::Ranges(_) => {
10650                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10651                    return Task::ready(Ok(ProjectTransaction::default()));
10652                }
10653            }
10654
10655            let buffer_store = self.buffer_store();
10656            cx.spawn(async move |lsp_store, cx| {
10657                zlog::trace!(logger => "Sending remote format request");
10658                let request_timer = zlog::time!(logger => "remote format request");
10659                let result = client
10660                    .request(proto::FormatBuffers {
10661                        project_id,
10662                        trigger: trigger as i32,
10663                        buffer_ids: buffers
10664                            .iter()
10665                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10666                            .collect::<Result<_>>()?,
10667                    })
10668                    .await
10669                    .and_then(|result| result.transaction.context("missing transaction"));
10670                request_timer.end();
10671
10672                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10673
10674                lsp_store.update(cx, |lsp_store, _| {
10675                    lsp_store.update_last_formatting_failure(&result);
10676                })?;
10677
10678                let transaction_response = result?;
10679                let _timer = zlog::time!(logger => "deserializing project transaction");
10680                buffer_store
10681                    .update(cx, |buffer_store, cx| {
10682                        buffer_store.deserialize_project_transaction(
10683                            transaction_response,
10684                            push_to_history,
10685                            cx,
10686                        )
10687                    })?
10688                    .await
10689            })
10690        } else {
10691            zlog::trace!(logger => "Not formatting");
10692            Task::ready(Ok(ProjectTransaction::default()))
10693        }
10694    }
10695
10696    async fn handle_format_buffers(
10697        this: Entity<Self>,
10698        envelope: TypedEnvelope<proto::FormatBuffers>,
10699        mut cx: AsyncApp,
10700    ) -> Result<proto::FormatBuffersResponse> {
10701        let sender_id = envelope.original_sender_id().unwrap_or_default();
10702        let format = this.update(&mut cx, |this, cx| {
10703            let mut buffers = HashSet::default();
10704            for buffer_id in &envelope.payload.buffer_ids {
10705                let buffer_id = BufferId::new(*buffer_id)?;
10706                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10707            }
10708            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10709            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10710        })??;
10711
10712        let project_transaction = format.await?;
10713        let project_transaction = this.update(&mut cx, |this, cx| {
10714            this.buffer_store.update(cx, |buffer_store, cx| {
10715                buffer_store.serialize_project_transaction_for_peer(
10716                    project_transaction,
10717                    sender_id,
10718                    cx,
10719                )
10720            })
10721        })?;
10722        Ok(proto::FormatBuffersResponse {
10723            transaction: Some(project_transaction),
10724        })
10725    }
10726
10727    async fn handle_apply_code_action_kind(
10728        this: Entity<Self>,
10729        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10730        mut cx: AsyncApp,
10731    ) -> Result<proto::ApplyCodeActionKindResponse> {
10732        let sender_id = envelope.original_sender_id().unwrap_or_default();
10733        let format = this.update(&mut cx, |this, cx| {
10734            let mut buffers = HashSet::default();
10735            for buffer_id in &envelope.payload.buffer_ids {
10736                let buffer_id = BufferId::new(*buffer_id)?;
10737                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10738            }
10739            let kind = match envelope.payload.kind.as_str() {
10740                "" => CodeActionKind::EMPTY,
10741                "quickfix" => CodeActionKind::QUICKFIX,
10742                "refactor" => CodeActionKind::REFACTOR,
10743                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10744                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10745                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10746                "source" => CodeActionKind::SOURCE,
10747                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10748                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10749                _ => anyhow::bail!(
10750                    "Invalid code action kind {}",
10751                    envelope.payload.kind.as_str()
10752                ),
10753            };
10754            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10755        })??;
10756
10757        let project_transaction = format.await?;
10758        let project_transaction = this.update(&mut cx, |this, cx| {
10759            this.buffer_store.update(cx, |buffer_store, cx| {
10760                buffer_store.serialize_project_transaction_for_peer(
10761                    project_transaction,
10762                    sender_id,
10763                    cx,
10764                )
10765            })
10766        })?;
10767        Ok(proto::ApplyCodeActionKindResponse {
10768            transaction: Some(project_transaction),
10769        })
10770    }
10771
10772    async fn shutdown_language_server(
10773        server_state: Option<LanguageServerState>,
10774        name: LanguageServerName,
10775        cx: &mut AsyncApp,
10776    ) {
10777        let server = match server_state {
10778            Some(LanguageServerState::Starting { startup, .. }) => {
10779                let mut timer = cx
10780                    .background_executor()
10781                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10782                    .fuse();
10783
10784                select! {
10785                    server = startup.fuse() => server,
10786                    () = timer => {
10787                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10788                        None
10789                    },
10790                }
10791            }
10792
10793            Some(LanguageServerState::Running { server, .. }) => Some(server),
10794
10795            None => None,
10796        };
10797
10798        if let Some(server) = server
10799            && let Some(shutdown) = server.shutdown()
10800        {
10801            shutdown.await;
10802        }
10803    }
10804
10805    // Returns a list of all of the worktrees which no longer have a language server and the root path
10806    // for the stopped server
10807    fn stop_local_language_server(
10808        &mut self,
10809        server_id: LanguageServerId,
10810        cx: &mut Context<Self>,
10811    ) -> Task<()> {
10812        let local = match &mut self.mode {
10813            LspStoreMode::Local(local) => local,
10814            _ => {
10815                return Task::ready(());
10816            }
10817        };
10818
10819        // Remove this server ID from all entries in the given worktree.
10820        local
10821            .language_server_ids
10822            .retain(|_, state| state.id != server_id);
10823        self.buffer_store.update(cx, |buffer_store, cx| {
10824            for buffer in buffer_store.buffers() {
10825                buffer.update(cx, |buffer, cx| {
10826                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10827                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10828                });
10829            }
10830        });
10831
10832        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10833            summaries.retain(|path, summaries_by_server_id| {
10834                if summaries_by_server_id.remove(&server_id).is_some() {
10835                    if let Some((client, project_id)) = self.downstream_client.clone() {
10836                        client
10837                            .send(proto::UpdateDiagnosticSummary {
10838                                project_id,
10839                                worktree_id: worktree_id.to_proto(),
10840                                summary: Some(proto::DiagnosticSummary {
10841                                    path: path.as_ref().to_proto(),
10842                                    language_server_id: server_id.0 as u64,
10843                                    error_count: 0,
10844                                    warning_count: 0,
10845                                }),
10846                                more_summaries: Vec::new(),
10847                            })
10848                            .log_err();
10849                    }
10850                    !summaries_by_server_id.is_empty()
10851                } else {
10852                    true
10853                }
10854            });
10855        }
10856
10857        let local = self.as_local_mut().unwrap();
10858        for diagnostics in local.diagnostics.values_mut() {
10859            diagnostics.retain(|_, diagnostics_by_server_id| {
10860                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10861                    diagnostics_by_server_id.remove(ix);
10862                    !diagnostics_by_server_id.is_empty()
10863                } else {
10864                    true
10865                }
10866            });
10867        }
10868        local.language_server_watched_paths.remove(&server_id);
10869
10870        let server_state = local.language_servers.remove(&server_id);
10871        self.cleanup_lsp_data(server_id);
10872        let name = self
10873            .language_server_statuses
10874            .remove(&server_id)
10875            .map(|status| status.name)
10876            .or_else(|| {
10877                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10878                    Some(adapter.name())
10879                } else {
10880                    None
10881                }
10882            });
10883
10884        if let Some(name) = name {
10885            log::info!("stopping language server {name}");
10886            self.languages
10887                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10888            cx.notify();
10889
10890            return cx.spawn(async move |lsp_store, cx| {
10891                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10892                lsp_store
10893                    .update(cx, |lsp_store, cx| {
10894                        lsp_store
10895                            .languages
10896                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10897                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10898                        cx.notify();
10899                    })
10900                    .ok();
10901            });
10902        }
10903
10904        if server_state.is_some() {
10905            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10906        }
10907        Task::ready(())
10908    }
10909
10910    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10911        if let Some((client, project_id)) = self.upstream_client() {
10912            let request = client.request(proto::StopLanguageServers {
10913                project_id,
10914                buffer_ids: Vec::new(),
10915                also_servers: Vec::new(),
10916                all: true,
10917            });
10918            cx.background_spawn(request).detach_and_log_err(cx);
10919        } else {
10920            let Some(local) = self.as_local_mut() else {
10921                return;
10922            };
10923            let language_servers_to_stop = local
10924                .language_server_ids
10925                .values()
10926                .map(|state| state.id)
10927                .collect();
10928            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10929            let tasks = language_servers_to_stop
10930                .into_iter()
10931                .map(|server| self.stop_local_language_server(server, cx))
10932                .collect::<Vec<_>>();
10933            cx.background_spawn(async move {
10934                futures::future::join_all(tasks).await;
10935            })
10936            .detach();
10937        }
10938    }
10939
10940    pub fn restart_language_servers_for_buffers(
10941        &mut self,
10942        buffers: Vec<Entity<Buffer>>,
10943        only_restart_servers: HashSet<LanguageServerSelector>,
10944        cx: &mut Context<Self>,
10945    ) {
10946        if let Some((client, project_id)) = self.upstream_client() {
10947            let request = client.request(proto::RestartLanguageServers {
10948                project_id,
10949                buffer_ids: buffers
10950                    .into_iter()
10951                    .map(|b| b.read(cx).remote_id().to_proto())
10952                    .collect(),
10953                only_servers: only_restart_servers
10954                    .into_iter()
10955                    .map(|selector| {
10956                        let selector = match selector {
10957                            LanguageServerSelector::Id(language_server_id) => {
10958                                proto::language_server_selector::Selector::ServerId(
10959                                    language_server_id.to_proto(),
10960                                )
10961                            }
10962                            LanguageServerSelector::Name(language_server_name) => {
10963                                proto::language_server_selector::Selector::Name(
10964                                    language_server_name.to_string(),
10965                                )
10966                            }
10967                        };
10968                        proto::LanguageServerSelector {
10969                            selector: Some(selector),
10970                        }
10971                    })
10972                    .collect(),
10973                all: false,
10974            });
10975            cx.background_spawn(request).detach_and_log_err(cx);
10976        } else {
10977            let stop_task = if only_restart_servers.is_empty() {
10978                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10979            } else {
10980                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10981            };
10982            cx.spawn(async move |lsp_store, cx| {
10983                stop_task.await;
10984                lsp_store
10985                    .update(cx, |lsp_store, cx| {
10986                        for buffer in buffers {
10987                            lsp_store.register_buffer_with_language_servers(
10988                                &buffer,
10989                                only_restart_servers.clone(),
10990                                true,
10991                                cx,
10992                            );
10993                        }
10994                    })
10995                    .ok()
10996            })
10997            .detach();
10998        }
10999    }
11000
11001    pub fn stop_language_servers_for_buffers(
11002        &mut self,
11003        buffers: Vec<Entity<Buffer>>,
11004        also_stop_servers: HashSet<LanguageServerSelector>,
11005        cx: &mut Context<Self>,
11006    ) -> Task<Result<()>> {
11007        if let Some((client, project_id)) = self.upstream_client() {
11008            let request = client.request(proto::StopLanguageServers {
11009                project_id,
11010                buffer_ids: buffers
11011                    .into_iter()
11012                    .map(|b| b.read(cx).remote_id().to_proto())
11013                    .collect(),
11014                also_servers: also_stop_servers
11015                    .into_iter()
11016                    .map(|selector| {
11017                        let selector = match selector {
11018                            LanguageServerSelector::Id(language_server_id) => {
11019                                proto::language_server_selector::Selector::ServerId(
11020                                    language_server_id.to_proto(),
11021                                )
11022                            }
11023                            LanguageServerSelector::Name(language_server_name) => {
11024                                proto::language_server_selector::Selector::Name(
11025                                    language_server_name.to_string(),
11026                                )
11027                            }
11028                        };
11029                        proto::LanguageServerSelector {
11030                            selector: Some(selector),
11031                        }
11032                    })
11033                    .collect(),
11034                all: false,
11035            });
11036            cx.background_spawn(async move {
11037                let _ = request.await?;
11038                Ok(())
11039            })
11040        } else {
11041            let task =
11042                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11043            cx.background_spawn(async move {
11044                task.await;
11045                Ok(())
11046            })
11047        }
11048    }
11049
11050    fn stop_local_language_servers_for_buffers(
11051        &mut self,
11052        buffers: &[Entity<Buffer>],
11053        also_stop_servers: HashSet<LanguageServerSelector>,
11054        cx: &mut Context<Self>,
11055    ) -> Task<()> {
11056        let Some(local) = self.as_local_mut() else {
11057            return Task::ready(());
11058        };
11059        let mut language_server_names_to_stop = BTreeSet::default();
11060        let mut language_servers_to_stop = also_stop_servers
11061            .into_iter()
11062            .flat_map(|selector| match selector {
11063                LanguageServerSelector::Id(id) => Some(id),
11064                LanguageServerSelector::Name(name) => {
11065                    language_server_names_to_stop.insert(name);
11066                    None
11067                }
11068            })
11069            .collect::<BTreeSet<_>>();
11070
11071        let mut covered_worktrees = HashSet::default();
11072        for buffer in buffers {
11073            buffer.update(cx, |buffer, cx| {
11074                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11075                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11076                    && covered_worktrees.insert(worktree_id)
11077                {
11078                    language_server_names_to_stop.retain(|name| {
11079                        let old_ids_count = language_servers_to_stop.len();
11080                        let all_language_servers_with_this_name = local
11081                            .language_server_ids
11082                            .iter()
11083                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11084                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11085                        old_ids_count == language_servers_to_stop.len()
11086                    });
11087                }
11088            });
11089        }
11090        for name in language_server_names_to_stop {
11091            language_servers_to_stop.extend(
11092                local
11093                    .language_server_ids
11094                    .iter()
11095                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11096            );
11097        }
11098
11099        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11100        let tasks = language_servers_to_stop
11101            .into_iter()
11102            .map(|server| self.stop_local_language_server(server, cx))
11103            .collect::<Vec<_>>();
11104
11105        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11106    }
11107
11108    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11109        let (worktree, relative_path) =
11110            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11111
11112        let project_path = ProjectPath {
11113            worktree_id: worktree.read(cx).id(),
11114            path: relative_path,
11115        };
11116
11117        Some(
11118            self.buffer_store()
11119                .read(cx)
11120                .get_by_path(&project_path)?
11121                .read(cx),
11122        )
11123    }
11124
11125    #[cfg(any(test, feature = "test-support"))]
11126    pub fn update_diagnostics(
11127        &mut self,
11128        server_id: LanguageServerId,
11129        diagnostics: lsp::PublishDiagnosticsParams,
11130        result_id: Option<SharedString>,
11131        source_kind: DiagnosticSourceKind,
11132        disk_based_sources: &[String],
11133        cx: &mut Context<Self>,
11134    ) -> Result<()> {
11135        self.merge_lsp_diagnostics(
11136            source_kind,
11137            vec![DocumentDiagnosticsUpdate {
11138                diagnostics,
11139                result_id,
11140                server_id,
11141                disk_based_sources: Cow::Borrowed(disk_based_sources),
11142                registration_id: None,
11143            }],
11144            |_, _, _| false,
11145            cx,
11146        )
11147    }
11148
11149    pub fn merge_lsp_diagnostics(
11150        &mut self,
11151        source_kind: DiagnosticSourceKind,
11152        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11153        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11154        cx: &mut Context<Self>,
11155    ) -> Result<()> {
11156        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11157        let updates = lsp_diagnostics
11158            .into_iter()
11159            .filter_map(|update| {
11160                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11161                Some(DocumentDiagnosticsUpdate {
11162                    diagnostics: self.lsp_to_document_diagnostics(
11163                        abs_path,
11164                        source_kind,
11165                        update.server_id,
11166                        update.diagnostics,
11167                        &update.disk_based_sources,
11168                        update.registration_id.clone(),
11169                    ),
11170                    result_id: update.result_id,
11171                    server_id: update.server_id,
11172                    disk_based_sources: update.disk_based_sources,
11173                    registration_id: update.registration_id,
11174                })
11175            })
11176            .collect();
11177        self.merge_diagnostic_entries(updates, merge, cx)?;
11178        Ok(())
11179    }
11180
11181    fn lsp_to_document_diagnostics(
11182        &mut self,
11183        document_abs_path: PathBuf,
11184        source_kind: DiagnosticSourceKind,
11185        server_id: LanguageServerId,
11186        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11187        disk_based_sources: &[String],
11188        registration_id: Option<SharedString>,
11189    ) -> DocumentDiagnostics {
11190        let mut diagnostics = Vec::default();
11191        let mut primary_diagnostic_group_ids = HashMap::default();
11192        let mut sources_by_group_id = HashMap::default();
11193        let mut supporting_diagnostics = HashMap::default();
11194
11195        let adapter = self.language_server_adapter_for_id(server_id);
11196
11197        // Ensure that primary diagnostics are always the most severe
11198        lsp_diagnostics
11199            .diagnostics
11200            .sort_by_key(|item| item.severity);
11201
11202        for diagnostic in &lsp_diagnostics.diagnostics {
11203            let source = diagnostic.source.as_ref();
11204            let range = range_from_lsp(diagnostic.range);
11205            let is_supporting = diagnostic
11206                .related_information
11207                .as_ref()
11208                .is_some_and(|infos| {
11209                    infos.iter().any(|info| {
11210                        primary_diagnostic_group_ids.contains_key(&(
11211                            source,
11212                            diagnostic.code.clone(),
11213                            range_from_lsp(info.location.range),
11214                        ))
11215                    })
11216                });
11217
11218            let is_unnecessary = diagnostic
11219                .tags
11220                .as_ref()
11221                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11222
11223            let underline = self
11224                .language_server_adapter_for_id(server_id)
11225                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11226
11227            if is_supporting {
11228                supporting_diagnostics.insert(
11229                    (source, diagnostic.code.clone(), range),
11230                    (diagnostic.severity, is_unnecessary),
11231                );
11232            } else {
11233                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11234                let is_disk_based =
11235                    source.is_some_and(|source| disk_based_sources.contains(source));
11236
11237                sources_by_group_id.insert(group_id, source);
11238                primary_diagnostic_group_ids
11239                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11240
11241                diagnostics.push(DiagnosticEntry {
11242                    range,
11243                    diagnostic: Diagnostic {
11244                        source: diagnostic.source.clone(),
11245                        source_kind,
11246                        code: diagnostic.code.clone(),
11247                        code_description: diagnostic
11248                            .code_description
11249                            .as_ref()
11250                            .and_then(|d| d.href.clone()),
11251                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11252                        markdown: adapter.as_ref().and_then(|adapter| {
11253                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11254                        }),
11255                        message: diagnostic.message.trim().to_string(),
11256                        group_id,
11257                        is_primary: true,
11258                        is_disk_based,
11259                        is_unnecessary,
11260                        underline,
11261                        data: diagnostic.data.clone(),
11262                        registration_id: registration_id.clone(),
11263                    },
11264                });
11265                if let Some(infos) = &diagnostic.related_information {
11266                    for info in infos {
11267                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11268                            let range = range_from_lsp(info.location.range);
11269                            diagnostics.push(DiagnosticEntry {
11270                                range,
11271                                diagnostic: Diagnostic {
11272                                    source: diagnostic.source.clone(),
11273                                    source_kind,
11274                                    code: diagnostic.code.clone(),
11275                                    code_description: diagnostic
11276                                        .code_description
11277                                        .as_ref()
11278                                        .and_then(|d| d.href.clone()),
11279                                    severity: DiagnosticSeverity::INFORMATION,
11280                                    markdown: adapter.as_ref().and_then(|adapter| {
11281                                        adapter.diagnostic_message_to_markdown(&info.message)
11282                                    }),
11283                                    message: info.message.trim().to_string(),
11284                                    group_id,
11285                                    is_primary: false,
11286                                    is_disk_based,
11287                                    is_unnecessary: false,
11288                                    underline,
11289                                    data: diagnostic.data.clone(),
11290                                    registration_id: registration_id.clone(),
11291                                },
11292                            });
11293                        }
11294                    }
11295                }
11296            }
11297        }
11298
11299        for entry in &mut diagnostics {
11300            let diagnostic = &mut entry.diagnostic;
11301            if !diagnostic.is_primary {
11302                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11303                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11304                    source,
11305                    diagnostic.code.clone(),
11306                    entry.range.clone(),
11307                )) {
11308                    if let Some(severity) = severity {
11309                        diagnostic.severity = severity;
11310                    }
11311                    diagnostic.is_unnecessary = is_unnecessary;
11312                }
11313            }
11314        }
11315
11316        DocumentDiagnostics {
11317            diagnostics,
11318            document_abs_path,
11319            version: lsp_diagnostics.version,
11320        }
11321    }
11322
11323    fn insert_newly_running_language_server(
11324        &mut self,
11325        adapter: Arc<CachedLspAdapter>,
11326        language_server: Arc<LanguageServer>,
11327        server_id: LanguageServerId,
11328        key: LanguageServerSeed,
11329        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11330        cx: &mut Context<Self>,
11331    ) {
11332        let Some(local) = self.as_local_mut() else {
11333            return;
11334        };
11335        // If the language server for this key doesn't match the server id, don't store the
11336        // server. Which will cause it to be dropped, killing the process
11337        if local
11338            .language_server_ids
11339            .get(&key)
11340            .map(|state| state.id != server_id)
11341            .unwrap_or(false)
11342        {
11343            return;
11344        }
11345
11346        // Update language_servers collection with Running variant of LanguageServerState
11347        // indicating that the server is up and running and ready
11348        let workspace_folders = workspace_folders.lock().clone();
11349        language_server.set_workspace_folders(workspace_folders);
11350
11351        let workspace_diagnostics_refresh_tasks = language_server
11352            .capabilities()
11353            .diagnostic_provider
11354            .and_then(|provider| {
11355                local
11356                    .language_server_dynamic_registrations
11357                    .entry(server_id)
11358                    .or_default()
11359                    .diagnostics
11360                    .entry(None)
11361                    .or_insert(provider.clone());
11362                let workspace_refresher =
11363                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11364
11365                Some((None, workspace_refresher))
11366            })
11367            .into_iter()
11368            .collect();
11369        local.language_servers.insert(
11370            server_id,
11371            LanguageServerState::Running {
11372                workspace_diagnostics_refresh_tasks,
11373                adapter: adapter.clone(),
11374                server: language_server.clone(),
11375                simulate_disk_based_diagnostics_completion: None,
11376            },
11377        );
11378        local
11379            .languages
11380            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11381        if let Some(file_ops_caps) = language_server
11382            .capabilities()
11383            .workspace
11384            .as_ref()
11385            .and_then(|ws| ws.file_operations.as_ref())
11386        {
11387            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11388            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11389            if did_rename_caps.or(will_rename_caps).is_some() {
11390                let watcher = RenamePathsWatchedForServer::default()
11391                    .with_did_rename_patterns(did_rename_caps)
11392                    .with_will_rename_patterns(will_rename_caps);
11393                local
11394                    .language_server_paths_watched_for_rename
11395                    .insert(server_id, watcher);
11396            }
11397        }
11398
11399        self.language_server_statuses.insert(
11400            server_id,
11401            LanguageServerStatus {
11402                name: language_server.name(),
11403                pending_work: Default::default(),
11404                has_pending_diagnostic_updates: false,
11405                progress_tokens: Default::default(),
11406                worktree: Some(key.worktree_id),
11407                binary: Some(language_server.binary().clone()),
11408                configuration: Some(language_server.configuration().clone()),
11409                workspace_folders: language_server.workspace_folders(),
11410            },
11411        );
11412
11413        cx.emit(LspStoreEvent::LanguageServerAdded(
11414            server_id,
11415            language_server.name(),
11416            Some(key.worktree_id),
11417        ));
11418
11419        let server_capabilities = language_server.capabilities();
11420        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11421            downstream_client
11422                .send(proto::StartLanguageServer {
11423                    project_id: *project_id,
11424                    server: Some(proto::LanguageServer {
11425                        id: server_id.to_proto(),
11426                        name: language_server.name().to_string(),
11427                        worktree_id: Some(key.worktree_id.to_proto()),
11428                    }),
11429                    capabilities: serde_json::to_string(&server_capabilities)
11430                        .expect("serializing server LSP capabilities"),
11431                })
11432                .log_err();
11433        }
11434        self.lsp_server_capabilities
11435            .insert(server_id, server_capabilities);
11436
11437        // Tell the language server about every open buffer in the worktree that matches the language.
11438        // Also check for buffers in worktrees that reused this server
11439        let mut worktrees_using_server = vec![key.worktree_id];
11440        if let Some(local) = self.as_local() {
11441            // Find all worktrees that have this server in their language server tree
11442            for (worktree_id, servers) in &local.lsp_tree.instances {
11443                if *worktree_id != key.worktree_id {
11444                    for server_map in servers.roots.values() {
11445                        if server_map
11446                            .values()
11447                            .any(|(node, _)| node.id() == Some(server_id))
11448                        {
11449                            worktrees_using_server.push(*worktree_id);
11450                        }
11451                    }
11452                }
11453            }
11454        }
11455
11456        let mut buffer_paths_registered = Vec::new();
11457        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11458            let mut lsp_adapters = HashMap::default();
11459            for buffer_handle in buffer_store.buffers() {
11460                let buffer = buffer_handle.read(cx);
11461                let file = match File::from_dyn(buffer.file()) {
11462                    Some(file) => file,
11463                    None => continue,
11464                };
11465                let language = match buffer.language() {
11466                    Some(language) => language,
11467                    None => continue,
11468                };
11469
11470                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11471                    || !lsp_adapters
11472                        .entry(language.name())
11473                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11474                        .iter()
11475                        .any(|a| a.name == key.name)
11476                {
11477                    continue;
11478                }
11479                // didOpen
11480                let file = match file.as_local() {
11481                    Some(file) => file,
11482                    None => continue,
11483                };
11484
11485                let local = self.as_local_mut().unwrap();
11486
11487                let buffer_id = buffer.remote_id();
11488                if local.registered_buffers.contains_key(&buffer_id) {
11489                    let versions = local
11490                        .buffer_snapshots
11491                        .entry(buffer_id)
11492                        .or_default()
11493                        .entry(server_id)
11494                        .and_modify(|_| {
11495                            assert!(
11496                            false,
11497                            "There should not be an existing snapshot for a newly inserted buffer"
11498                        )
11499                        })
11500                        .or_insert_with(|| {
11501                            vec![LspBufferSnapshot {
11502                                version: 0,
11503                                snapshot: buffer.text_snapshot(),
11504                            }]
11505                        });
11506
11507                    let snapshot = versions.last().unwrap();
11508                    let version = snapshot.version;
11509                    let initial_snapshot = &snapshot.snapshot;
11510                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11511                    language_server.register_buffer(
11512                        uri,
11513                        adapter.language_id(&language.name()),
11514                        version,
11515                        initial_snapshot.text(),
11516                    );
11517                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11518                    local
11519                        .buffers_opened_in_servers
11520                        .entry(buffer_id)
11521                        .or_default()
11522                        .insert(server_id);
11523                }
11524                buffer_handle.update(cx, |buffer, cx| {
11525                    buffer.set_completion_triggers(
11526                        server_id,
11527                        language_server
11528                            .capabilities()
11529                            .completion_provider
11530                            .as_ref()
11531                            .and_then(|provider| {
11532                                provider
11533                                    .trigger_characters
11534                                    .as_ref()
11535                                    .map(|characters| characters.iter().cloned().collect())
11536                            })
11537                            .unwrap_or_default(),
11538                        cx,
11539                    )
11540                });
11541            }
11542        });
11543
11544        for (buffer_id, abs_path) in buffer_paths_registered {
11545            cx.emit(LspStoreEvent::LanguageServerUpdate {
11546                language_server_id: server_id,
11547                name: Some(adapter.name()),
11548                message: proto::update_language_server::Variant::RegisteredForBuffer(
11549                    proto::RegisteredForBuffer {
11550                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11551                        buffer_id: buffer_id.to_proto(),
11552                    },
11553                ),
11554            });
11555        }
11556
11557        cx.notify();
11558    }
11559
11560    pub fn language_servers_running_disk_based_diagnostics(
11561        &self,
11562    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11563        self.language_server_statuses
11564            .iter()
11565            .filter_map(|(id, status)| {
11566                if status.has_pending_diagnostic_updates {
11567                    Some(*id)
11568                } else {
11569                    None
11570                }
11571            })
11572    }
11573
11574    pub(crate) fn cancel_language_server_work_for_buffers(
11575        &mut self,
11576        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11577        cx: &mut Context<Self>,
11578    ) {
11579        if let Some((client, project_id)) = self.upstream_client() {
11580            let request = client.request(proto::CancelLanguageServerWork {
11581                project_id,
11582                work: Some(proto::cancel_language_server_work::Work::Buffers(
11583                    proto::cancel_language_server_work::Buffers {
11584                        buffer_ids: buffers
11585                            .into_iter()
11586                            .map(|b| b.read(cx).remote_id().to_proto())
11587                            .collect(),
11588                    },
11589                )),
11590            });
11591            cx.background_spawn(request).detach_and_log_err(cx);
11592        } else if let Some(local) = self.as_local() {
11593            let servers = buffers
11594                .into_iter()
11595                .flat_map(|buffer| {
11596                    buffer.update(cx, |buffer, cx| {
11597                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11598                    })
11599                })
11600                .collect::<HashSet<_>>();
11601            for server_id in servers {
11602                self.cancel_language_server_work(server_id, None, cx);
11603            }
11604        }
11605    }
11606
11607    pub(crate) fn cancel_language_server_work(
11608        &mut self,
11609        server_id: LanguageServerId,
11610        token_to_cancel: Option<ProgressToken>,
11611        cx: &mut Context<Self>,
11612    ) {
11613        if let Some(local) = self.as_local() {
11614            let status = self.language_server_statuses.get(&server_id);
11615            let server = local.language_servers.get(&server_id);
11616            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11617            {
11618                for (token, progress) in &status.pending_work {
11619                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11620                        && token != token_to_cancel
11621                    {
11622                        continue;
11623                    }
11624                    if progress.is_cancellable {
11625                        server
11626                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11627                                WorkDoneProgressCancelParams {
11628                                    token: token.to_lsp(),
11629                                },
11630                            )
11631                            .ok();
11632                    }
11633                }
11634            }
11635        } else if let Some((client, project_id)) = self.upstream_client() {
11636            let request = client.request(proto::CancelLanguageServerWork {
11637                project_id,
11638                work: Some(
11639                    proto::cancel_language_server_work::Work::LanguageServerWork(
11640                        proto::cancel_language_server_work::LanguageServerWork {
11641                            language_server_id: server_id.to_proto(),
11642                            token: token_to_cancel.map(|token| token.to_proto()),
11643                        },
11644                    ),
11645                ),
11646            });
11647            cx.background_spawn(request).detach_and_log_err(cx);
11648        }
11649    }
11650
11651    fn register_supplementary_language_server(
11652        &mut self,
11653        id: LanguageServerId,
11654        name: LanguageServerName,
11655        server: Arc<LanguageServer>,
11656        cx: &mut Context<Self>,
11657    ) {
11658        if let Some(local) = self.as_local_mut() {
11659            local
11660                .supplementary_language_servers
11661                .insert(id, (name.clone(), server));
11662            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11663        }
11664    }
11665
11666    fn unregister_supplementary_language_server(
11667        &mut self,
11668        id: LanguageServerId,
11669        cx: &mut Context<Self>,
11670    ) {
11671        if let Some(local) = self.as_local_mut() {
11672            local.supplementary_language_servers.remove(&id);
11673            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11674        }
11675    }
11676
11677    pub(crate) fn supplementary_language_servers(
11678        &self,
11679    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11680        self.as_local().into_iter().flat_map(|local| {
11681            local
11682                .supplementary_language_servers
11683                .iter()
11684                .map(|(id, (name, _))| (*id, name.clone()))
11685        })
11686    }
11687
11688    pub fn language_server_adapter_for_id(
11689        &self,
11690        id: LanguageServerId,
11691    ) -> Option<Arc<CachedLspAdapter>> {
11692        self.as_local()
11693            .and_then(|local| local.language_servers.get(&id))
11694            .and_then(|language_server_state| match language_server_state {
11695                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11696                _ => None,
11697            })
11698    }
11699
11700    pub(super) fn update_local_worktree_language_servers(
11701        &mut self,
11702        worktree_handle: &Entity<Worktree>,
11703        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11704        cx: &mut Context<Self>,
11705    ) {
11706        if changes.is_empty() {
11707            return;
11708        }
11709
11710        let Some(local) = self.as_local() else { return };
11711
11712        local.prettier_store.update(cx, |prettier_store, cx| {
11713            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11714        });
11715
11716        let worktree_id = worktree_handle.read(cx).id();
11717        let mut language_server_ids = local
11718            .language_server_ids
11719            .iter()
11720            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11721            .collect::<Vec<_>>();
11722        language_server_ids.sort();
11723        language_server_ids.dedup();
11724
11725        // let abs_path = worktree_handle.read(cx).abs_path();
11726        for server_id in &language_server_ids {
11727            if let Some(LanguageServerState::Running { server, .. }) =
11728                local.language_servers.get(server_id)
11729                && let Some(watched_paths) = local
11730                    .language_server_watched_paths
11731                    .get(server_id)
11732                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11733            {
11734                let params = lsp::DidChangeWatchedFilesParams {
11735                    changes: changes
11736                        .iter()
11737                        .filter_map(|(path, _, change)| {
11738                            if !watched_paths.is_match(path.as_std_path()) {
11739                                return None;
11740                            }
11741                            let typ = match change {
11742                                PathChange::Loaded => return None,
11743                                PathChange::Added => lsp::FileChangeType::CREATED,
11744                                PathChange::Removed => lsp::FileChangeType::DELETED,
11745                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11746                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11747                            };
11748                            let uri = lsp::Uri::from_file_path(
11749                                worktree_handle.read(cx).absolutize(&path),
11750                            )
11751                            .ok()?;
11752                            Some(lsp::FileEvent { uri, typ })
11753                        })
11754                        .collect(),
11755                };
11756                if !params.changes.is_empty() {
11757                    server
11758                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11759                        .ok();
11760                }
11761            }
11762        }
11763        for (path, _, _) in changes {
11764            if let Some(file_name) = path.file_name()
11765                && local.watched_manifest_filenames.contains(file_name)
11766            {
11767                self.request_workspace_config_refresh();
11768                break;
11769            }
11770        }
11771    }
11772
11773    pub fn wait_for_remote_buffer(
11774        &mut self,
11775        id: BufferId,
11776        cx: &mut Context<Self>,
11777    ) -> Task<Result<Entity<Buffer>>> {
11778        self.buffer_store.update(cx, |buffer_store, cx| {
11779            buffer_store.wait_for_remote_buffer(id, cx)
11780        })
11781    }
11782
11783    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11784        let mut result = proto::Symbol {
11785            language_server_name: symbol.language_server_name.0.to_string(),
11786            source_worktree_id: symbol.source_worktree_id.to_proto(),
11787            language_server_id: symbol.source_language_server_id.to_proto(),
11788            name: symbol.name.clone(),
11789            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11790            start: Some(proto::PointUtf16 {
11791                row: symbol.range.start.0.row,
11792                column: symbol.range.start.0.column,
11793            }),
11794            end: Some(proto::PointUtf16 {
11795                row: symbol.range.end.0.row,
11796                column: symbol.range.end.0.column,
11797            }),
11798            worktree_id: Default::default(),
11799            path: Default::default(),
11800            signature: Default::default(),
11801        };
11802        match &symbol.path {
11803            SymbolLocation::InProject(path) => {
11804                result.worktree_id = path.worktree_id.to_proto();
11805                result.path = path.path.to_proto();
11806            }
11807            SymbolLocation::OutsideProject {
11808                abs_path,
11809                signature,
11810            } => {
11811                result.path = abs_path.to_string_lossy().into_owned();
11812                result.signature = signature.to_vec();
11813            }
11814        }
11815        result
11816    }
11817
11818    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11819        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11820        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11821        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11822
11823        let path = if serialized_symbol.signature.is_empty() {
11824            SymbolLocation::InProject(ProjectPath {
11825                worktree_id,
11826                path: RelPath::from_proto(&serialized_symbol.path)
11827                    .context("invalid symbol path")?,
11828            })
11829        } else {
11830            SymbolLocation::OutsideProject {
11831                abs_path: Path::new(&serialized_symbol.path).into(),
11832                signature: serialized_symbol
11833                    .signature
11834                    .try_into()
11835                    .map_err(|_| anyhow!("invalid signature"))?,
11836            }
11837        };
11838
11839        let start = serialized_symbol.start.context("invalid start")?;
11840        let end = serialized_symbol.end.context("invalid end")?;
11841        Ok(CoreSymbol {
11842            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11843            source_worktree_id,
11844            source_language_server_id: LanguageServerId::from_proto(
11845                serialized_symbol.language_server_id,
11846            ),
11847            path,
11848            name: serialized_symbol.name,
11849            range: Unclipped(PointUtf16::new(start.row, start.column))
11850                ..Unclipped(PointUtf16::new(end.row, end.column)),
11851            kind,
11852        })
11853    }
11854
11855    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11856        let mut serialized_completion = proto::Completion {
11857            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11858            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11859            new_text: completion.new_text.clone(),
11860            ..proto::Completion::default()
11861        };
11862        match &completion.source {
11863            CompletionSource::Lsp {
11864                insert_range,
11865                server_id,
11866                lsp_completion,
11867                lsp_defaults,
11868                resolved,
11869            } => {
11870                let (old_insert_start, old_insert_end) = insert_range
11871                    .as_ref()
11872                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11873                    .unzip();
11874
11875                serialized_completion.old_insert_start = old_insert_start;
11876                serialized_completion.old_insert_end = old_insert_end;
11877                serialized_completion.source = proto::completion::Source::Lsp as i32;
11878                serialized_completion.server_id = server_id.0 as u64;
11879                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11880                serialized_completion.lsp_defaults = lsp_defaults
11881                    .as_deref()
11882                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11883                serialized_completion.resolved = *resolved;
11884            }
11885            CompletionSource::BufferWord {
11886                word_range,
11887                resolved,
11888            } => {
11889                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11890                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11891                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11892                serialized_completion.resolved = *resolved;
11893            }
11894            CompletionSource::Custom => {
11895                serialized_completion.source = proto::completion::Source::Custom as i32;
11896                serialized_completion.resolved = true;
11897            }
11898            CompletionSource::Dap { sort_text } => {
11899                serialized_completion.source = proto::completion::Source::Dap as i32;
11900                serialized_completion.sort_text = Some(sort_text.clone());
11901            }
11902        }
11903
11904        serialized_completion
11905    }
11906
11907    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11908        let old_replace_start = completion
11909            .old_replace_start
11910            .and_then(deserialize_anchor)
11911            .context("invalid old start")?;
11912        let old_replace_end = completion
11913            .old_replace_end
11914            .and_then(deserialize_anchor)
11915            .context("invalid old end")?;
11916        let insert_range = {
11917            match completion.old_insert_start.zip(completion.old_insert_end) {
11918                Some((start, end)) => {
11919                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11920                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11921                    Some(start..end)
11922                }
11923                None => None,
11924            }
11925        };
11926        Ok(CoreCompletion {
11927            replace_range: old_replace_start..old_replace_end,
11928            new_text: completion.new_text,
11929            source: match proto::completion::Source::from_i32(completion.source) {
11930                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11931                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11932                    insert_range,
11933                    server_id: LanguageServerId::from_proto(completion.server_id),
11934                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11935                    lsp_defaults: completion
11936                        .lsp_defaults
11937                        .as_deref()
11938                        .map(serde_json::from_slice)
11939                        .transpose()?,
11940                    resolved: completion.resolved,
11941                },
11942                Some(proto::completion::Source::BufferWord) => {
11943                    let word_range = completion
11944                        .buffer_word_start
11945                        .and_then(deserialize_anchor)
11946                        .context("invalid buffer word start")?
11947                        ..completion
11948                            .buffer_word_end
11949                            .and_then(deserialize_anchor)
11950                            .context("invalid buffer word end")?;
11951                    CompletionSource::BufferWord {
11952                        word_range,
11953                        resolved: completion.resolved,
11954                    }
11955                }
11956                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11957                    sort_text: completion
11958                        .sort_text
11959                        .context("expected sort text to exist")?,
11960                },
11961                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11962            },
11963        })
11964    }
11965
11966    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11967        let (kind, lsp_action) = match &action.lsp_action {
11968            LspAction::Action(code_action) => (
11969                proto::code_action::Kind::Action as i32,
11970                serde_json::to_vec(code_action).unwrap(),
11971            ),
11972            LspAction::Command(command) => (
11973                proto::code_action::Kind::Command as i32,
11974                serde_json::to_vec(command).unwrap(),
11975            ),
11976            LspAction::CodeLens(code_lens) => (
11977                proto::code_action::Kind::CodeLens as i32,
11978                serde_json::to_vec(code_lens).unwrap(),
11979            ),
11980        };
11981
11982        proto::CodeAction {
11983            server_id: action.server_id.0 as u64,
11984            start: Some(serialize_anchor(&action.range.start)),
11985            end: Some(serialize_anchor(&action.range.end)),
11986            lsp_action,
11987            kind,
11988            resolved: action.resolved,
11989        }
11990    }
11991
11992    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11993        let start = action
11994            .start
11995            .and_then(deserialize_anchor)
11996            .context("invalid start")?;
11997        let end = action
11998            .end
11999            .and_then(deserialize_anchor)
12000            .context("invalid end")?;
12001        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12002            Some(proto::code_action::Kind::Action) => {
12003                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12004            }
12005            Some(proto::code_action::Kind::Command) => {
12006                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12007            }
12008            Some(proto::code_action::Kind::CodeLens) => {
12009                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12010            }
12011            None => anyhow::bail!("Unknown action kind {}", action.kind),
12012        };
12013        Ok(CodeAction {
12014            server_id: LanguageServerId(action.server_id as usize),
12015            range: start..end,
12016            resolved: action.resolved,
12017            lsp_action,
12018        })
12019    }
12020
12021    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12022        match &formatting_result {
12023            Ok(_) => self.last_formatting_failure = None,
12024            Err(error) => {
12025                let error_string = format!("{error:#}");
12026                log::error!("Formatting failed: {error_string}");
12027                self.last_formatting_failure
12028                    .replace(error_string.lines().join(" "));
12029            }
12030        }
12031    }
12032
12033    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12034        self.lsp_server_capabilities.remove(&for_server);
12035        for lsp_data in self.lsp_data.values_mut() {
12036            lsp_data.remove_server_data(for_server);
12037        }
12038        if let Some(local) = self.as_local_mut() {
12039            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12040            local
12041                .workspace_pull_diagnostics_result_ids
12042                .remove(&for_server);
12043            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12044                buffer_servers.remove(&for_server);
12045            }
12046        }
12047    }
12048
12049    pub fn result_id_for_buffer_pull(
12050        &self,
12051        server_id: LanguageServerId,
12052        buffer_id: BufferId,
12053        registration_id: &Option<SharedString>,
12054        cx: &App,
12055    ) -> Option<SharedString> {
12056        let abs_path = self
12057            .buffer_store
12058            .read(cx)
12059            .get(buffer_id)
12060            .and_then(|b| File::from_dyn(b.read(cx).file()))
12061            .map(|f| f.abs_path(cx))?;
12062        self.as_local()?
12063            .buffer_pull_diagnostics_result_ids
12064            .get(&server_id)?
12065            .get(registration_id)?
12066            .get(&abs_path)?
12067            .clone()
12068    }
12069
12070    /// Gets all result_ids for a workspace diagnostics pull request.
12071    /// 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.
12072    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12073    pub fn result_ids_for_workspace_refresh(
12074        &self,
12075        server_id: LanguageServerId,
12076        registration_id: &Option<SharedString>,
12077    ) -> HashMap<PathBuf, SharedString> {
12078        let Some(local) = self.as_local() else {
12079            return HashMap::default();
12080        };
12081        local
12082            .workspace_pull_diagnostics_result_ids
12083            .get(&server_id)
12084            .into_iter()
12085            .filter_map(|diagnostics| diagnostics.get(registration_id))
12086            .flatten()
12087            .filter_map(|(abs_path, result_id)| {
12088                let result_id = local
12089                    .buffer_pull_diagnostics_result_ids
12090                    .get(&server_id)
12091                    .and_then(|buffer_ids_result_ids| {
12092                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12093                    })
12094                    .cloned()
12095                    .flatten()
12096                    .or_else(|| result_id.clone())?;
12097                Some((abs_path.clone(), result_id))
12098            })
12099            .collect()
12100    }
12101
12102    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12103        if let Some(LanguageServerState::Running {
12104            workspace_diagnostics_refresh_tasks,
12105            ..
12106        }) = self
12107            .as_local_mut()
12108            .and_then(|local| local.language_servers.get_mut(&server_id))
12109        {
12110            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12111                diagnostics.refresh_tx.try_send(()).ok();
12112            }
12113        }
12114    }
12115
12116    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
12117        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
12118            return;
12119        };
12120        let Some(local) = self.as_local_mut() else {
12121            return;
12122        };
12123
12124        for server_id in buffer.update(cx, |buffer, cx| {
12125            local.language_server_ids_for_buffer(buffer, cx)
12126        }) {
12127            if let Some(LanguageServerState::Running {
12128                workspace_diagnostics_refresh_tasks,
12129                ..
12130            }) = local.language_servers.get_mut(&server_id)
12131            {
12132                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12133                    diagnostics.refresh_tx.try_send(()).ok();
12134                }
12135            }
12136        }
12137    }
12138
12139    fn apply_workspace_diagnostic_report(
12140        &mut self,
12141        server_id: LanguageServerId,
12142        report: lsp::WorkspaceDiagnosticReportResult,
12143        registration_id: Option<SharedString>,
12144        cx: &mut Context<Self>,
12145    ) {
12146        let workspace_diagnostics =
12147            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12148                report,
12149                server_id,
12150                registration_id,
12151            );
12152        let mut unchanged_buffers = HashMap::default();
12153        let workspace_diagnostics_updates = workspace_diagnostics
12154            .into_iter()
12155            .filter_map(
12156                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12157                    LspPullDiagnostics::Response {
12158                        server_id,
12159                        uri,
12160                        diagnostics,
12161                        registration_id,
12162                    } => Some((
12163                        server_id,
12164                        uri,
12165                        diagnostics,
12166                        workspace_diagnostics.version,
12167                        registration_id,
12168                    )),
12169                    LspPullDiagnostics::Default => None,
12170                },
12171            )
12172            .fold(
12173                HashMap::default(),
12174                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12175                    let (result_id, diagnostics) = match diagnostics {
12176                        PulledDiagnostics::Unchanged { result_id } => {
12177                            unchanged_buffers
12178                                .entry(new_registration_id.clone())
12179                                .or_insert_with(HashSet::default)
12180                                .insert(uri.clone());
12181                            (Some(result_id), Vec::new())
12182                        }
12183                        PulledDiagnostics::Changed {
12184                            result_id,
12185                            diagnostics,
12186                        } => (result_id, diagnostics),
12187                    };
12188                    let disk_based_sources = Cow::Owned(
12189                        self.language_server_adapter_for_id(server_id)
12190                            .as_ref()
12191                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12192                            .unwrap_or(&[])
12193                            .to_vec(),
12194                    );
12195
12196                    let Some(abs_path) = uri.to_file_path().ok() else {
12197                        return acc;
12198                    };
12199                    let Some((worktree, relative_path)) =
12200                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12201                    else {
12202                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12203                        return acc;
12204                    };
12205                    let worktree_id = worktree.read(cx).id();
12206                    let project_path = ProjectPath {
12207                        worktree_id,
12208                        path: relative_path,
12209                    };
12210                    if let Some(local_lsp_store) = self.as_local_mut() {
12211                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12212                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12213                    }
12214                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12215                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12216                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12217                        acc.entry(server_id)
12218                            .or_insert_with(HashMap::default)
12219                            .entry(new_registration_id.clone())
12220                            .or_insert_with(Vec::new)
12221                            .push(DocumentDiagnosticsUpdate {
12222                                server_id,
12223                                diagnostics: lsp::PublishDiagnosticsParams {
12224                                    uri,
12225                                    diagnostics,
12226                                    version,
12227                                },
12228                                result_id,
12229                                disk_based_sources,
12230                                registration_id: new_registration_id,
12231                            });
12232                    }
12233                    acc
12234                },
12235            );
12236
12237        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12238            for (registration_id, diagnostic_updates) in diagnostic_updates {
12239                self.merge_lsp_diagnostics(
12240                    DiagnosticSourceKind::Pulled,
12241                    diagnostic_updates,
12242                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12243                        DiagnosticSourceKind::Pulled => {
12244                            old_diagnostic.registration_id != registration_id
12245                                || unchanged_buffers
12246                                    .get(&old_diagnostic.registration_id)
12247                                    .is_some_and(|unchanged_buffers| {
12248                                        unchanged_buffers.contains(&document_uri)
12249                                    })
12250                        }
12251                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12252                    },
12253                    cx,
12254                )
12255                .log_err();
12256            }
12257        }
12258    }
12259
12260    fn register_server_capabilities(
12261        &mut self,
12262        server_id: LanguageServerId,
12263        params: lsp::RegistrationParams,
12264        cx: &mut Context<Self>,
12265    ) -> anyhow::Result<()> {
12266        let server = self
12267            .language_server_for_id(server_id)
12268            .with_context(|| format!("no server {server_id} found"))?;
12269        for reg in params.registrations {
12270            match reg.method.as_str() {
12271                "workspace/didChangeWatchedFiles" => {
12272                    if let Some(options) = reg.register_options {
12273                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12274                            let caps = serde_json::from_value(options)?;
12275                            local_lsp_store
12276                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12277                            true
12278                        } else {
12279                            false
12280                        };
12281                        if notify {
12282                            notify_server_capabilities_updated(&server, cx);
12283                        }
12284                    }
12285                }
12286                "workspace/didChangeConfiguration" => {
12287                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12288                }
12289                "workspace/didChangeWorkspaceFolders" => {
12290                    // In this case register options is an empty object, we can ignore it
12291                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12292                        supported: Some(true),
12293                        change_notifications: Some(OneOf::Right(reg.id)),
12294                    };
12295                    server.update_capabilities(|capabilities| {
12296                        capabilities
12297                            .workspace
12298                            .get_or_insert_default()
12299                            .workspace_folders = Some(caps);
12300                    });
12301                    notify_server_capabilities_updated(&server, cx);
12302                }
12303                "workspace/symbol" => {
12304                    let options = parse_register_capabilities(reg)?;
12305                    server.update_capabilities(|capabilities| {
12306                        capabilities.workspace_symbol_provider = Some(options);
12307                    });
12308                    notify_server_capabilities_updated(&server, cx);
12309                }
12310                "workspace/fileOperations" => {
12311                    if let Some(options) = reg.register_options {
12312                        let caps = serde_json::from_value(options)?;
12313                        server.update_capabilities(|capabilities| {
12314                            capabilities
12315                                .workspace
12316                                .get_or_insert_default()
12317                                .file_operations = Some(caps);
12318                        });
12319                        notify_server_capabilities_updated(&server, cx);
12320                    }
12321                }
12322                "workspace/executeCommand" => {
12323                    if let Some(options) = reg.register_options {
12324                        let options = serde_json::from_value(options)?;
12325                        server.update_capabilities(|capabilities| {
12326                            capabilities.execute_command_provider = Some(options);
12327                        });
12328                        notify_server_capabilities_updated(&server, cx);
12329                    }
12330                }
12331                "textDocument/rangeFormatting" => {
12332                    let options = parse_register_capabilities(reg)?;
12333                    server.update_capabilities(|capabilities| {
12334                        capabilities.document_range_formatting_provider = Some(options);
12335                    });
12336                    notify_server_capabilities_updated(&server, cx);
12337                }
12338                "textDocument/onTypeFormatting" => {
12339                    if let Some(options) = reg
12340                        .register_options
12341                        .map(serde_json::from_value)
12342                        .transpose()?
12343                    {
12344                        server.update_capabilities(|capabilities| {
12345                            capabilities.document_on_type_formatting_provider = Some(options);
12346                        });
12347                        notify_server_capabilities_updated(&server, cx);
12348                    }
12349                }
12350                "textDocument/formatting" => {
12351                    let options = parse_register_capabilities(reg)?;
12352                    server.update_capabilities(|capabilities| {
12353                        capabilities.document_formatting_provider = Some(options);
12354                    });
12355                    notify_server_capabilities_updated(&server, cx);
12356                }
12357                "textDocument/rename" => {
12358                    let options = parse_register_capabilities(reg)?;
12359                    server.update_capabilities(|capabilities| {
12360                        capabilities.rename_provider = Some(options);
12361                    });
12362                    notify_server_capabilities_updated(&server, cx);
12363                }
12364                "textDocument/inlayHint" => {
12365                    let options = parse_register_capabilities(reg)?;
12366                    server.update_capabilities(|capabilities| {
12367                        capabilities.inlay_hint_provider = Some(options);
12368                    });
12369                    notify_server_capabilities_updated(&server, cx);
12370                }
12371                "textDocument/documentSymbol" => {
12372                    let options = parse_register_capabilities(reg)?;
12373                    server.update_capabilities(|capabilities| {
12374                        capabilities.document_symbol_provider = Some(options);
12375                    });
12376                    notify_server_capabilities_updated(&server, cx);
12377                }
12378                "textDocument/codeAction" => {
12379                    let options = parse_register_capabilities(reg)?;
12380                    let provider = match options {
12381                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12382                        OneOf::Right(caps) => caps,
12383                    };
12384                    server.update_capabilities(|capabilities| {
12385                        capabilities.code_action_provider = Some(provider);
12386                    });
12387                    notify_server_capabilities_updated(&server, cx);
12388                }
12389                "textDocument/definition" => {
12390                    let options = parse_register_capabilities(reg)?;
12391                    server.update_capabilities(|capabilities| {
12392                        capabilities.definition_provider = Some(options);
12393                    });
12394                    notify_server_capabilities_updated(&server, cx);
12395                }
12396                "textDocument/completion" => {
12397                    if let Some(caps) = reg
12398                        .register_options
12399                        .map(serde_json::from_value::<CompletionOptions>)
12400                        .transpose()?
12401                    {
12402                        server.update_capabilities(|capabilities| {
12403                            capabilities.completion_provider = Some(caps.clone());
12404                        });
12405
12406                        if let Some(local) = self.as_local() {
12407                            let mut buffers_with_language_server = Vec::new();
12408                            for handle in self.buffer_store.read(cx).buffers() {
12409                                let buffer_id = handle.read(cx).remote_id();
12410                                if local
12411                                    .buffers_opened_in_servers
12412                                    .get(&buffer_id)
12413                                    .filter(|s| s.contains(&server_id))
12414                                    .is_some()
12415                                {
12416                                    buffers_with_language_server.push(handle);
12417                                }
12418                            }
12419                            let triggers = caps
12420                                .trigger_characters
12421                                .unwrap_or_default()
12422                                .into_iter()
12423                                .collect::<BTreeSet<_>>();
12424                            for handle in buffers_with_language_server {
12425                                let triggers = triggers.clone();
12426                                let _ = handle.update(cx, move |buffer, cx| {
12427                                    buffer.set_completion_triggers(server_id, triggers, cx);
12428                                });
12429                            }
12430                        }
12431                        notify_server_capabilities_updated(&server, cx);
12432                    }
12433                }
12434                "textDocument/hover" => {
12435                    let options = parse_register_capabilities(reg)?;
12436                    let provider = match options {
12437                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12438                        OneOf::Right(caps) => caps,
12439                    };
12440                    server.update_capabilities(|capabilities| {
12441                        capabilities.hover_provider = Some(provider);
12442                    });
12443                    notify_server_capabilities_updated(&server, cx);
12444                }
12445                "textDocument/signatureHelp" => {
12446                    if let Some(caps) = reg
12447                        .register_options
12448                        .map(serde_json::from_value)
12449                        .transpose()?
12450                    {
12451                        server.update_capabilities(|capabilities| {
12452                            capabilities.signature_help_provider = Some(caps);
12453                        });
12454                        notify_server_capabilities_updated(&server, cx);
12455                    }
12456                }
12457                "textDocument/didChange" => {
12458                    if let Some(sync_kind) = reg
12459                        .register_options
12460                        .and_then(|opts| opts.get("syncKind").cloned())
12461                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12462                        .transpose()?
12463                    {
12464                        server.update_capabilities(|capabilities| {
12465                            let mut sync_options =
12466                                Self::take_text_document_sync_options(capabilities);
12467                            sync_options.change = Some(sync_kind);
12468                            capabilities.text_document_sync =
12469                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12470                        });
12471                        notify_server_capabilities_updated(&server, cx);
12472                    }
12473                }
12474                "textDocument/didSave" => {
12475                    if let Some(include_text) = reg
12476                        .register_options
12477                        .map(|opts| {
12478                            let transpose = opts
12479                                .get("includeText")
12480                                .cloned()
12481                                .map(serde_json::from_value::<Option<bool>>)
12482                                .transpose();
12483                            match transpose {
12484                                Ok(value) => Ok(value.flatten()),
12485                                Err(e) => Err(e),
12486                            }
12487                        })
12488                        .transpose()?
12489                    {
12490                        server.update_capabilities(|capabilities| {
12491                            let mut sync_options =
12492                                Self::take_text_document_sync_options(capabilities);
12493                            sync_options.save =
12494                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12495                                    include_text,
12496                                }));
12497                            capabilities.text_document_sync =
12498                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12499                        });
12500                        notify_server_capabilities_updated(&server, cx);
12501                    }
12502                }
12503                "textDocument/codeLens" => {
12504                    if let Some(caps) = reg
12505                        .register_options
12506                        .map(serde_json::from_value)
12507                        .transpose()?
12508                    {
12509                        server.update_capabilities(|capabilities| {
12510                            capabilities.code_lens_provider = Some(caps);
12511                        });
12512                        notify_server_capabilities_updated(&server, cx);
12513                    }
12514                }
12515                "textDocument/diagnostic" => {
12516                    if let Some(caps) = reg
12517                        .register_options
12518                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12519                        .transpose()?
12520                    {
12521                        let local = self
12522                            .as_local_mut()
12523                            .context("Expected LSP Store to be local")?;
12524                        let state = local
12525                            .language_servers
12526                            .get_mut(&server_id)
12527                            .context("Could not obtain Language Servers state")?;
12528                        local
12529                            .language_server_dynamic_registrations
12530                            .entry(server_id)
12531                            .or_default()
12532                            .diagnostics
12533                            .insert(Some(reg.id.clone()), caps.clone());
12534
12535                        let supports_workspace_diagnostics =
12536                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12537                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12538                                    diagnostic_options.workspace_diagnostics
12539                                }
12540                                DiagnosticServerCapabilities::RegistrationOptions(
12541                                    diagnostic_registration_options,
12542                                ) => {
12543                                    diagnostic_registration_options
12544                                        .diagnostic_options
12545                                        .workspace_diagnostics
12546                                }
12547                            };
12548
12549                        if supports_workspace_diagnostics(&caps) {
12550                            if let LanguageServerState::Running {
12551                                workspace_diagnostics_refresh_tasks,
12552                                ..
12553                            } = state
12554                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12555                                    Some(reg.id.clone()),
12556                                    caps.clone(),
12557                                    server.clone(),
12558                                    cx,
12559                                )
12560                            {
12561                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12562                            }
12563                        }
12564
12565                        server.update_capabilities(|capabilities| {
12566                            capabilities.diagnostic_provider = Some(caps);
12567                        });
12568
12569                        notify_server_capabilities_updated(&server, cx);
12570                    }
12571                }
12572                "textDocument/documentColor" => {
12573                    let options = parse_register_capabilities(reg)?;
12574                    let provider = match options {
12575                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12576                        OneOf::Right(caps) => caps,
12577                    };
12578                    server.update_capabilities(|capabilities| {
12579                        capabilities.color_provider = Some(provider);
12580                    });
12581                    notify_server_capabilities_updated(&server, cx);
12582                }
12583                _ => log::warn!("unhandled capability registration: {reg:?}"),
12584            }
12585        }
12586
12587        Ok(())
12588    }
12589
12590    fn unregister_server_capabilities(
12591        &mut self,
12592        server_id: LanguageServerId,
12593        params: lsp::UnregistrationParams,
12594        cx: &mut Context<Self>,
12595    ) -> anyhow::Result<()> {
12596        let server = self
12597            .language_server_for_id(server_id)
12598            .with_context(|| format!("no server {server_id} found"))?;
12599        for unreg in params.unregisterations.iter() {
12600            match unreg.method.as_str() {
12601                "workspace/didChangeWatchedFiles" => {
12602                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12603                        local_lsp_store
12604                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12605                        true
12606                    } else {
12607                        false
12608                    };
12609                    if notify {
12610                        notify_server_capabilities_updated(&server, cx);
12611                    }
12612                }
12613                "workspace/didChangeConfiguration" => {
12614                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12615                }
12616                "workspace/didChangeWorkspaceFolders" => {
12617                    server.update_capabilities(|capabilities| {
12618                        capabilities
12619                            .workspace
12620                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12621                                workspace_folders: None,
12622                                file_operations: None,
12623                            })
12624                            .workspace_folders = None;
12625                    });
12626                    notify_server_capabilities_updated(&server, cx);
12627                }
12628                "workspace/symbol" => {
12629                    server.update_capabilities(|capabilities| {
12630                        capabilities.workspace_symbol_provider = None
12631                    });
12632                    notify_server_capabilities_updated(&server, cx);
12633                }
12634                "workspace/fileOperations" => {
12635                    server.update_capabilities(|capabilities| {
12636                        capabilities
12637                            .workspace
12638                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12639                                workspace_folders: None,
12640                                file_operations: None,
12641                            })
12642                            .file_operations = None;
12643                    });
12644                    notify_server_capabilities_updated(&server, cx);
12645                }
12646                "workspace/executeCommand" => {
12647                    server.update_capabilities(|capabilities| {
12648                        capabilities.execute_command_provider = None;
12649                    });
12650                    notify_server_capabilities_updated(&server, cx);
12651                }
12652                "textDocument/rangeFormatting" => {
12653                    server.update_capabilities(|capabilities| {
12654                        capabilities.document_range_formatting_provider = None
12655                    });
12656                    notify_server_capabilities_updated(&server, cx);
12657                }
12658                "textDocument/onTypeFormatting" => {
12659                    server.update_capabilities(|capabilities| {
12660                        capabilities.document_on_type_formatting_provider = None;
12661                    });
12662                    notify_server_capabilities_updated(&server, cx);
12663                }
12664                "textDocument/formatting" => {
12665                    server.update_capabilities(|capabilities| {
12666                        capabilities.document_formatting_provider = None;
12667                    });
12668                    notify_server_capabilities_updated(&server, cx);
12669                }
12670                "textDocument/rename" => {
12671                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12672                    notify_server_capabilities_updated(&server, cx);
12673                }
12674                "textDocument/codeAction" => {
12675                    server.update_capabilities(|capabilities| {
12676                        capabilities.code_action_provider = None;
12677                    });
12678                    notify_server_capabilities_updated(&server, cx);
12679                }
12680                "textDocument/definition" => {
12681                    server.update_capabilities(|capabilities| {
12682                        capabilities.definition_provider = None;
12683                    });
12684                    notify_server_capabilities_updated(&server, cx);
12685                }
12686                "textDocument/completion" => {
12687                    server.update_capabilities(|capabilities| {
12688                        capabilities.completion_provider = None;
12689                    });
12690                    notify_server_capabilities_updated(&server, cx);
12691                }
12692                "textDocument/hover" => {
12693                    server.update_capabilities(|capabilities| {
12694                        capabilities.hover_provider = None;
12695                    });
12696                    notify_server_capabilities_updated(&server, cx);
12697                }
12698                "textDocument/signatureHelp" => {
12699                    server.update_capabilities(|capabilities| {
12700                        capabilities.signature_help_provider = None;
12701                    });
12702                    notify_server_capabilities_updated(&server, cx);
12703                }
12704                "textDocument/didChange" => {
12705                    server.update_capabilities(|capabilities| {
12706                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12707                        sync_options.change = None;
12708                        capabilities.text_document_sync =
12709                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12710                    });
12711                    notify_server_capabilities_updated(&server, cx);
12712                }
12713                "textDocument/didSave" => {
12714                    server.update_capabilities(|capabilities| {
12715                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12716                        sync_options.save = None;
12717                        capabilities.text_document_sync =
12718                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12719                    });
12720                    notify_server_capabilities_updated(&server, cx);
12721                }
12722                "textDocument/codeLens" => {
12723                    server.update_capabilities(|capabilities| {
12724                        capabilities.code_lens_provider = None;
12725                    });
12726                    notify_server_capabilities_updated(&server, cx);
12727                }
12728                "textDocument/diagnostic" => {
12729                    let local = self
12730                        .as_local_mut()
12731                        .context("Expected LSP Store to be local")?;
12732
12733                    let state = local
12734                        .language_servers
12735                        .get_mut(&server_id)
12736                        .context("Could not obtain Language Servers state")?;
12737                    let registrations = local
12738                        .language_server_dynamic_registrations
12739                        .get_mut(&server_id)
12740                        .with_context(|| {
12741                            format!("Expected dynamic registration to exist for server {server_id}")
12742                        })?;
12743                    registrations.diagnostics
12744                        .remove(&Some(unreg.id.clone()))
12745                        .with_context(|| format!(
12746                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12747                            unreg.id)
12748                        )?;
12749                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12750
12751                    if let LanguageServerState::Running {
12752                        workspace_diagnostics_refresh_tasks,
12753                        ..
12754                    } = state
12755                    {
12756                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12757                    }
12758
12759                    if removed_last_diagnostic_provider {
12760                        server.update_capabilities(|capabilities| {
12761                            debug_assert!(capabilities.diagnostic_provider.is_some());
12762                            capabilities.diagnostic_provider = None;
12763                        });
12764                    }
12765
12766                    notify_server_capabilities_updated(&server, cx);
12767                }
12768                "textDocument/documentColor" => {
12769                    server.update_capabilities(|capabilities| {
12770                        capabilities.color_provider = None;
12771                    });
12772                    notify_server_capabilities_updated(&server, cx);
12773                }
12774                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12775            }
12776        }
12777
12778        Ok(())
12779    }
12780
12781    async fn deduplicate_range_based_lsp_requests<T>(
12782        lsp_store: &Entity<Self>,
12783        server_id: Option<LanguageServerId>,
12784        lsp_request_id: LspRequestId,
12785        proto_request: &T::ProtoRequest,
12786        range: Range<Anchor>,
12787        cx: &mut AsyncApp,
12788    ) -> Result<()>
12789    where
12790        T: LspCommand,
12791        T::ProtoRequest: proto::LspRequestMessage,
12792    {
12793        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12794        let version = deserialize_version(proto_request.buffer_version());
12795        let buffer = lsp_store.update(cx, |this, cx| {
12796            this.buffer_store.read(cx).get_existing(buffer_id)
12797        })??;
12798        buffer
12799            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12800            .await?;
12801        lsp_store.update(cx, |lsp_store, cx| {
12802            let buffer_snapshot = buffer.read(cx).snapshot();
12803            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12804            let chunks_queried_for = lsp_data
12805                .inlay_hints
12806                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12807                .collect::<Vec<_>>();
12808            match chunks_queried_for.as_slice() {
12809                &[chunk] => {
12810                    let key = LspKey {
12811                        request_type: TypeId::of::<T>(),
12812                        server_queried: server_id,
12813                    };
12814                    let previous_request = lsp_data
12815                        .chunk_lsp_requests
12816                        .entry(key)
12817                        .or_default()
12818                        .insert(chunk, lsp_request_id);
12819                    if let Some((previous_request, running_requests)) =
12820                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12821                    {
12822                        running_requests.remove(&previous_request);
12823                    }
12824                }
12825                _ambiguous_chunks => {
12826                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12827                    // there, a buffer version-based check will be performed and outdated requests discarded.
12828                }
12829            }
12830            anyhow::Ok(())
12831        })??;
12832
12833        Ok(())
12834    }
12835
12836    async fn query_lsp_locally<T>(
12837        lsp_store: Entity<Self>,
12838        for_server_id: Option<LanguageServerId>,
12839        sender_id: proto::PeerId,
12840        lsp_request_id: LspRequestId,
12841        proto_request: T::ProtoRequest,
12842        position: Option<Anchor>,
12843        cx: &mut AsyncApp,
12844    ) -> Result<()>
12845    where
12846        T: LspCommand + Clone,
12847        T::ProtoRequest: proto::LspRequestMessage,
12848        <T::ProtoRequest as proto::RequestMessage>::Response:
12849            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12850    {
12851        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12852        let version = deserialize_version(proto_request.buffer_version());
12853        let buffer = lsp_store.update(cx, |this, cx| {
12854            this.buffer_store.read(cx).get_existing(buffer_id)
12855        })??;
12856        buffer
12857            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12858            .await?;
12859        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12860        let request =
12861            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12862        let key = LspKey {
12863            request_type: TypeId::of::<T>(),
12864            server_queried: for_server_id,
12865        };
12866        lsp_store.update(cx, |lsp_store, cx| {
12867            let request_task = match for_server_id {
12868                Some(server_id) => {
12869                    let server_task = lsp_store.request_lsp(
12870                        buffer.clone(),
12871                        LanguageServerToQuery::Other(server_id),
12872                        request.clone(),
12873                        cx,
12874                    );
12875                    cx.background_spawn(async move {
12876                        let mut responses = Vec::new();
12877                        match server_task.await {
12878                            Ok(response) => responses.push((server_id, response)),
12879                            // rust-analyzer likes to error with this when its still loading up
12880                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12881                            Err(e) => log::error!(
12882                                "Error handling response for request {request:?}: {e:#}"
12883                            ),
12884                        }
12885                        responses
12886                    })
12887                }
12888                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12889            };
12890            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12891            if T::ProtoRequest::stop_previous_requests() {
12892                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12893                    lsp_requests.clear();
12894                }
12895            }
12896            lsp_data.lsp_requests.entry(key).or_default().insert(
12897                lsp_request_id,
12898                cx.spawn(async move |lsp_store, cx| {
12899                    let response = request_task.await;
12900                    lsp_store
12901                        .update(cx, |lsp_store, cx| {
12902                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12903                            {
12904                                let response = response
12905                                    .into_iter()
12906                                    .map(|(server_id, response)| {
12907                                        (
12908                                            server_id.to_proto(),
12909                                            T::response_to_proto(
12910                                                response,
12911                                                lsp_store,
12912                                                sender_id,
12913                                                &buffer_version,
12914                                                cx,
12915                                            )
12916                                            .into(),
12917                                        )
12918                                    })
12919                                    .collect::<HashMap<_, _>>();
12920                                match client.send_lsp_response::<T::ProtoRequest>(
12921                                    project_id,
12922                                    lsp_request_id,
12923                                    response,
12924                                ) {
12925                                    Ok(()) => {}
12926                                    Err(e) => {
12927                                        log::error!("Failed to send LSP response: {e:#}",)
12928                                    }
12929                                }
12930                            }
12931                        })
12932                        .ok();
12933                }),
12934            );
12935        })?;
12936        Ok(())
12937    }
12938
12939    fn take_text_document_sync_options(
12940        capabilities: &mut lsp::ServerCapabilities,
12941    ) -> lsp::TextDocumentSyncOptions {
12942        match capabilities.text_document_sync.take() {
12943            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12944            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12945                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12946                sync_options.change = Some(sync_kind);
12947                sync_options
12948            }
12949            None => lsp::TextDocumentSyncOptions::default(),
12950        }
12951    }
12952
12953    #[cfg(any(test, feature = "test-support"))]
12954    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12955        Some(
12956            self.lsp_data
12957                .get_mut(&buffer_id)?
12958                .code_lens
12959                .take()?
12960                .update
12961                .take()?
12962                .1,
12963        )
12964    }
12965
12966    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12967        self.downstream_client.clone()
12968    }
12969
12970    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12971        self.worktree_store.clone()
12972    }
12973
12974    /// Gets what's stored in the LSP data for the given buffer.
12975    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12976        self.lsp_data.get_mut(&buffer_id)
12977    }
12978
12979    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12980    /// new [`BufferLspData`] will be created to replace the previous state.
12981    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
12982        let (buffer_id, buffer_version) =
12983            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
12984        let lsp_data = self
12985            .lsp_data
12986            .entry(buffer_id)
12987            .or_insert_with(|| BufferLspData::new(buffer, cx));
12988        if buffer_version.changed_since(&lsp_data.buffer_version) {
12989            *lsp_data = BufferLspData::new(buffer, cx);
12990        }
12991        lsp_data
12992    }
12993}
12994
12995// Registration with registerOptions as null, should fallback to true.
12996// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12997fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12998    reg: lsp::Registration,
12999) -> Result<OneOf<bool, T>> {
13000    Ok(match reg.register_options {
13001        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13002        None => OneOf::Left(true),
13003    })
13004}
13005
13006fn subscribe_to_binary_statuses(
13007    languages: &Arc<LanguageRegistry>,
13008    cx: &mut Context<'_, LspStore>,
13009) -> Task<()> {
13010    let mut server_statuses = languages.language_server_binary_statuses();
13011    cx.spawn(async move |lsp_store, cx| {
13012        while let Some((server_name, binary_status)) = server_statuses.next().await {
13013            if lsp_store
13014                .update(cx, |_, cx| {
13015                    let mut message = None;
13016                    let binary_status = match binary_status {
13017                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13018                        BinaryStatus::CheckingForUpdate => {
13019                            proto::ServerBinaryStatus::CheckingForUpdate
13020                        }
13021                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13022                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13023                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13024                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13025                        BinaryStatus::Failed { error } => {
13026                            message = Some(error);
13027                            proto::ServerBinaryStatus::Failed
13028                        }
13029                    };
13030                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13031                        // Binary updates are about the binary that might not have any language server id at that point.
13032                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13033                        language_server_id: LanguageServerId(0),
13034                        name: Some(server_name),
13035                        message: proto::update_language_server::Variant::StatusUpdate(
13036                            proto::StatusUpdate {
13037                                message,
13038                                status: Some(proto::status_update::Status::Binary(
13039                                    binary_status as i32,
13040                                )),
13041                            },
13042                        ),
13043                    });
13044                })
13045                .is_err()
13046            {
13047                break;
13048            }
13049        }
13050    })
13051}
13052
13053fn lsp_workspace_diagnostics_refresh(
13054    registration_id: Option<String>,
13055    options: DiagnosticServerCapabilities,
13056    server: Arc<LanguageServer>,
13057    cx: &mut Context<'_, LspStore>,
13058) -> Option<WorkspaceRefreshTask> {
13059    let identifier = workspace_diagnostic_identifier(&options)?;
13060    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13061
13062    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13063    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13064    refresh_tx.try_send(()).ok();
13065
13066    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13067        let mut attempts = 0;
13068        let max_attempts = 50;
13069        let mut requests = 0;
13070
13071        loop {
13072            let Some(()) = refresh_rx.recv().await else {
13073                return;
13074            };
13075
13076            'request: loop {
13077                requests += 1;
13078                if attempts > max_attempts {
13079                    log::error!(
13080                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13081                    );
13082                    return;
13083                }
13084                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13085                cx.background_executor()
13086                    .timer(Duration::from_millis(backoff_millis))
13087                    .await;
13088                attempts += 1;
13089
13090                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13091                    lsp_store
13092                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13093                        .into_iter()
13094                        .filter_map(|(abs_path, result_id)| {
13095                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13096                            Some(lsp::PreviousResultId {
13097                                uri,
13098                                value: result_id.to_string(),
13099                            })
13100                        })
13101                        .collect()
13102                }) else {
13103                    return;
13104                };
13105
13106                let token = if let Some(registration_id) = &registration_id {
13107                    format!(
13108                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13109                        server.server_id(),
13110                    )
13111                } else {
13112                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13113                };
13114
13115                progress_rx.try_recv().ok();
13116                let timer =
13117                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13118                let progress = pin!(progress_rx.recv().fuse());
13119                let response_result = server
13120                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13121                        lsp::WorkspaceDiagnosticParams {
13122                            previous_result_ids,
13123                            identifier: identifier.clone(),
13124                            work_done_progress_params: Default::default(),
13125                            partial_result_params: lsp::PartialResultParams {
13126                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13127                            },
13128                        },
13129                        select(timer, progress).then(|either| match either {
13130                            Either::Left((message, ..)) => ready(message).left_future(),
13131                            Either::Right(..) => pending::<String>().right_future(),
13132                        }),
13133                    )
13134                    .await;
13135
13136                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13137                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13138                match response_result {
13139                    ConnectionResult::Timeout => {
13140                        log::error!("Timeout during workspace diagnostics pull");
13141                        continue 'request;
13142                    }
13143                    ConnectionResult::ConnectionReset => {
13144                        log::error!("Server closed a workspace diagnostics pull request");
13145                        continue 'request;
13146                    }
13147                    ConnectionResult::Result(Err(e)) => {
13148                        log::error!("Error during workspace diagnostics pull: {e:#}");
13149                        break 'request;
13150                    }
13151                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13152                        attempts = 0;
13153                        if lsp_store
13154                            .update(cx, |lsp_store, cx| {
13155                                lsp_store.apply_workspace_diagnostic_report(
13156                                    server.server_id(),
13157                                    pulled_diagnostics,
13158                                    registration_id_shared.clone(),
13159                                    cx,
13160                                )
13161                            })
13162                            .is_err()
13163                        {
13164                            return;
13165                        }
13166                        break 'request;
13167                    }
13168                }
13169            }
13170        }
13171    });
13172
13173    Some(WorkspaceRefreshTask {
13174        refresh_tx,
13175        progress_tx,
13176        task: workspace_query_language_server,
13177    })
13178}
13179
13180fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13181    match &options {
13182        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13183            diagnostic_options.identifier.clone()
13184        }
13185        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13186            let diagnostic_options = &registration_options.diagnostic_options;
13187            diagnostic_options.identifier.clone()
13188        }
13189    }
13190}
13191
13192fn workspace_diagnostic_identifier(
13193    options: &DiagnosticServerCapabilities,
13194) -> Option<Option<String>> {
13195    match &options {
13196        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13197            if !diagnostic_options.workspace_diagnostics {
13198                return None;
13199            }
13200            Some(diagnostic_options.identifier.clone())
13201        }
13202        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13203            let diagnostic_options = &registration_options.diagnostic_options;
13204            if !diagnostic_options.workspace_diagnostics {
13205                return None;
13206            }
13207            Some(diagnostic_options.identifier.clone())
13208        }
13209    }
13210}
13211
13212fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13213    let CompletionSource::BufferWord {
13214        word_range,
13215        resolved,
13216    } = &mut completion.source
13217    else {
13218        return;
13219    };
13220    if *resolved {
13221        return;
13222    }
13223
13224    if completion.new_text
13225        != snapshot
13226            .text_for_range(word_range.clone())
13227            .collect::<String>()
13228    {
13229        return;
13230    }
13231
13232    let mut offset = 0;
13233    for chunk in snapshot.chunks(word_range.clone(), true) {
13234        let end_offset = offset + chunk.text.len();
13235        if let Some(highlight_id) = chunk.syntax_highlight_id {
13236            completion
13237                .label
13238                .runs
13239                .push((offset..end_offset, highlight_id));
13240        }
13241        offset = end_offset;
13242    }
13243    *resolved = true;
13244}
13245
13246impl EventEmitter<LspStoreEvent> for LspStore {}
13247
13248fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13249    hover
13250        .contents
13251        .retain(|hover_block| !hover_block.text.trim().is_empty());
13252    if hover.contents.is_empty() {
13253        None
13254    } else {
13255        Some(hover)
13256    }
13257}
13258
13259async fn populate_labels_for_completions(
13260    new_completions: Vec<CoreCompletion>,
13261    language: Option<Arc<Language>>,
13262    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13263) -> Vec<Completion> {
13264    let lsp_completions = new_completions
13265        .iter()
13266        .filter_map(|new_completion| {
13267            new_completion
13268                .source
13269                .lsp_completion(true)
13270                .map(|lsp_completion| lsp_completion.into_owned())
13271        })
13272        .collect::<Vec<_>>();
13273
13274    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13275        lsp_adapter
13276            .labels_for_completions(&lsp_completions, language)
13277            .await
13278            .log_err()
13279            .unwrap_or_default()
13280    } else {
13281        Vec::new()
13282    }
13283    .into_iter()
13284    .fuse();
13285
13286    let mut completions = Vec::new();
13287    for completion in new_completions {
13288        match completion.source.lsp_completion(true) {
13289            Some(lsp_completion) => {
13290                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13291
13292                let mut label = labels.next().flatten().unwrap_or_else(|| {
13293                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13294                });
13295                ensure_uniform_list_compatible_label(&mut label);
13296                completions.push(Completion {
13297                    label,
13298                    documentation,
13299                    replace_range: completion.replace_range,
13300                    new_text: completion.new_text,
13301                    insert_text_mode: lsp_completion.insert_text_mode,
13302                    source: completion.source,
13303                    icon_path: None,
13304                    confirm: None,
13305                    match_start: None,
13306                    snippet_deduplication_key: None,
13307                });
13308            }
13309            None => {
13310                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13311                ensure_uniform_list_compatible_label(&mut label);
13312                completions.push(Completion {
13313                    label,
13314                    documentation: None,
13315                    replace_range: completion.replace_range,
13316                    new_text: completion.new_text,
13317                    source: completion.source,
13318                    insert_text_mode: None,
13319                    icon_path: None,
13320                    confirm: None,
13321                    match_start: None,
13322                    snippet_deduplication_key: None,
13323                });
13324            }
13325        }
13326    }
13327    completions
13328}
13329
13330#[derive(Debug)]
13331pub enum LanguageServerToQuery {
13332    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13333    FirstCapable,
13334    /// Query a specific language server.
13335    Other(LanguageServerId),
13336}
13337
13338#[derive(Default)]
13339struct RenamePathsWatchedForServer {
13340    did_rename: Vec<RenameActionPredicate>,
13341    will_rename: Vec<RenameActionPredicate>,
13342}
13343
13344impl RenamePathsWatchedForServer {
13345    fn with_did_rename_patterns(
13346        mut self,
13347        did_rename: Option<&FileOperationRegistrationOptions>,
13348    ) -> Self {
13349        if let Some(did_rename) = did_rename {
13350            self.did_rename = did_rename
13351                .filters
13352                .iter()
13353                .filter_map(|filter| filter.try_into().log_err())
13354                .collect();
13355        }
13356        self
13357    }
13358    fn with_will_rename_patterns(
13359        mut self,
13360        will_rename: Option<&FileOperationRegistrationOptions>,
13361    ) -> Self {
13362        if let Some(will_rename) = will_rename {
13363            self.will_rename = will_rename
13364                .filters
13365                .iter()
13366                .filter_map(|filter| filter.try_into().log_err())
13367                .collect();
13368        }
13369        self
13370    }
13371
13372    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13373        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13374    }
13375    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13376        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13377    }
13378}
13379
13380impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13381    type Error = globset::Error;
13382    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13383        Ok(Self {
13384            kind: ops.pattern.matches.clone(),
13385            glob: GlobBuilder::new(&ops.pattern.glob)
13386                .case_insensitive(
13387                    ops.pattern
13388                        .options
13389                        .as_ref()
13390                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13391                )
13392                .build()?
13393                .compile_matcher(),
13394        })
13395    }
13396}
13397struct RenameActionPredicate {
13398    glob: GlobMatcher,
13399    kind: Option<FileOperationPatternKind>,
13400}
13401
13402impl RenameActionPredicate {
13403    // Returns true if language server should be notified
13404    fn eval(&self, path: &str, is_dir: bool) -> bool {
13405        self.kind.as_ref().is_none_or(|kind| {
13406            let expected_kind = if is_dir {
13407                FileOperationPatternKind::Folder
13408            } else {
13409                FileOperationPatternKind::File
13410            };
13411            kind == &expected_kind
13412        }) && self.glob.is_match(path)
13413    }
13414}
13415
13416#[derive(Default)]
13417struct LanguageServerWatchedPaths {
13418    worktree_paths: HashMap<WorktreeId, GlobSet>,
13419    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13420}
13421
13422#[derive(Default)]
13423struct LanguageServerWatchedPathsBuilder {
13424    worktree_paths: HashMap<WorktreeId, GlobSet>,
13425    abs_paths: HashMap<Arc<Path>, GlobSet>,
13426}
13427
13428impl LanguageServerWatchedPathsBuilder {
13429    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13430        self.worktree_paths.insert(worktree_id, glob_set);
13431    }
13432    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13433        self.abs_paths.insert(path, glob_set);
13434    }
13435    fn build(
13436        self,
13437        fs: Arc<dyn Fs>,
13438        language_server_id: LanguageServerId,
13439        cx: &mut Context<LspStore>,
13440    ) -> LanguageServerWatchedPaths {
13441        let lsp_store = cx.weak_entity();
13442
13443        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13444        let abs_paths = self
13445            .abs_paths
13446            .into_iter()
13447            .map(|(abs_path, globset)| {
13448                let task = cx.spawn({
13449                    let abs_path = abs_path.clone();
13450                    let fs = fs.clone();
13451
13452                    let lsp_store = lsp_store.clone();
13453                    async move |_, cx| {
13454                        maybe!(async move {
13455                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13456                            while let Some(update) = push_updates.0.next().await {
13457                                let action = lsp_store
13458                                    .update(cx, |this, _| {
13459                                        let Some(local) = this.as_local() else {
13460                                            return ControlFlow::Break(());
13461                                        };
13462                                        let Some(watcher) = local
13463                                            .language_server_watched_paths
13464                                            .get(&language_server_id)
13465                                        else {
13466                                            return ControlFlow::Break(());
13467                                        };
13468                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13469                                            "Watched abs path is not registered with a watcher",
13470                                        );
13471                                        let matching_entries = update
13472                                            .into_iter()
13473                                            .filter(|event| globs.is_match(&event.path))
13474                                            .collect::<Vec<_>>();
13475                                        this.lsp_notify_abs_paths_changed(
13476                                            language_server_id,
13477                                            matching_entries,
13478                                        );
13479                                        ControlFlow::Continue(())
13480                                    })
13481                                    .ok()?;
13482
13483                                if action.is_break() {
13484                                    break;
13485                                }
13486                            }
13487                            Some(())
13488                        })
13489                        .await;
13490                    }
13491                });
13492                (abs_path, (globset, task))
13493            })
13494            .collect();
13495        LanguageServerWatchedPaths {
13496            worktree_paths: self.worktree_paths,
13497            abs_paths,
13498        }
13499    }
13500}
13501
13502struct LspBufferSnapshot {
13503    version: i32,
13504    snapshot: TextBufferSnapshot,
13505}
13506
13507/// A prompt requested by LSP server.
13508#[derive(Clone, Debug)]
13509pub struct LanguageServerPromptRequest {
13510    pub level: PromptLevel,
13511    pub message: String,
13512    pub actions: Vec<MessageActionItem>,
13513    pub lsp_name: String,
13514    pub(crate) response_channel: Sender<MessageActionItem>,
13515}
13516
13517impl LanguageServerPromptRequest {
13518    pub async fn respond(self, index: usize) -> Option<()> {
13519        if let Some(response) = self.actions.into_iter().nth(index) {
13520            self.response_channel.send(response).await.ok()
13521        } else {
13522            None
13523        }
13524    }
13525}
13526impl PartialEq for LanguageServerPromptRequest {
13527    fn eq(&self, other: &Self) -> bool {
13528        self.message == other.message && self.actions == other.actions
13529    }
13530}
13531
13532#[derive(Clone, Debug, PartialEq)]
13533pub enum LanguageServerLogType {
13534    Log(MessageType),
13535    Trace { verbose_info: Option<String> },
13536    Rpc { received: bool },
13537}
13538
13539impl LanguageServerLogType {
13540    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13541        match self {
13542            Self::Log(log_type) => {
13543                use proto::log_message::LogLevel;
13544                let level = match *log_type {
13545                    MessageType::ERROR => LogLevel::Error,
13546                    MessageType::WARNING => LogLevel::Warning,
13547                    MessageType::INFO => LogLevel::Info,
13548                    MessageType::LOG => LogLevel::Log,
13549                    other => {
13550                        log::warn!("Unknown lsp log message type: {other:?}");
13551                        LogLevel::Log
13552                    }
13553                };
13554                proto::language_server_log::LogType::Log(proto::LogMessage {
13555                    level: level as i32,
13556                })
13557            }
13558            Self::Trace { verbose_info } => {
13559                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13560                    verbose_info: verbose_info.to_owned(),
13561                })
13562            }
13563            Self::Rpc { received } => {
13564                let kind = if *received {
13565                    proto::rpc_message::Kind::Received
13566                } else {
13567                    proto::rpc_message::Kind::Sent
13568                };
13569                let kind = kind as i32;
13570                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13571            }
13572        }
13573    }
13574
13575    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13576        use proto::log_message::LogLevel;
13577        use proto::rpc_message;
13578        match log_type {
13579            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13580                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13581                    LogLevel::Error => MessageType::ERROR,
13582                    LogLevel::Warning => MessageType::WARNING,
13583                    LogLevel::Info => MessageType::INFO,
13584                    LogLevel::Log => MessageType::LOG,
13585                },
13586            ),
13587            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13588                verbose_info: trace_message.verbose_info,
13589            },
13590            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13591                received: match rpc_message::Kind::from_i32(message.kind)
13592                    .unwrap_or(rpc_message::Kind::Received)
13593                {
13594                    rpc_message::Kind::Received => true,
13595                    rpc_message::Kind::Sent => false,
13596                },
13597            },
13598        }
13599    }
13600}
13601
13602pub struct WorkspaceRefreshTask {
13603    refresh_tx: mpsc::Sender<()>,
13604    progress_tx: mpsc::Sender<()>,
13605    #[allow(dead_code)]
13606    task: Task<()>,
13607}
13608
13609pub enum LanguageServerState {
13610    Starting {
13611        startup: Task<Option<Arc<LanguageServer>>>,
13612        /// List of language servers that will be added to the workspace once it's initialization completes.
13613        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13614    },
13615
13616    Running {
13617        adapter: Arc<CachedLspAdapter>,
13618        server: Arc<LanguageServer>,
13619        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13620        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13621    },
13622}
13623
13624impl LanguageServerState {
13625    fn add_workspace_folder(&self, uri: Uri) {
13626        match self {
13627            LanguageServerState::Starting {
13628                pending_workspace_folders,
13629                ..
13630            } => {
13631                pending_workspace_folders.lock().insert(uri);
13632            }
13633            LanguageServerState::Running { server, .. } => {
13634                server.add_workspace_folder(uri);
13635            }
13636        }
13637    }
13638    fn _remove_workspace_folder(&self, uri: Uri) {
13639        match self {
13640            LanguageServerState::Starting {
13641                pending_workspace_folders,
13642                ..
13643            } => {
13644                pending_workspace_folders.lock().remove(&uri);
13645            }
13646            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13647        }
13648    }
13649}
13650
13651impl std::fmt::Debug for LanguageServerState {
13652    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13653        match self {
13654            LanguageServerState::Starting { .. } => {
13655                f.debug_struct("LanguageServerState::Starting").finish()
13656            }
13657            LanguageServerState::Running { .. } => {
13658                f.debug_struct("LanguageServerState::Running").finish()
13659            }
13660        }
13661    }
13662}
13663
13664#[derive(Clone, Debug, Serialize)]
13665pub struct LanguageServerProgress {
13666    pub is_disk_based_diagnostics_progress: bool,
13667    pub is_cancellable: bool,
13668    pub title: Option<String>,
13669    pub message: Option<String>,
13670    pub percentage: Option<usize>,
13671    #[serde(skip_serializing)]
13672    pub last_update_at: Instant,
13673}
13674
13675#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13676pub struct DiagnosticSummary {
13677    pub error_count: usize,
13678    pub warning_count: usize,
13679}
13680
13681impl DiagnosticSummary {
13682    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13683        let mut this = Self {
13684            error_count: 0,
13685            warning_count: 0,
13686        };
13687
13688        for entry in diagnostics {
13689            if entry.diagnostic.is_primary {
13690                match entry.diagnostic.severity {
13691                    DiagnosticSeverity::ERROR => this.error_count += 1,
13692                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13693                    _ => {}
13694                }
13695            }
13696        }
13697
13698        this
13699    }
13700
13701    pub fn is_empty(&self) -> bool {
13702        self.error_count == 0 && self.warning_count == 0
13703    }
13704
13705    pub fn to_proto(
13706        self,
13707        language_server_id: LanguageServerId,
13708        path: &RelPath,
13709    ) -> proto::DiagnosticSummary {
13710        proto::DiagnosticSummary {
13711            path: path.to_proto(),
13712            language_server_id: language_server_id.0 as u64,
13713            error_count: self.error_count as u32,
13714            warning_count: self.warning_count as u32,
13715        }
13716    }
13717}
13718
13719#[derive(Clone, Debug)]
13720pub enum CompletionDocumentation {
13721    /// There is no documentation for this completion.
13722    Undocumented,
13723    /// A single line of documentation.
13724    SingleLine(SharedString),
13725    /// Multiple lines of plain text documentation.
13726    MultiLinePlainText(SharedString),
13727    /// Markdown documentation.
13728    MultiLineMarkdown(SharedString),
13729    /// Both single line and multiple lines of plain text documentation.
13730    SingleLineAndMultiLinePlainText {
13731        single_line: SharedString,
13732        plain_text: Option<SharedString>,
13733    },
13734}
13735
13736impl CompletionDocumentation {
13737    #[cfg(any(test, feature = "test-support"))]
13738    pub fn text(&self) -> SharedString {
13739        match self {
13740            CompletionDocumentation::Undocumented => "".into(),
13741            CompletionDocumentation::SingleLine(s) => s.clone(),
13742            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13743            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13744            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13745                single_line.clone()
13746            }
13747        }
13748    }
13749}
13750
13751impl From<lsp::Documentation> for CompletionDocumentation {
13752    fn from(docs: lsp::Documentation) -> Self {
13753        match docs {
13754            lsp::Documentation::String(text) => {
13755                if text.lines().count() <= 1 {
13756                    CompletionDocumentation::SingleLine(text.into())
13757                } else {
13758                    CompletionDocumentation::MultiLinePlainText(text.into())
13759                }
13760            }
13761
13762            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13763                lsp::MarkupKind::PlainText => {
13764                    if value.lines().count() <= 1 {
13765                        CompletionDocumentation::SingleLine(value.into())
13766                    } else {
13767                        CompletionDocumentation::MultiLinePlainText(value.into())
13768                    }
13769                }
13770
13771                lsp::MarkupKind::Markdown => {
13772                    CompletionDocumentation::MultiLineMarkdown(value.into())
13773                }
13774            },
13775        }
13776    }
13777}
13778
13779pub enum ResolvedHint {
13780    Resolved(InlayHint),
13781    Resolving(Shared<Task<()>>),
13782}
13783
13784fn glob_literal_prefix(glob: &Path) -> PathBuf {
13785    glob.components()
13786        .take_while(|component| match component {
13787            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13788            _ => true,
13789        })
13790        .collect()
13791}
13792
13793pub struct SshLspAdapter {
13794    name: LanguageServerName,
13795    binary: LanguageServerBinary,
13796    initialization_options: Option<String>,
13797    code_action_kinds: Option<Vec<CodeActionKind>>,
13798}
13799
13800impl SshLspAdapter {
13801    pub fn new(
13802        name: LanguageServerName,
13803        binary: LanguageServerBinary,
13804        initialization_options: Option<String>,
13805        code_action_kinds: Option<String>,
13806    ) -> Self {
13807        Self {
13808            name,
13809            binary,
13810            initialization_options,
13811            code_action_kinds: code_action_kinds
13812                .as_ref()
13813                .and_then(|c| serde_json::from_str(c).ok()),
13814        }
13815    }
13816}
13817
13818impl LspInstaller for SshLspAdapter {
13819    type BinaryVersion = ();
13820    async fn check_if_user_installed(
13821        &self,
13822        _: &dyn LspAdapterDelegate,
13823        _: Option<Toolchain>,
13824        _: &AsyncApp,
13825    ) -> Option<LanguageServerBinary> {
13826        Some(self.binary.clone())
13827    }
13828
13829    async fn cached_server_binary(
13830        &self,
13831        _: PathBuf,
13832        _: &dyn LspAdapterDelegate,
13833    ) -> Option<LanguageServerBinary> {
13834        None
13835    }
13836
13837    async fn fetch_latest_server_version(
13838        &self,
13839        _: &dyn LspAdapterDelegate,
13840        _: bool,
13841        _: &mut AsyncApp,
13842    ) -> Result<()> {
13843        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13844    }
13845
13846    async fn fetch_server_binary(
13847        &self,
13848        _: (),
13849        _: PathBuf,
13850        _: &dyn LspAdapterDelegate,
13851    ) -> Result<LanguageServerBinary> {
13852        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13853    }
13854}
13855
13856#[async_trait(?Send)]
13857impl LspAdapter for SshLspAdapter {
13858    fn name(&self) -> LanguageServerName {
13859        self.name.clone()
13860    }
13861
13862    async fn initialization_options(
13863        self: Arc<Self>,
13864        _: &Arc<dyn LspAdapterDelegate>,
13865    ) -> Result<Option<serde_json::Value>> {
13866        let Some(options) = &self.initialization_options else {
13867            return Ok(None);
13868        };
13869        let result = serde_json::from_str(options)?;
13870        Ok(result)
13871    }
13872
13873    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13874        self.code_action_kinds.clone()
13875    }
13876}
13877
13878pub fn language_server_settings<'a>(
13879    delegate: &'a dyn LspAdapterDelegate,
13880    language: &LanguageServerName,
13881    cx: &'a App,
13882) -> Option<&'a LspSettings> {
13883    language_server_settings_for(
13884        SettingsLocation {
13885            worktree_id: delegate.worktree_id(),
13886            path: RelPath::empty(),
13887        },
13888        language,
13889        cx,
13890    )
13891}
13892
13893pub fn language_server_settings_for<'a>(
13894    location: SettingsLocation<'a>,
13895    language: &LanguageServerName,
13896    cx: &'a App,
13897) -> Option<&'a LspSettings> {
13898    ProjectSettings::get(Some(location), cx).lsp.get(language)
13899}
13900
13901pub struct LocalLspAdapterDelegate {
13902    lsp_store: WeakEntity<LspStore>,
13903    worktree: worktree::Snapshot,
13904    fs: Arc<dyn Fs>,
13905    http_client: Arc<dyn HttpClient>,
13906    language_registry: Arc<LanguageRegistry>,
13907    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13908}
13909
13910impl LocalLspAdapterDelegate {
13911    pub fn new(
13912        language_registry: Arc<LanguageRegistry>,
13913        environment: &Entity<ProjectEnvironment>,
13914        lsp_store: WeakEntity<LspStore>,
13915        worktree: &Entity<Worktree>,
13916        http_client: Arc<dyn HttpClient>,
13917        fs: Arc<dyn Fs>,
13918        cx: &mut App,
13919    ) -> Arc<Self> {
13920        let load_shell_env_task =
13921            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
13922
13923        Arc::new(Self {
13924            lsp_store,
13925            worktree: worktree.read(cx).snapshot(),
13926            fs,
13927            http_client,
13928            language_registry,
13929            load_shell_env_task,
13930        })
13931    }
13932
13933    fn from_local_lsp(
13934        local: &LocalLspStore,
13935        worktree: &Entity<Worktree>,
13936        cx: &mut App,
13937    ) -> Arc<Self> {
13938        Self::new(
13939            local.languages.clone(),
13940            &local.environment,
13941            local.weak.clone(),
13942            worktree,
13943            local.http_client.clone(),
13944            local.fs.clone(),
13945            cx,
13946        )
13947    }
13948}
13949
13950#[async_trait]
13951impl LspAdapterDelegate for LocalLspAdapterDelegate {
13952    fn show_notification(&self, message: &str, cx: &mut App) {
13953        self.lsp_store
13954            .update(cx, |_, cx| {
13955                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13956            })
13957            .ok();
13958    }
13959
13960    fn http_client(&self) -> Arc<dyn HttpClient> {
13961        self.http_client.clone()
13962    }
13963
13964    fn worktree_id(&self) -> WorktreeId {
13965        self.worktree.id()
13966    }
13967
13968    fn worktree_root_path(&self) -> &Path {
13969        self.worktree.abs_path().as_ref()
13970    }
13971
13972    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
13973        self.worktree.resolve_executable_path(path)
13974    }
13975
13976    async fn shell_env(&self) -> HashMap<String, String> {
13977        let task = self.load_shell_env_task.clone();
13978        task.await.unwrap_or_default()
13979    }
13980
13981    async fn npm_package_installed_version(
13982        &self,
13983        package_name: &str,
13984    ) -> Result<Option<(PathBuf, String)>> {
13985        let local_package_directory = self.worktree_root_path();
13986        let node_modules_directory = local_package_directory.join("node_modules");
13987
13988        if let Some(version) =
13989            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13990        {
13991            return Ok(Some((node_modules_directory, version)));
13992        }
13993        let Some(npm) = self.which("npm".as_ref()).await else {
13994            log::warn!(
13995                "Failed to find npm executable for {:?}",
13996                local_package_directory
13997            );
13998            return Ok(None);
13999        };
14000
14001        let env = self.shell_env().await;
14002        let output = util::command::new_smol_command(&npm)
14003            .args(["root", "-g"])
14004            .envs(env)
14005            .current_dir(local_package_directory)
14006            .output()
14007            .await?;
14008        let global_node_modules =
14009            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14010
14011        if let Some(version) =
14012            read_package_installed_version(global_node_modules.clone(), package_name).await?
14013        {
14014            return Ok(Some((global_node_modules, version)));
14015        }
14016        return Ok(None);
14017    }
14018
14019    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14020        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14021        if self.fs.is_file(&worktree_abs_path).await {
14022            worktree_abs_path.pop();
14023        }
14024
14025        let env = self.shell_env().await;
14026
14027        let shell_path = env.get("PATH").cloned();
14028
14029        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14030    }
14031
14032    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14033        let mut working_dir = self.worktree_root_path().to_path_buf();
14034        if self.fs.is_file(&working_dir).await {
14035            working_dir.pop();
14036        }
14037        let output = util::command::new_smol_command(&command.path)
14038            .args(command.arguments)
14039            .envs(command.env.clone().unwrap_or_default())
14040            .current_dir(working_dir)
14041            .output()
14042            .await?;
14043
14044        anyhow::ensure!(
14045            output.status.success(),
14046            "{}, stdout: {:?}, stderr: {:?}",
14047            output.status,
14048            String::from_utf8_lossy(&output.stdout),
14049            String::from_utf8_lossy(&output.stderr)
14050        );
14051        Ok(())
14052    }
14053
14054    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14055        self.language_registry
14056            .update_lsp_binary_status(server_name, status);
14057    }
14058
14059    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14060        self.language_registry
14061            .all_lsp_adapters()
14062            .into_iter()
14063            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14064            .collect()
14065    }
14066
14067    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14068        let dir = self.language_registry.language_server_download_dir(name)?;
14069
14070        if !dir.exists() {
14071            smol::fs::create_dir_all(&dir)
14072                .await
14073                .context("failed to create container directory")
14074                .log_err()?;
14075        }
14076
14077        Some(dir)
14078    }
14079
14080    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14081        let entry = self
14082            .worktree
14083            .entry_for_path(path)
14084            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14085        let abs_path = self.worktree.absolutize(&entry.path);
14086        self.fs.load(&abs_path).await
14087    }
14088}
14089
14090async fn populate_labels_for_symbols(
14091    symbols: Vec<CoreSymbol>,
14092    language_registry: &Arc<LanguageRegistry>,
14093    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14094    output: &mut Vec<Symbol>,
14095) {
14096    #[allow(clippy::mutable_key_type)]
14097    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14098
14099    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14100    for symbol in symbols {
14101        let Some(file_name) = symbol.path.file_name() else {
14102            continue;
14103        };
14104        let language = language_registry
14105            .load_language_for_file_path(Path::new(file_name))
14106            .await
14107            .ok()
14108            .or_else(|| {
14109                unknown_paths.insert(file_name.into());
14110                None
14111            });
14112        symbols_by_language
14113            .entry(language)
14114            .or_default()
14115            .push(symbol);
14116    }
14117
14118    for unknown_path in unknown_paths {
14119        log::info!("no language found for symbol in file {unknown_path:?}");
14120    }
14121
14122    let mut label_params = Vec::new();
14123    for (language, mut symbols) in symbols_by_language {
14124        label_params.clear();
14125        label_params.extend(
14126            symbols
14127                .iter_mut()
14128                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14129        );
14130
14131        let mut labels = Vec::new();
14132        if let Some(language) = language {
14133            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14134                language_registry
14135                    .lsp_adapters(&language.name())
14136                    .first()
14137                    .cloned()
14138            });
14139            if let Some(lsp_adapter) = lsp_adapter {
14140                labels = lsp_adapter
14141                    .labels_for_symbols(&label_params, &language)
14142                    .await
14143                    .log_err()
14144                    .unwrap_or_default();
14145            }
14146        }
14147
14148        for ((symbol, (name, _)), label) in symbols
14149            .into_iter()
14150            .zip(label_params.drain(..))
14151            .zip(labels.into_iter().chain(iter::repeat(None)))
14152        {
14153            output.push(Symbol {
14154                language_server_name: symbol.language_server_name,
14155                source_worktree_id: symbol.source_worktree_id,
14156                source_language_server_id: symbol.source_language_server_id,
14157                path: symbol.path,
14158                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14159                name,
14160                kind: symbol.kind,
14161                range: symbol.range,
14162            });
14163        }
14164    }
14165}
14166
14167fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14168    match server.capabilities().text_document_sync.as_ref()? {
14169        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14170            // Server wants didSave but didn't specify includeText.
14171            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14172            // Server doesn't want didSave at all.
14173            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14174            // Server provided SaveOptions.
14175            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14176                Some(save_options.include_text.unwrap_or(false))
14177            }
14178        },
14179        // We do not have any save info. Kind affects didChange only.
14180        lsp::TextDocumentSyncCapability::Kind(_) => None,
14181    }
14182}
14183
14184/// Completion items are displayed in a `UniformList`.
14185/// Usually, those items are single-line strings, but in LSP responses,
14186/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14187/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14188/// 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,
14189/// breaking the completions menu presentation.
14190///
14191/// 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.
14192fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14193    let mut new_text = String::with_capacity(label.text.len());
14194    let mut offset_map = vec![0; label.text.len() + 1];
14195    let mut last_char_was_space = false;
14196    let mut new_idx = 0;
14197    let chars = label.text.char_indices().fuse();
14198    let mut newlines_removed = false;
14199
14200    for (idx, c) in chars {
14201        offset_map[idx] = new_idx;
14202
14203        match c {
14204            '\n' if last_char_was_space => {
14205                newlines_removed = true;
14206            }
14207            '\t' | ' ' if last_char_was_space => {}
14208            '\n' if !last_char_was_space => {
14209                new_text.push(' ');
14210                new_idx += 1;
14211                last_char_was_space = true;
14212                newlines_removed = true;
14213            }
14214            ' ' | '\t' => {
14215                new_text.push(' ');
14216                new_idx += 1;
14217                last_char_was_space = true;
14218            }
14219            _ => {
14220                new_text.push(c);
14221                new_idx += c.len_utf8();
14222                last_char_was_space = false;
14223            }
14224        }
14225    }
14226    offset_map[label.text.len()] = new_idx;
14227
14228    // Only modify the label if newlines were removed.
14229    if !newlines_removed {
14230        return;
14231    }
14232
14233    let last_index = new_idx;
14234    let mut run_ranges_errors = Vec::new();
14235    label.runs.retain_mut(|(range, _)| {
14236        match offset_map.get(range.start) {
14237            Some(&start) => range.start = start,
14238            None => {
14239                run_ranges_errors.push(range.clone());
14240                return false;
14241            }
14242        }
14243
14244        match offset_map.get(range.end) {
14245            Some(&end) => range.end = end,
14246            None => {
14247                run_ranges_errors.push(range.clone());
14248                range.end = last_index;
14249            }
14250        }
14251        true
14252    });
14253    if !run_ranges_errors.is_empty() {
14254        log::error!(
14255            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14256            label.text
14257        );
14258    }
14259
14260    let mut wrong_filter_range = None;
14261    if label.filter_range == (0..label.text.len()) {
14262        label.filter_range = 0..new_text.len();
14263    } else {
14264        let mut original_filter_range = Some(label.filter_range.clone());
14265        match offset_map.get(label.filter_range.start) {
14266            Some(&start) => label.filter_range.start = start,
14267            None => {
14268                wrong_filter_range = original_filter_range.take();
14269                label.filter_range.start = last_index;
14270            }
14271        }
14272
14273        match offset_map.get(label.filter_range.end) {
14274            Some(&end) => label.filter_range.end = end,
14275            None => {
14276                wrong_filter_range = original_filter_range.take();
14277                label.filter_range.end = last_index;
14278            }
14279        }
14280    }
14281    if let Some(wrong_filter_range) = wrong_filter_range {
14282        log::error!(
14283            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14284            label.text
14285        );
14286    }
14287
14288    label.text = new_text;
14289}
14290
14291#[cfg(test)]
14292mod tests {
14293    use language::HighlightId;
14294
14295    use super::*;
14296
14297    #[test]
14298    fn test_glob_literal_prefix() {
14299        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14300        assert_eq!(
14301            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14302            Path::new("node_modules")
14303        );
14304        assert_eq!(
14305            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14306            Path::new("foo")
14307        );
14308        assert_eq!(
14309            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14310            Path::new("foo/bar/baz.js")
14311        );
14312
14313        #[cfg(target_os = "windows")]
14314        {
14315            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14316            assert_eq!(
14317                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14318                Path::new("node_modules")
14319            );
14320            assert_eq!(
14321                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14322                Path::new("foo")
14323            );
14324            assert_eq!(
14325                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14326                Path::new("foo/bar/baz.js")
14327            );
14328        }
14329    }
14330
14331    #[test]
14332    fn test_multi_len_chars_normalization() {
14333        let mut label = CodeLabel::new(
14334            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14335            0..6,
14336            vec![(0..6, HighlightId(1))],
14337        );
14338        ensure_uniform_list_compatible_label(&mut label);
14339        assert_eq!(
14340            label,
14341            CodeLabel::new(
14342                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14343                0..6,
14344                vec![(0..6, HighlightId(1))],
14345            )
14346        );
14347    }
14348}