lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13pub mod json_language_server_ext;
   14pub mod log_store;
   15pub mod lsp_ext_command;
   16pub mod rust_analyzer_ext;
   17pub mod vue_language_server_ext;
   18
   19mod inlay_hint_cache;
   20
   21use self::inlay_hint_cache::BufferInlayHints;
   22use crate::{
   23    CodeAction, ColorPresentation, Completion, CompletionDisplayOptions, CompletionResponse,
   24    CompletionSource, CoreCompletion, DocumentColor, Hover, InlayHint, InlayId, LocationLink,
   25    LspAction, LspPullDiagnostics, ManifestProvidersStore, Project, ProjectItem, ProjectPath,
   26    ProjectTransaction, PulledDiagnostics, ResolveState, Symbol,
   27    buffer_store::{BufferStore, BufferStoreEvent},
   28    environment::ProjectEnvironment,
   29    lsp_command::{self, *},
   30    lsp_store::{
   31        self,
   32        log_store::{GlobalLogStore, LanguageServerKind},
   33    },
   34    manifest_tree::{
   35        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   36        ManifestTree,
   37    },
   38    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   39    project_settings::{LspSettings, ProjectSettings},
   40    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   41    trusted_worktrees::{PathTrust, TrustedWorktrees, TrustedWorktreesEvent},
   42    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   43    yarn::YarnPathStore,
   44};
   45use anyhow::{Context as _, Result, anyhow};
   46use async_trait::async_trait;
   47use client::{TypedEnvelope, proto};
   48use clock::Global;
   49use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   50use futures::{
   51    AsyncWriteExt, Future, FutureExt, StreamExt,
   52    future::{Either, Shared, join_all, pending, select},
   53    select, select_biased,
   54    stream::FuturesUnordered,
   55};
   56use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   57use gpui::{
   58    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString,
   59    Subscription, Task, WeakEntity,
   60};
   61use http_client::HttpClient;
   62use itertools::Itertools as _;
   63use language::{
   64    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   65    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   66    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate,
   67    ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Toolchain,
   68    Transaction, Unclipped,
   69    language_settings::{FormatOnSave, Formatter, LanguageSettings, language_settings},
   70    point_to_lsp,
   71    proto::{
   72        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   73        serialize_lsp_edit, serialize_version,
   74    },
   75    range_from_lsp, range_to_lsp,
   76    row_chunk::RowChunk,
   77};
   78use lsp::{
   79    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   80    DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   81    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   82    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LSP_REQUEST_TIMEOUT,
   83    LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId,
   84    LanguageServerName, LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType,
   85    OneOf, RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri,
   86    WillRenameFiles, WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   87};
   88use node_runtime::read_package_installed_version;
   89use parking_lot::Mutex;
   90use postage::{mpsc, sink::Sink, stream::Stream, watch};
   91use rand::prelude::*;
   92use rpc::{
   93    AnyProtoClient, ErrorCode, ErrorExt as _,
   94    proto::{LspRequestId, LspRequestMessage as _},
   95};
   96use semver::Version;
   97use serde::Serialize;
   98use serde_json::Value;
   99use settings::{Settings, SettingsLocation, SettingsStore};
  100use sha2::{Digest, Sha256};
  101use smol::channel::{Receiver, Sender};
  102use snippet::Snippet;
  103use std::{
  104    any::TypeId,
  105    borrow::Cow,
  106    cell::RefCell,
  107    cmp::{Ordering, Reverse},
  108    collections::hash_map,
  109    convert::TryInto,
  110    ffi::OsStr,
  111    future::ready,
  112    iter, mem,
  113    ops::{ControlFlow, Range},
  114    path::{self, Path, PathBuf},
  115    pin::pin,
  116    rc::Rc,
  117    sync::{
  118        Arc,
  119        atomic::{self, AtomicUsize},
  120    },
  121    time::{Duration, Instant},
  122    vec,
  123};
  124use sum_tree::Dimensions;
  125use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  126
  127use util::{
  128    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  129    paths::{PathStyle, SanitizedPath},
  130    post_inc,
  131    rel_path::RelPath,
  132};
  133
  134pub use fs::*;
  135pub use language::Location;
  136pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  137#[cfg(any(test, feature = "test-support"))]
  138pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  139pub use worktree::{
  140    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  141    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  142};
  143
  144const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  145pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  146const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  147const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  148
  149#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  150pub enum ProgressToken {
  151    Number(i32),
  152    String(SharedString),
  153}
  154
  155impl std::fmt::Display for ProgressToken {
  156    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  157        match self {
  158            Self::Number(number) => write!(f, "{number}"),
  159            Self::String(string) => write!(f, "{string}"),
  160        }
  161    }
  162}
  163
  164impl ProgressToken {
  165    fn from_lsp(value: lsp::NumberOrString) -> Self {
  166        match value {
  167            lsp::NumberOrString::Number(number) => Self::Number(number),
  168            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  169        }
  170    }
  171
  172    fn to_lsp(&self) -> lsp::NumberOrString {
  173        match self {
  174            Self::Number(number) => lsp::NumberOrString::Number(*number),
  175            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  176        }
  177    }
  178
  179    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  180        Some(match value.value? {
  181            proto::progress_token::Value::Number(number) => Self::Number(number),
  182            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  183        })
  184    }
  185
  186    fn to_proto(&self) -> proto::ProgressToken {
  187        proto::ProgressToken {
  188            value: Some(match self {
  189                Self::Number(number) => proto::progress_token::Value::Number(*number),
  190                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  191            }),
  192        }
  193    }
  194}
  195
  196#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  197pub enum FormatTrigger {
  198    Save,
  199    Manual,
  200}
  201
  202pub enum LspFormatTarget {
  203    Buffers,
  204    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  205}
  206
  207#[derive(Clone, PartialEq, Eq, Hash)]
  208pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  209
  210struct OpenLspBuffer(Entity<Buffer>);
  211
  212impl FormatTrigger {
  213    fn from_proto(value: i32) -> FormatTrigger {
  214        match value {
  215            0 => FormatTrigger::Save,
  216            1 => FormatTrigger::Manual,
  217            _ => FormatTrigger::Save,
  218        }
  219    }
  220}
  221
  222#[derive(Clone)]
  223struct UnifiedLanguageServer {
  224    id: LanguageServerId,
  225    project_roots: HashSet<Arc<RelPath>>,
  226}
  227
  228#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  229struct LanguageServerSeed {
  230    worktree_id: WorktreeId,
  231    name: LanguageServerName,
  232    toolchain: Option<Toolchain>,
  233    settings: Arc<LspSettings>,
  234}
  235
  236#[derive(Debug)]
  237pub struct DocumentDiagnosticsUpdate<'a, D> {
  238    pub diagnostics: D,
  239    pub result_id: Option<SharedString>,
  240    pub registration_id: Option<SharedString>,
  241    pub server_id: LanguageServerId,
  242    pub disk_based_sources: Cow<'a, [String]>,
  243}
  244
  245pub struct DocumentDiagnostics {
  246    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  247    document_abs_path: PathBuf,
  248    version: Option<i32>,
  249}
  250
  251#[derive(Default, Debug)]
  252struct DynamicRegistrations {
  253    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  254    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  255}
  256
  257pub struct LocalLspStore {
  258    weak: WeakEntity<LspStore>,
  259    worktree_store: Entity<WorktreeStore>,
  260    toolchain_store: Entity<LocalToolchainStore>,
  261    http_client: Arc<dyn HttpClient>,
  262    environment: Entity<ProjectEnvironment>,
  263    fs: Arc<dyn Fs>,
  264    languages: Arc<LanguageRegistry>,
  265    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  266    yarn: Entity<YarnPathStore>,
  267    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  268    buffers_being_formatted: HashSet<BufferId>,
  269    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  270    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  271    watched_manifest_filenames: HashSet<ManifestName>,
  272    language_server_paths_watched_for_rename:
  273        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  274    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  275    supplementary_language_servers:
  276        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  277    prettier_store: Entity<PrettierStore>,
  278    next_diagnostic_group_id: usize,
  279    diagnostics: HashMap<
  280        WorktreeId,
  281        HashMap<
  282            Arc<RelPath>,
  283            Vec<(
  284                LanguageServerId,
  285                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  286            )>,
  287        >,
  288    >,
  289    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  290    _subscription: gpui::Subscription,
  291    lsp_tree: LanguageServerTree,
  292    registered_buffers: HashMap<BufferId, usize>,
  293    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  294    buffer_pull_diagnostics_result_ids: HashMap<
  295        LanguageServerId,
  296        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  297    >,
  298    workspace_pull_diagnostics_result_ids: HashMap<
  299        LanguageServerId,
  300        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  301    >,
  302    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, Receiver<()>)>,
  303}
  304
  305impl LocalLspStore {
  306    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  307    pub fn running_language_server_for_id(
  308        &self,
  309        id: LanguageServerId,
  310    ) -> Option<&Arc<LanguageServer>> {
  311        let language_server_state = self.language_servers.get(&id)?;
  312
  313        match language_server_state {
  314            LanguageServerState::Running { server, .. } => Some(server),
  315            LanguageServerState::Starting { .. } => None,
  316        }
  317    }
  318
  319    fn get_or_insert_language_server(
  320        &mut self,
  321        worktree_handle: &Entity<Worktree>,
  322        delegate: Arc<LocalLspAdapterDelegate>,
  323        disposition: &Arc<LaunchDisposition>,
  324        language_name: &LanguageName,
  325        cx: &mut App,
  326    ) -> LanguageServerId {
  327        let key = LanguageServerSeed {
  328            worktree_id: worktree_handle.read(cx).id(),
  329            name: disposition.server_name.clone(),
  330            settings: disposition.settings.clone(),
  331            toolchain: disposition.toolchain.clone(),
  332        };
  333        if let Some(state) = self.language_server_ids.get_mut(&key) {
  334            state.project_roots.insert(disposition.path.path.clone());
  335            state.id
  336        } else {
  337            let adapter = self
  338                .languages
  339                .lsp_adapters(language_name)
  340                .into_iter()
  341                .find(|adapter| adapter.name() == disposition.server_name)
  342                .expect("To find LSP adapter");
  343            let new_language_server_id = self.start_language_server(
  344                worktree_handle,
  345                delegate,
  346                adapter,
  347                disposition.settings.clone(),
  348                key.clone(),
  349                cx,
  350            );
  351            if let Some(state) = self.language_server_ids.get_mut(&key) {
  352                state.project_roots.insert(disposition.path.path.clone());
  353            } else {
  354                debug_assert!(
  355                    false,
  356                    "Expected `start_language_server` to ensure that `key` exists in a map"
  357                );
  358            }
  359            new_language_server_id
  360        }
  361    }
  362
  363    fn start_language_server(
  364        &mut self,
  365        worktree_handle: &Entity<Worktree>,
  366        delegate: Arc<LocalLspAdapterDelegate>,
  367        adapter: Arc<CachedLspAdapter>,
  368        settings: Arc<LspSettings>,
  369        key: LanguageServerSeed,
  370        cx: &mut App,
  371    ) -> LanguageServerId {
  372        let worktree = worktree_handle.read(cx);
  373
  374        let worktree_id = worktree.id();
  375        let worktree_abs_path = worktree.abs_path();
  376        let toolchain = key.toolchain.clone();
  377        let override_options = settings.initialization_options.clone();
  378
  379        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  380
  381        let server_id = self.languages.next_language_server_id();
  382        log::trace!(
  383            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  384            adapter.name.0
  385        );
  386
  387        let untrusted_worktree_task =
  388            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  389                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  390                    trusted_worktrees.can_trust(worktree_id, cx)
  391                });
  392                if can_trust {
  393                    self.restricted_worktrees_tasks.remove(&worktree_id);
  394                    None
  395                } else {
  396                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  397                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  398                        hash_map::Entry::Vacant(v) => {
  399                            let (tx, rx) = smol::channel::bounded::<()>(1);
  400                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, _| {
  401                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  402                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  403                                        tx.send_blocking(()).ok();
  404                                    }
  405                                }
  406                            });
  407                            v.insert((subscription, rx.clone()));
  408                            Some(rx)
  409                        }
  410                    }
  411                }
  412            });
  413        let update_binary_status = untrusted_worktree_task.is_none();
  414
  415        let binary = self.get_language_server_binary(
  416            worktree_abs_path.clone(),
  417            adapter.clone(),
  418            settings,
  419            toolchain.clone(),
  420            delegate.clone(),
  421            true,
  422            untrusted_worktree_task,
  423            cx,
  424        );
  425        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  426
  427        let pending_server = cx.spawn({
  428            let adapter = adapter.clone();
  429            let server_name = adapter.name.clone();
  430            let stderr_capture = stderr_capture.clone();
  431            #[cfg(any(test, feature = "test-support"))]
  432            let lsp_store = self.weak.clone();
  433            let pending_workspace_folders = pending_workspace_folders.clone();
  434            async move |cx| {
  435                let binary = binary.await?;
  436                #[cfg(any(test, feature = "test-support"))]
  437                if let Some(server) = lsp_store
  438                    .update(&mut cx.clone(), |this, cx| {
  439                        this.languages.create_fake_language_server(
  440                            server_id,
  441                            &server_name,
  442                            binary.clone(),
  443                            &mut cx.to_async(),
  444                        )
  445                    })
  446                    .ok()
  447                    .flatten()
  448                {
  449                    return Ok(server);
  450                }
  451
  452                let code_action_kinds = adapter.code_action_kinds();
  453                lsp::LanguageServer::new(
  454                    stderr_capture,
  455                    server_id,
  456                    server_name,
  457                    binary,
  458                    &worktree_abs_path,
  459                    code_action_kinds,
  460                    Some(pending_workspace_folders),
  461                    cx,
  462                )
  463            }
  464        });
  465
  466        let startup = {
  467            let server_name = adapter.name.0.clone();
  468            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  469            let key = key.clone();
  470            let adapter = adapter.clone();
  471            let lsp_store = self.weak.clone();
  472            let pending_workspace_folders = pending_workspace_folders.clone();
  473
  474            let pull_diagnostics = ProjectSettings::get_global(cx)
  475                .diagnostics
  476                .lsp_pull_diagnostics
  477                .enabled;
  478            cx.spawn(async move |cx| {
  479                let result = async {
  480                    let language_server = pending_server.await?;
  481
  482                    let workspace_config = Self::workspace_configuration_for_adapter(
  483                        adapter.adapter.clone(),
  484                        &delegate,
  485                        toolchain,
  486                        None,
  487                        cx,
  488                    )
  489                    .await?;
  490
  491                    let mut initialization_options = Self::initialization_options_for_adapter(
  492                        adapter.adapter.clone(),
  493                        &delegate,
  494                    )
  495                    .await?;
  496
  497                    match (&mut initialization_options, override_options) {
  498                        (Some(initialization_options), Some(override_options)) => {
  499                            merge_json_value_into(override_options, initialization_options);
  500                        }
  501                        (None, override_options) => initialization_options = override_options,
  502                        _ => {}
  503                    }
  504
  505                    let initialization_params = cx.update(|cx| {
  506                        let mut params =
  507                            language_server.default_initialize_params(pull_diagnostics, cx);
  508                        params.initialization_options = initialization_options;
  509                        adapter.adapter.prepare_initialize_params(params, cx)
  510                    })??;
  511
  512                    Self::setup_lsp_messages(
  513                        lsp_store.clone(),
  514                        &language_server,
  515                        delegate.clone(),
  516                        adapter.clone(),
  517                    );
  518
  519                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  520                        settings: workspace_config,
  521                    };
  522                    let language_server = cx
  523                        .update(|cx| {
  524                            language_server.initialize(
  525                                initialization_params,
  526                                Arc::new(did_change_configuration_params.clone()),
  527                                cx,
  528                            )
  529                        })?
  530                        .await
  531                        .inspect_err(|_| {
  532                            if let Some(lsp_store) = lsp_store.upgrade() {
  533                                lsp_store
  534                                    .update(cx, |lsp_store, cx| {
  535                                        lsp_store.cleanup_lsp_data(server_id);
  536                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  537                                    })
  538                                    .ok();
  539                            }
  540                        })?;
  541
  542                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  543                        did_change_configuration_params,
  544                    )?;
  545
  546                    anyhow::Ok(language_server)
  547                }
  548                .await;
  549
  550                match result {
  551                    Ok(server) => {
  552                        lsp_store
  553                            .update(cx, |lsp_store, cx| {
  554                                lsp_store.insert_newly_running_language_server(
  555                                    adapter,
  556                                    server.clone(),
  557                                    server_id,
  558                                    key,
  559                                    pending_workspace_folders,
  560                                    cx,
  561                                );
  562                            })
  563                            .ok();
  564                        stderr_capture.lock().take();
  565                        Some(server)
  566                    }
  567
  568                    Err(err) => {
  569                        let log = stderr_capture.lock().take().unwrap_or_default();
  570                        delegate.update_status(
  571                            adapter.name(),
  572                            BinaryStatus::Failed {
  573                                error: if log.is_empty() {
  574                                    format!("{err:#}")
  575                                } else {
  576                                    format!("{err:#}\n-- stderr --\n{log}")
  577                                },
  578                            },
  579                        );
  580                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  581                        if !log.is_empty() {
  582                            log::error!("server stderr: {log}");
  583                        }
  584                        None
  585                    }
  586                }
  587            })
  588        };
  589        let state = LanguageServerState::Starting {
  590            startup,
  591            pending_workspace_folders,
  592        };
  593
  594        if update_binary_status {
  595            self.languages
  596                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  597        }
  598
  599        self.language_servers.insert(server_id, state);
  600        self.language_server_ids
  601            .entry(key)
  602            .or_insert(UnifiedLanguageServer {
  603                id: server_id,
  604                project_roots: Default::default(),
  605            });
  606        server_id
  607    }
  608
  609    fn get_language_server_binary(
  610        &self,
  611        worktree_abs_path: Arc<Path>,
  612        adapter: Arc<CachedLspAdapter>,
  613        settings: Arc<LspSettings>,
  614        toolchain: Option<Toolchain>,
  615        delegate: Arc<dyn LspAdapterDelegate>,
  616        allow_binary_download: bool,
  617        untrusted_worktree_task: Option<Receiver<()>>,
  618        cx: &mut App,
  619    ) -> Task<Result<LanguageServerBinary>> {
  620        if let Some(settings) = &settings.binary
  621            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  622        {
  623            let settings = settings.clone();
  624            let languages = self.languages.clone();
  625            return cx.background_spawn(async move {
  626                if let Some(untrusted_worktree_task) = untrusted_worktree_task {
  627                    log::info!(
  628                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  629                        adapter.name(),
  630                    );
  631                    untrusted_worktree_task.recv().await.ok();
  632                    log::info!(
  633                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  634                        adapter.name(),
  635                    );
  636                    languages
  637                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  638                }
  639                let mut env = delegate.shell_env().await;
  640                env.extend(settings.env.unwrap_or_default());
  641
  642                Ok(LanguageServerBinary {
  643                    path: delegate.resolve_executable_path(path),
  644                    env: Some(env),
  645                    arguments: settings
  646                        .arguments
  647                        .unwrap_or_default()
  648                        .iter()
  649                        .map(Into::into)
  650                        .collect(),
  651                })
  652            });
  653        }
  654        let lsp_binary_options = LanguageServerBinaryOptions {
  655            allow_path_lookup: !settings
  656                .binary
  657                .as_ref()
  658                .and_then(|b| b.ignore_system_version)
  659                .unwrap_or_default(),
  660            allow_binary_download,
  661            pre_release: settings
  662                .fetch
  663                .as_ref()
  664                .and_then(|f| f.pre_release)
  665                .unwrap_or(false),
  666        };
  667
  668        cx.spawn(async move |cx| {
  669            if let Some(untrusted_worktree_task) = untrusted_worktree_task {
  670                log::info!(
  671                    "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  672                    adapter.name(),
  673                );
  674                untrusted_worktree_task.recv().await.ok();
  675                log::info!(
  676                    "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  677                    adapter.name(),
  678                );
  679            }
  680
  681            let (existing_binary, maybe_download_binary) = adapter
  682                .clone()
  683                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  684                .await
  685                .await;
  686
  687            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  688
  689            let mut binary = match (existing_binary, maybe_download_binary) {
  690                (binary, None) => binary?,
  691                (Err(_), Some(downloader)) => downloader.await?,
  692                (Ok(existing_binary), Some(downloader)) => {
  693                    let mut download_timeout = cx
  694                        .background_executor()
  695                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  696                        .fuse();
  697                    let mut downloader = downloader.fuse();
  698                    futures::select! {
  699                        _ = download_timeout => {
  700                            // Return existing binary and kick the existing work to the background.
  701                            cx.spawn(async move |_| downloader.await).detach();
  702                            Ok(existing_binary)
  703                        },
  704                        downloaded_or_existing_binary = downloader => {
  705                            // If download fails, this results in the existing binary.
  706                            downloaded_or_existing_binary
  707                        }
  708                    }?
  709                }
  710            };
  711            let mut shell_env = delegate.shell_env().await;
  712
  713            shell_env.extend(binary.env.unwrap_or_default());
  714
  715            if let Some(settings) = settings.binary.as_ref() {
  716                if let Some(arguments) = &settings.arguments {
  717                    binary.arguments = arguments.iter().map(Into::into).collect();
  718                }
  719                if let Some(env) = &settings.env {
  720                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  721                }
  722            }
  723
  724            binary.env = Some(shell_env);
  725            Ok(binary)
  726        })
  727    }
  728
  729    fn setup_lsp_messages(
  730        lsp_store: WeakEntity<LspStore>,
  731        language_server: &LanguageServer,
  732        delegate: Arc<dyn LspAdapterDelegate>,
  733        adapter: Arc<CachedLspAdapter>,
  734    ) {
  735        let name = language_server.name();
  736        let server_id = language_server.server_id();
  737        language_server
  738            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  739                let adapter = adapter.clone();
  740                let this = lsp_store.clone();
  741                move |mut params, cx| {
  742                    let adapter = adapter.clone();
  743                    if let Some(this) = this.upgrade() {
  744                        this.update(cx, |this, cx| {
  745                            {
  746                                let buffer = params
  747                                    .uri
  748                                    .to_file_path()
  749                                    .map(|file_path| this.get_buffer(&file_path, cx))
  750                                    .ok()
  751                                    .flatten();
  752                                adapter.process_diagnostics(&mut params, server_id, buffer);
  753                            }
  754
  755                            this.merge_lsp_diagnostics(
  756                                DiagnosticSourceKind::Pushed,
  757                                vec![DocumentDiagnosticsUpdate {
  758                                    server_id,
  759                                    diagnostics: params,
  760                                    result_id: None,
  761                                    disk_based_sources: Cow::Borrowed(
  762                                        &adapter.disk_based_diagnostic_sources,
  763                                    ),
  764                                    registration_id: None,
  765                                }],
  766                                |_, diagnostic, cx| match diagnostic.source_kind {
  767                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  768                                        adapter.retain_old_diagnostic(diagnostic, cx)
  769                                    }
  770                                    DiagnosticSourceKind::Pulled => true,
  771                                },
  772                                cx,
  773                            )
  774                            .log_err();
  775                        })
  776                        .ok();
  777                    }
  778                }
  779            })
  780            .detach();
  781        language_server
  782            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  783                let adapter = adapter.adapter.clone();
  784                let delegate = delegate.clone();
  785                let this = lsp_store.clone();
  786                move |params, cx| {
  787                    let adapter = adapter.clone();
  788                    let delegate = delegate.clone();
  789                    let this = this.clone();
  790                    let mut cx = cx.clone();
  791                    async move {
  792                        let toolchain_for_id = this
  793                            .update(&mut cx, |this, _| {
  794                                this.as_local()?.language_server_ids.iter().find_map(
  795                                    |(seed, value)| {
  796                                        (value.id == server_id).then(|| seed.toolchain.clone())
  797                                    },
  798                                )
  799                            })?
  800                            .context("Expected the LSP store to be in a local mode")?;
  801
  802                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  803                        for item in &params.items {
  804                            let scope_uri = item.scope_uri.clone();
  805                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  806                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  807                            else {
  808                                // We've already queried workspace configuration of this URI.
  809                                continue;
  810                            };
  811                            let workspace_config = Self::workspace_configuration_for_adapter(
  812                                adapter.clone(),
  813                                &delegate,
  814                                toolchain_for_id.clone(),
  815                                scope_uri,
  816                                &mut cx,
  817                            )
  818                            .await?;
  819                            new_scope_uri.insert(workspace_config);
  820                        }
  821
  822                        Ok(params
  823                            .items
  824                            .into_iter()
  825                            .filter_map(|item| {
  826                                let workspace_config =
  827                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  828                                if let Some(section) = &item.section {
  829                                    Some(
  830                                        workspace_config
  831                                            .get(section)
  832                                            .cloned()
  833                                            .unwrap_or(serde_json::Value::Null),
  834                                    )
  835                                } else {
  836                                    Some(workspace_config.clone())
  837                                }
  838                            })
  839                            .collect())
  840                    }
  841                }
  842            })
  843            .detach();
  844
  845        language_server
  846            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  847                let this = lsp_store.clone();
  848                move |_, cx| {
  849                    let this = this.clone();
  850                    let cx = cx.clone();
  851                    async move {
  852                        let Some(server) =
  853                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  854                        else {
  855                            return Ok(None);
  856                        };
  857                        let root = server.workspace_folders();
  858                        Ok(Some(
  859                            root.into_iter()
  860                                .map(|uri| WorkspaceFolder {
  861                                    uri,
  862                                    name: Default::default(),
  863                                })
  864                                .collect(),
  865                        ))
  866                    }
  867                }
  868            })
  869            .detach();
  870        // Even though we don't have handling for these requests, respond to them to
  871        // avoid stalling any language server like `gopls` which waits for a response
  872        // to these requests when initializing.
  873        language_server
  874            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  875                let this = lsp_store.clone();
  876                move |params, cx| {
  877                    let this = this.clone();
  878                    let mut cx = cx.clone();
  879                    async move {
  880                        this.update(&mut cx, |this, _| {
  881                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  882                            {
  883                                status
  884                                    .progress_tokens
  885                                    .insert(ProgressToken::from_lsp(params.token));
  886                            }
  887                        })?;
  888
  889                        Ok(())
  890                    }
  891                }
  892            })
  893            .detach();
  894
  895        language_server
  896            .on_request::<lsp::request::RegisterCapability, _, _>({
  897                let lsp_store = lsp_store.clone();
  898                move |params, cx| {
  899                    let lsp_store = lsp_store.clone();
  900                    let mut cx = cx.clone();
  901                    async move {
  902                        lsp_store
  903                            .update(&mut cx, |lsp_store, cx| {
  904                                if lsp_store.as_local().is_some() {
  905                                    match lsp_store
  906                                        .register_server_capabilities(server_id, params, cx)
  907                                    {
  908                                        Ok(()) => {}
  909                                        Err(e) => {
  910                                            log::error!(
  911                                                "Failed to register server capabilities: {e:#}"
  912                                            );
  913                                        }
  914                                    };
  915                                }
  916                            })
  917                            .ok();
  918                        Ok(())
  919                    }
  920                }
  921            })
  922            .detach();
  923
  924        language_server
  925            .on_request::<lsp::request::UnregisterCapability, _, _>({
  926                let lsp_store = lsp_store.clone();
  927                move |params, cx| {
  928                    let lsp_store = lsp_store.clone();
  929                    let mut cx = cx.clone();
  930                    async move {
  931                        lsp_store
  932                            .update(&mut cx, |lsp_store, cx| {
  933                                if lsp_store.as_local().is_some() {
  934                                    match lsp_store
  935                                        .unregister_server_capabilities(server_id, params, cx)
  936                                    {
  937                                        Ok(()) => {}
  938                                        Err(e) => {
  939                                            log::error!(
  940                                                "Failed to unregister server capabilities: {e:#}"
  941                                            );
  942                                        }
  943                                    }
  944                                }
  945                            })
  946                            .ok();
  947                        Ok(())
  948                    }
  949                }
  950            })
  951            .detach();
  952
  953        language_server
  954            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  955                let this = lsp_store.clone();
  956                move |params, cx| {
  957                    let mut cx = cx.clone();
  958                    let this = this.clone();
  959                    async move {
  960                        LocalLspStore::on_lsp_workspace_edit(
  961                            this.clone(),
  962                            params,
  963                            server_id,
  964                            &mut cx,
  965                        )
  966                        .await
  967                    }
  968                }
  969            })
  970            .detach();
  971
  972        language_server
  973            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  974                let lsp_store = lsp_store.clone();
  975                let request_id = Arc::new(AtomicUsize::new(0));
  976                move |(), cx| {
  977                    let lsp_store = lsp_store.clone();
  978                    let request_id = request_id.clone();
  979                    let mut cx = cx.clone();
  980                    async move {
  981                        lsp_store
  982                            .update(&mut cx, |lsp_store, cx| {
  983                                let request_id =
  984                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
  985                                cx.emit(LspStoreEvent::RefreshInlayHints {
  986                                    server_id,
  987                                    request_id,
  988                                });
  989                                lsp_store
  990                                    .downstream_client
  991                                    .as_ref()
  992                                    .map(|(client, project_id)| {
  993                                        client.send(proto::RefreshInlayHints {
  994                                            project_id: *project_id,
  995                                            server_id: server_id.to_proto(),
  996                                            request_id: request_id.map(|id| id as u64),
  997                                        })
  998                                    })
  999                            })?
 1000                            .transpose()?;
 1001                        Ok(())
 1002                    }
 1003                }
 1004            })
 1005            .detach();
 1006
 1007        language_server
 1008            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1009                let this = lsp_store.clone();
 1010                move |(), cx| {
 1011                    let this = this.clone();
 1012                    let mut cx = cx.clone();
 1013                    async move {
 1014                        this.update(&mut cx, |this, cx| {
 1015                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1016                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1017                                client.send(proto::RefreshCodeLens {
 1018                                    project_id: *project_id,
 1019                                })
 1020                            })
 1021                        })?
 1022                        .transpose()?;
 1023                        Ok(())
 1024                    }
 1025                }
 1026            })
 1027            .detach();
 1028
 1029        language_server
 1030            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1031                let this = lsp_store.clone();
 1032                move |(), cx| {
 1033                    let this = this.clone();
 1034                    let mut cx = cx.clone();
 1035                    async move {
 1036                        this.update(&mut cx, |lsp_store, _| {
 1037                            lsp_store.pull_workspace_diagnostics(server_id);
 1038                            lsp_store
 1039                                .downstream_client
 1040                                .as_ref()
 1041                                .map(|(client, project_id)| {
 1042                                    client.send(proto::PullWorkspaceDiagnostics {
 1043                                        project_id: *project_id,
 1044                                        server_id: server_id.to_proto(),
 1045                                    })
 1046                                })
 1047                        })?
 1048                        .transpose()?;
 1049                        Ok(())
 1050                    }
 1051                }
 1052            })
 1053            .detach();
 1054
 1055        language_server
 1056            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1057                let this = lsp_store.clone();
 1058                let name = name.to_string();
 1059                move |params, cx| {
 1060                    let this = this.clone();
 1061                    let name = name.to_string();
 1062                    let mut cx = cx.clone();
 1063                    async move {
 1064                        let actions = params.actions.unwrap_or_default();
 1065                        let (tx, rx) = smol::channel::bounded(1);
 1066                        let request = LanguageServerPromptRequest {
 1067                            level: match params.typ {
 1068                                lsp::MessageType::ERROR => PromptLevel::Critical,
 1069                                lsp::MessageType::WARNING => PromptLevel::Warning,
 1070                                _ => PromptLevel::Info,
 1071                            },
 1072                            message: params.message,
 1073                            actions,
 1074                            response_channel: tx,
 1075                            lsp_name: name.clone(),
 1076                        };
 1077
 1078                        let did_update = this
 1079                            .update(&mut cx, |_, cx| {
 1080                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1081                            })
 1082                            .is_ok();
 1083                        if did_update {
 1084                            let response = rx.recv().await.ok();
 1085                            Ok(response)
 1086                        } else {
 1087                            Ok(None)
 1088                        }
 1089                    }
 1090                }
 1091            })
 1092            .detach();
 1093        language_server
 1094            .on_notification::<lsp::notification::ShowMessage, _>({
 1095                let this = lsp_store.clone();
 1096                let name = name.to_string();
 1097                move |params, cx| {
 1098                    let this = this.clone();
 1099                    let name = name.to_string();
 1100                    let mut cx = cx.clone();
 1101
 1102                    let (tx, _) = smol::channel::bounded(1);
 1103                    let request = LanguageServerPromptRequest {
 1104                        level: match params.typ {
 1105                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1106                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1107                            _ => PromptLevel::Info,
 1108                        },
 1109                        message: params.message,
 1110                        actions: vec![],
 1111                        response_channel: tx,
 1112                        lsp_name: name,
 1113                    };
 1114
 1115                    let _ = this.update(&mut cx, |_, cx| {
 1116                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1117                    });
 1118                }
 1119            })
 1120            .detach();
 1121
 1122        let disk_based_diagnostics_progress_token =
 1123            adapter.disk_based_diagnostics_progress_token.clone();
 1124
 1125        language_server
 1126            .on_notification::<lsp::notification::Progress, _>({
 1127                let this = lsp_store.clone();
 1128                move |params, cx| {
 1129                    if let Some(this) = this.upgrade() {
 1130                        this.update(cx, |this, cx| {
 1131                            this.on_lsp_progress(
 1132                                params,
 1133                                server_id,
 1134                                disk_based_diagnostics_progress_token.clone(),
 1135                                cx,
 1136                            );
 1137                        })
 1138                        .ok();
 1139                    }
 1140                }
 1141            })
 1142            .detach();
 1143
 1144        language_server
 1145            .on_notification::<lsp::notification::LogMessage, _>({
 1146                let this = lsp_store.clone();
 1147                move |params, cx| {
 1148                    if let Some(this) = this.upgrade() {
 1149                        this.update(cx, |_, cx| {
 1150                            cx.emit(LspStoreEvent::LanguageServerLog(
 1151                                server_id,
 1152                                LanguageServerLogType::Log(params.typ),
 1153                                params.message,
 1154                            ));
 1155                        })
 1156                        .ok();
 1157                    }
 1158                }
 1159            })
 1160            .detach();
 1161
 1162        language_server
 1163            .on_notification::<lsp::notification::LogTrace, _>({
 1164                let this = lsp_store.clone();
 1165                move |params, cx| {
 1166                    let mut cx = cx.clone();
 1167                    if let Some(this) = this.upgrade() {
 1168                        this.update(&mut cx, |_, cx| {
 1169                            cx.emit(LspStoreEvent::LanguageServerLog(
 1170                                server_id,
 1171                                LanguageServerLogType::Trace {
 1172                                    verbose_info: params.verbose,
 1173                                },
 1174                                params.message,
 1175                            ));
 1176                        })
 1177                        .ok();
 1178                    }
 1179                }
 1180            })
 1181            .detach();
 1182
 1183        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1184        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1185        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1186        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1187    }
 1188
 1189    fn shutdown_language_servers_on_quit(
 1190        &mut self,
 1191        _: &mut Context<LspStore>,
 1192    ) -> impl Future<Output = ()> + use<> {
 1193        let shutdown_futures = self
 1194            .language_servers
 1195            .drain()
 1196            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1197            .collect::<Vec<_>>();
 1198
 1199        async move {
 1200            join_all(shutdown_futures).await;
 1201        }
 1202    }
 1203
 1204    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1205        match server_state {
 1206            LanguageServerState::Running { server, .. } => {
 1207                if let Some(shutdown) = server.shutdown() {
 1208                    shutdown.await;
 1209                }
 1210            }
 1211            LanguageServerState::Starting { startup, .. } => {
 1212                if let Some(server) = startup.await
 1213                    && let Some(shutdown) = server.shutdown()
 1214                {
 1215                    shutdown.await;
 1216                }
 1217            }
 1218        }
 1219        Ok(())
 1220    }
 1221
 1222    fn language_servers_for_worktree(
 1223        &self,
 1224        worktree_id: WorktreeId,
 1225    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1226        self.language_server_ids
 1227            .iter()
 1228            .filter_map(move |(seed, state)| {
 1229                if seed.worktree_id != worktree_id {
 1230                    return None;
 1231                }
 1232
 1233                if let Some(LanguageServerState::Running { server, .. }) =
 1234                    self.language_servers.get(&state.id)
 1235                {
 1236                    Some(server)
 1237                } else {
 1238                    None
 1239                }
 1240            })
 1241    }
 1242
 1243    fn language_server_ids_for_project_path(
 1244        &self,
 1245        project_path: ProjectPath,
 1246        language: &Language,
 1247        cx: &mut App,
 1248    ) -> Vec<LanguageServerId> {
 1249        let Some(worktree) = self
 1250            .worktree_store
 1251            .read(cx)
 1252            .worktree_for_id(project_path.worktree_id, cx)
 1253        else {
 1254            return Vec::new();
 1255        };
 1256        let delegate: Arc<dyn ManifestDelegate> =
 1257            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1258
 1259        self.lsp_tree
 1260            .get(
 1261                project_path,
 1262                language.name(),
 1263                language.manifest(),
 1264                &delegate,
 1265                cx,
 1266            )
 1267            .collect::<Vec<_>>()
 1268    }
 1269
 1270    fn language_server_ids_for_buffer(
 1271        &self,
 1272        buffer: &Buffer,
 1273        cx: &mut App,
 1274    ) -> Vec<LanguageServerId> {
 1275        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1276            let worktree_id = file.worktree_id(cx);
 1277
 1278            let path: Arc<RelPath> = file
 1279                .path()
 1280                .parent()
 1281                .map(Arc::from)
 1282                .unwrap_or_else(|| file.path().clone());
 1283            let worktree_path = ProjectPath { worktree_id, path };
 1284            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1285        } else {
 1286            Vec::new()
 1287        }
 1288    }
 1289
 1290    fn language_servers_for_buffer<'a>(
 1291        &'a self,
 1292        buffer: &'a Buffer,
 1293        cx: &'a mut App,
 1294    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1295        self.language_server_ids_for_buffer(buffer, cx)
 1296            .into_iter()
 1297            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1298                LanguageServerState::Running {
 1299                    adapter, server, ..
 1300                } => Some((adapter, server)),
 1301                _ => None,
 1302            })
 1303    }
 1304
 1305    async fn execute_code_action_kind_locally(
 1306        lsp_store: WeakEntity<LspStore>,
 1307        mut buffers: Vec<Entity<Buffer>>,
 1308        kind: CodeActionKind,
 1309        push_to_history: bool,
 1310        cx: &mut AsyncApp,
 1311    ) -> anyhow::Result<ProjectTransaction> {
 1312        // Do not allow multiple concurrent code actions requests for the
 1313        // same buffer.
 1314        lsp_store.update(cx, |this, cx| {
 1315            let this = this.as_local_mut().unwrap();
 1316            buffers.retain(|buffer| {
 1317                this.buffers_being_formatted
 1318                    .insert(buffer.read(cx).remote_id())
 1319            });
 1320        })?;
 1321        let _cleanup = defer({
 1322            let this = lsp_store.clone();
 1323            let mut cx = cx.clone();
 1324            let buffers = &buffers;
 1325            move || {
 1326                this.update(&mut cx, |this, cx| {
 1327                    let this = this.as_local_mut().unwrap();
 1328                    for buffer in buffers {
 1329                        this.buffers_being_formatted
 1330                            .remove(&buffer.read(cx).remote_id());
 1331                    }
 1332                })
 1333                .ok();
 1334            }
 1335        });
 1336        let mut project_transaction = ProjectTransaction::default();
 1337
 1338        for buffer in &buffers {
 1339            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1340                buffer.update(cx, |buffer, cx| {
 1341                    lsp_store
 1342                        .as_local()
 1343                        .unwrap()
 1344                        .language_servers_for_buffer(buffer, cx)
 1345                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1346                        .collect::<Vec<_>>()
 1347                })
 1348            })?;
 1349            for (_, language_server) in adapters_and_servers.iter() {
 1350                let actions = Self::get_server_code_actions_from_action_kinds(
 1351                    &lsp_store,
 1352                    language_server.server_id(),
 1353                    vec![kind.clone()],
 1354                    buffer,
 1355                    cx,
 1356                )
 1357                .await?;
 1358                Self::execute_code_actions_on_server(
 1359                    &lsp_store,
 1360                    language_server,
 1361                    actions,
 1362                    push_to_history,
 1363                    &mut project_transaction,
 1364                    cx,
 1365                )
 1366                .await?;
 1367            }
 1368        }
 1369        Ok(project_transaction)
 1370    }
 1371
 1372    async fn format_locally(
 1373        lsp_store: WeakEntity<LspStore>,
 1374        mut buffers: Vec<FormattableBuffer>,
 1375        push_to_history: bool,
 1376        trigger: FormatTrigger,
 1377        logger: zlog::Logger,
 1378        cx: &mut AsyncApp,
 1379    ) -> anyhow::Result<ProjectTransaction> {
 1380        // Do not allow multiple concurrent formatting requests for the
 1381        // same buffer.
 1382        lsp_store.update(cx, |this, cx| {
 1383            let this = this.as_local_mut().unwrap();
 1384            buffers.retain(|buffer| {
 1385                this.buffers_being_formatted
 1386                    .insert(buffer.handle.read(cx).remote_id())
 1387            });
 1388        })?;
 1389
 1390        let _cleanup = defer({
 1391            let this = lsp_store.clone();
 1392            let mut cx = cx.clone();
 1393            let buffers = &buffers;
 1394            move || {
 1395                this.update(&mut cx, |this, cx| {
 1396                    let this = this.as_local_mut().unwrap();
 1397                    for buffer in buffers {
 1398                        this.buffers_being_formatted
 1399                            .remove(&buffer.handle.read(cx).remote_id());
 1400                    }
 1401                })
 1402                .ok();
 1403            }
 1404        });
 1405
 1406        let mut project_transaction = ProjectTransaction::default();
 1407
 1408        for buffer in &buffers {
 1409            zlog::debug!(
 1410                logger =>
 1411                "formatting buffer '{:?}'",
 1412                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1413            );
 1414            // Create an empty transaction to hold all of the formatting edits.
 1415            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1416                // ensure no transactions created while formatting are
 1417                // grouped with the previous transaction in the history
 1418                // based on the transaction group interval
 1419                buffer.finalize_last_transaction();
 1420                buffer
 1421                    .start_transaction()
 1422                    .context("transaction already open")?;
 1423                buffer.end_transaction(cx);
 1424                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1425                buffer.finalize_last_transaction();
 1426                anyhow::Ok(transaction_id)
 1427            })??;
 1428
 1429            let result = Self::format_buffer_locally(
 1430                lsp_store.clone(),
 1431                buffer,
 1432                formatting_transaction_id,
 1433                trigger,
 1434                logger,
 1435                cx,
 1436            )
 1437            .await;
 1438
 1439            buffer.handle.update(cx, |buffer, cx| {
 1440                let Some(formatting_transaction) =
 1441                    buffer.get_transaction(formatting_transaction_id).cloned()
 1442                else {
 1443                    zlog::warn!(logger => "no formatting transaction");
 1444                    return;
 1445                };
 1446                if formatting_transaction.edit_ids.is_empty() {
 1447                    zlog::debug!(logger => "no changes made while formatting");
 1448                    buffer.forget_transaction(formatting_transaction_id);
 1449                    return;
 1450                }
 1451                if !push_to_history {
 1452                    zlog::trace!(logger => "forgetting format transaction");
 1453                    buffer.forget_transaction(formatting_transaction.id);
 1454                }
 1455                project_transaction
 1456                    .0
 1457                    .insert(cx.entity(), formatting_transaction);
 1458            })?;
 1459
 1460            result?;
 1461        }
 1462
 1463        Ok(project_transaction)
 1464    }
 1465
 1466    async fn format_buffer_locally(
 1467        lsp_store: WeakEntity<LspStore>,
 1468        buffer: &FormattableBuffer,
 1469        formatting_transaction_id: clock::Lamport,
 1470        trigger: FormatTrigger,
 1471        logger: zlog::Logger,
 1472        cx: &mut AsyncApp,
 1473    ) -> Result<()> {
 1474        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1475            buffer.handle.update(cx, |buffer, cx| {
 1476                let adapters_and_servers = lsp_store
 1477                    .as_local()
 1478                    .unwrap()
 1479                    .language_servers_for_buffer(buffer, cx)
 1480                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1481                    .collect::<Vec<_>>();
 1482                let settings =
 1483                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1484                        .into_owned();
 1485                (adapters_and_servers, settings)
 1486            })
 1487        })?;
 1488
 1489        /// Apply edits to the buffer that will become part of the formatting transaction.
 1490        /// Fails if the buffer has been edited since the start of that transaction.
 1491        fn extend_formatting_transaction(
 1492            buffer: &FormattableBuffer,
 1493            formatting_transaction_id: text::TransactionId,
 1494            cx: &mut AsyncApp,
 1495            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1496        ) -> anyhow::Result<()> {
 1497            buffer.handle.update(cx, |buffer, cx| {
 1498                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1499                if last_transaction_id != Some(formatting_transaction_id) {
 1500                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1501                }
 1502                buffer.start_transaction();
 1503                operation(buffer, cx);
 1504                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1505                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1506                }
 1507                Ok(())
 1508            })?
 1509        }
 1510
 1511        // handle whitespace formatting
 1512        if settings.remove_trailing_whitespace_on_save {
 1513            zlog::trace!(logger => "removing trailing whitespace");
 1514            let diff = buffer
 1515                .handle
 1516                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1517                .await;
 1518            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1519                buffer.apply_diff(diff, cx);
 1520            })?;
 1521        }
 1522
 1523        if settings.ensure_final_newline_on_save {
 1524            zlog::trace!(logger => "ensuring final newline");
 1525            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1526                buffer.ensure_final_newline(cx);
 1527            })?;
 1528        }
 1529
 1530        // Formatter for `code_actions_on_format` that runs before
 1531        // the rest of the formatters
 1532        let mut code_actions_on_format_formatters = None;
 1533        let should_run_code_actions_on_format = !matches!(
 1534            (trigger, &settings.format_on_save),
 1535            (FormatTrigger::Save, &FormatOnSave::Off)
 1536        );
 1537        if should_run_code_actions_on_format {
 1538            let have_code_actions_to_run_on_format = settings
 1539                .code_actions_on_format
 1540                .values()
 1541                .any(|enabled| *enabled);
 1542            if have_code_actions_to_run_on_format {
 1543                zlog::trace!(logger => "going to run code actions on format");
 1544                code_actions_on_format_formatters = Some(
 1545                    settings
 1546                        .code_actions_on_format
 1547                        .iter()
 1548                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1549                        .cloned()
 1550                        .map(Formatter::CodeAction)
 1551                        .collect::<Vec<_>>(),
 1552                );
 1553            }
 1554        }
 1555
 1556        let formatters = match (trigger, &settings.format_on_save) {
 1557            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1558            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1559                settings.formatter.as_ref()
 1560            }
 1561        };
 1562
 1563        let formatters = code_actions_on_format_formatters
 1564            .iter()
 1565            .flatten()
 1566            .chain(formatters);
 1567
 1568        for formatter in formatters {
 1569            let formatter = if formatter == &Formatter::Auto {
 1570                if settings.prettier.allowed {
 1571                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1572                    &Formatter::Prettier
 1573                } else {
 1574                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1575                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1576                }
 1577            } else {
 1578                formatter
 1579            };
 1580            match formatter {
 1581                Formatter::Auto => unreachable!("Auto resolved above"),
 1582                Formatter::Prettier => {
 1583                    let logger = zlog::scoped!(logger => "prettier");
 1584                    zlog::trace!(logger => "formatting");
 1585                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1586
 1587                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1588                        lsp_store.prettier_store().unwrap().downgrade()
 1589                    })?;
 1590                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1591                        .await
 1592                        .transpose()?;
 1593                    let Some(diff) = diff else {
 1594                        zlog::trace!(logger => "No changes");
 1595                        continue;
 1596                    };
 1597
 1598                    extend_formatting_transaction(
 1599                        buffer,
 1600                        formatting_transaction_id,
 1601                        cx,
 1602                        |buffer, cx| {
 1603                            buffer.apply_diff(diff, cx);
 1604                        },
 1605                    )?;
 1606                }
 1607                Formatter::External { command, arguments } => {
 1608                    let logger = zlog::scoped!(logger => "command");
 1609                    zlog::trace!(logger => "formatting");
 1610                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1611
 1612                    let diff = Self::format_via_external_command(
 1613                        buffer,
 1614                        command.as_ref(),
 1615                        arguments.as_deref(),
 1616                        cx,
 1617                    )
 1618                    .await
 1619                    .with_context(|| {
 1620                        format!("Failed to format buffer via external command: {}", command)
 1621                    })?;
 1622                    let Some(diff) = diff else {
 1623                        zlog::trace!(logger => "No changes");
 1624                        continue;
 1625                    };
 1626
 1627                    extend_formatting_transaction(
 1628                        buffer,
 1629                        formatting_transaction_id,
 1630                        cx,
 1631                        |buffer, cx| {
 1632                            buffer.apply_diff(diff, cx);
 1633                        },
 1634                    )?;
 1635                }
 1636                Formatter::LanguageServer(specifier) => {
 1637                    let logger = zlog::scoped!(logger => "language-server");
 1638                    zlog::trace!(logger => "formatting");
 1639                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1640
 1641                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1642                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1643                        continue;
 1644                    };
 1645
 1646                    let language_server = match specifier {
 1647                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1648                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1649                                if adapter.name.0.as_ref() == name {
 1650                                    Some(server.clone())
 1651                                } else {
 1652                                    None
 1653                                }
 1654                            })
 1655                        }
 1656                        settings::LanguageServerFormatterSpecifier::Current => {
 1657                            adapters_and_servers.first().map(|e| e.1.clone())
 1658                        }
 1659                    };
 1660
 1661                    let Some(language_server) = language_server else {
 1662                        log::debug!(
 1663                            "No language server found to format buffer '{:?}'. Skipping",
 1664                            buffer_path_abs.as_path().to_string_lossy()
 1665                        );
 1666                        continue;
 1667                    };
 1668
 1669                    zlog::trace!(
 1670                        logger =>
 1671                        "Formatting buffer '{:?}' using language server '{:?}'",
 1672                        buffer_path_abs.as_path().to_string_lossy(),
 1673                        language_server.name()
 1674                    );
 1675
 1676                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1677                        zlog::trace!(logger => "formatting ranges");
 1678                        Self::format_ranges_via_lsp(
 1679                            &lsp_store,
 1680                            &buffer.handle,
 1681                            ranges,
 1682                            buffer_path_abs,
 1683                            &language_server,
 1684                            &settings,
 1685                            cx,
 1686                        )
 1687                        .await
 1688                        .context("Failed to format ranges via language server")?
 1689                    } else {
 1690                        zlog::trace!(logger => "formatting full");
 1691                        Self::format_via_lsp(
 1692                            &lsp_store,
 1693                            &buffer.handle,
 1694                            buffer_path_abs,
 1695                            &language_server,
 1696                            &settings,
 1697                            cx,
 1698                        )
 1699                        .await
 1700                        .context("failed to format via language server")?
 1701                    };
 1702
 1703                    if edits.is_empty() {
 1704                        zlog::trace!(logger => "No changes");
 1705                        continue;
 1706                    }
 1707                    extend_formatting_transaction(
 1708                        buffer,
 1709                        formatting_transaction_id,
 1710                        cx,
 1711                        |buffer, cx| {
 1712                            buffer.edit(edits, None, cx);
 1713                        },
 1714                    )?;
 1715                }
 1716                Formatter::CodeAction(code_action_name) => {
 1717                    let logger = zlog::scoped!(logger => "code-actions");
 1718                    zlog::trace!(logger => "formatting");
 1719                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1720
 1721                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1722                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1723                        continue;
 1724                    };
 1725
 1726                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1727                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1728
 1729                    let mut actions_and_servers = Vec::new();
 1730
 1731                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1732                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1733                            &lsp_store,
 1734                            language_server.server_id(),
 1735                            vec![code_action_kind.clone()],
 1736                            &buffer.handle,
 1737                            cx,
 1738                        )
 1739                        .await
 1740                        .with_context(|| {
 1741                            format!(
 1742                                "Failed to resolve code action {:?} with language server {}",
 1743                                code_action_kind,
 1744                                language_server.name()
 1745                            )
 1746                        });
 1747                        let Ok(actions) = actions_result else {
 1748                            // note: it may be better to set result to the error and break formatters here
 1749                            // but for now we try to execute the actions that we can resolve and skip the rest
 1750                            zlog::error!(
 1751                                logger =>
 1752                                "Failed to resolve code action {:?} with language server {}",
 1753                                code_action_kind,
 1754                                language_server.name()
 1755                            );
 1756                            continue;
 1757                        };
 1758                        for action in actions {
 1759                            actions_and_servers.push((action, index));
 1760                        }
 1761                    }
 1762
 1763                    if actions_and_servers.is_empty() {
 1764                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1765                        continue;
 1766                    }
 1767
 1768                    'actions: for (mut action, server_index) in actions_and_servers {
 1769                        let server = &adapters_and_servers[server_index].1;
 1770
 1771                        let describe_code_action = |action: &CodeAction| {
 1772                            format!(
 1773                                "code action '{}' with title \"{}\" on server {}",
 1774                                action
 1775                                    .lsp_action
 1776                                    .action_kind()
 1777                                    .unwrap_or("unknown".into())
 1778                                    .as_str(),
 1779                                action.lsp_action.title(),
 1780                                server.name(),
 1781                            )
 1782                        };
 1783
 1784                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1785
 1786                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1787                            zlog::error!(
 1788                                logger =>
 1789                                "Failed to resolve {}. Error: {}",
 1790                                describe_code_action(&action),
 1791                                err
 1792                            );
 1793                            continue;
 1794                        }
 1795
 1796                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1797                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1798                            // but filters out and logs warnings for code actions that require unreasonably
 1799                            // difficult handling on our part, such as:
 1800                            // - applying edits that call commands
 1801                            //   which can result in arbitrary workspace edits being sent from the server that
 1802                            //   have no way of being tied back to the command that initiated them (i.e. we
 1803                            //   can't know which edits are part of the format request, or if the server is done sending
 1804                            //   actions in response to the command)
 1805                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1806                            //   as we then would need to handle such changes correctly in the local history as well
 1807                            //   as the remote history through the ProjectTransaction
 1808                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1809                            // Supporting these actions is not impossible, but not supported as of yet.
 1810                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1811                                zlog::trace!(
 1812                                    logger =>
 1813                                    "No changes for code action. Skipping {}",
 1814                                    describe_code_action(&action),
 1815                                );
 1816                                continue;
 1817                            }
 1818
 1819                            let mut operations = Vec::new();
 1820                            if let Some(document_changes) = edit.document_changes {
 1821                                match document_changes {
 1822                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1823                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1824                                    ),
 1825                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1826                                }
 1827                            } else if let Some(changes) = edit.changes {
 1828                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1829                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1830                                        text_document:
 1831                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1832                                                uri,
 1833                                                version: None,
 1834                                            },
 1835                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1836                                    })
 1837                                }));
 1838                            }
 1839
 1840                            let mut edits = Vec::with_capacity(operations.len());
 1841
 1842                            if operations.is_empty() {
 1843                                zlog::trace!(
 1844                                    logger =>
 1845                                    "No changes for code action. Skipping {}",
 1846                                    describe_code_action(&action),
 1847                                );
 1848                                continue;
 1849                            }
 1850                            for operation in operations {
 1851                                let op = match operation {
 1852                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1853                                    lsp::DocumentChangeOperation::Op(_) => {
 1854                                        zlog::warn!(
 1855                                            logger =>
 1856                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1857                                            describe_code_action(&action),
 1858                                        );
 1859                                        continue 'actions;
 1860                                    }
 1861                                };
 1862                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1863                                    zlog::warn!(
 1864                                        logger =>
 1865                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1866                                        &op.text_document.uri,
 1867                                        describe_code_action(&action),
 1868                                    );
 1869                                    continue 'actions;
 1870                                };
 1871                                if &file_path != buffer_path_abs {
 1872                                    zlog::warn!(
 1873                                        logger =>
 1874                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1875                                        file_path,
 1876                                        buffer_path_abs,
 1877                                        describe_code_action(&action),
 1878                                    );
 1879                                    continue 'actions;
 1880                                }
 1881
 1882                                let mut lsp_edits = Vec::new();
 1883                                for edit in op.edits {
 1884                                    match edit {
 1885                                        Edit::Plain(edit) => {
 1886                                            if !lsp_edits.contains(&edit) {
 1887                                                lsp_edits.push(edit);
 1888                                            }
 1889                                        }
 1890                                        Edit::Annotated(edit) => {
 1891                                            if !lsp_edits.contains(&edit.text_edit) {
 1892                                                lsp_edits.push(edit.text_edit);
 1893                                            }
 1894                                        }
 1895                                        Edit::Snippet(_) => {
 1896                                            zlog::warn!(
 1897                                                logger =>
 1898                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1899                                                describe_code_action(&action),
 1900                                            );
 1901                                            continue 'actions;
 1902                                        }
 1903                                    }
 1904                                }
 1905                                let edits_result = lsp_store
 1906                                    .update(cx, |lsp_store, cx| {
 1907                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1908                                            &buffer.handle,
 1909                                            lsp_edits,
 1910                                            server.server_id(),
 1911                                            op.text_document.version,
 1912                                            cx,
 1913                                        )
 1914                                    })?
 1915                                    .await;
 1916                                let Ok(resolved_edits) = edits_result else {
 1917                                    zlog::warn!(
 1918                                        logger =>
 1919                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1920                                        buffer_path_abs.as_path(),
 1921                                        describe_code_action(&action),
 1922                                    );
 1923                                    continue 'actions;
 1924                                };
 1925                                edits.extend(resolved_edits);
 1926                            }
 1927
 1928                            if edits.is_empty() {
 1929                                zlog::warn!(logger => "No edits resolved from LSP");
 1930                                continue;
 1931                            }
 1932
 1933                            extend_formatting_transaction(
 1934                                buffer,
 1935                                formatting_transaction_id,
 1936                                cx,
 1937                                |buffer, cx| {
 1938                                    zlog::info!(
 1939                                        "Applying edits {edits:?}. Content: {:?}",
 1940                                        buffer.text()
 1941                                    );
 1942                                    buffer.edit(edits, None, cx);
 1943                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1944                                },
 1945                            )?;
 1946                        }
 1947
 1948                        if let Some(command) = action.lsp_action.command() {
 1949                            zlog::warn!(
 1950                                logger =>
 1951                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1952                                &command.command,
 1953                            );
 1954
 1955                            // bail early if command is invalid
 1956                            let server_capabilities = server.capabilities();
 1957                            let available_commands = server_capabilities
 1958                                .execute_command_provider
 1959                                .as_ref()
 1960                                .map(|options| options.commands.as_slice())
 1961                                .unwrap_or_default();
 1962                            if !available_commands.contains(&command.command) {
 1963                                zlog::warn!(
 1964                                    logger =>
 1965                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1966                                    command.command,
 1967                                    server.name(),
 1968                                );
 1969                                continue;
 1970                            }
 1971
 1972                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1973                            extend_formatting_transaction(
 1974                                buffer,
 1975                                formatting_transaction_id,
 1976                                cx,
 1977                                |_, _| {},
 1978                            )?;
 1979                            zlog::info!(logger => "Executing command {}", &command.command);
 1980
 1981                            lsp_store.update(cx, |this, _| {
 1982                                this.as_local_mut()
 1983                                    .unwrap()
 1984                                    .last_workspace_edits_by_language_server
 1985                                    .remove(&server.server_id());
 1986                            })?;
 1987
 1988                            let execute_command_result = server
 1989                                .request::<lsp::request::ExecuteCommand>(
 1990                                    lsp::ExecuteCommandParams {
 1991                                        command: command.command.clone(),
 1992                                        arguments: command.arguments.clone().unwrap_or_default(),
 1993                                        ..Default::default()
 1994                                    },
 1995                                )
 1996                                .await
 1997                                .into_response();
 1998
 1999                            if execute_command_result.is_err() {
 2000                                zlog::error!(
 2001                                    logger =>
 2002                                    "Failed to execute command '{}' as part of {}",
 2003                                    &command.command,
 2004                                    describe_code_action(&action),
 2005                                );
 2006                                continue 'actions;
 2007                            }
 2008
 2009                            let mut project_transaction_command =
 2010                                lsp_store.update(cx, |this, _| {
 2011                                    this.as_local_mut()
 2012                                        .unwrap()
 2013                                        .last_workspace_edits_by_language_server
 2014                                        .remove(&server.server_id())
 2015                                        .unwrap_or_default()
 2016                                })?;
 2017
 2018                            if let Some(transaction) =
 2019                                project_transaction_command.0.remove(&buffer.handle)
 2020                            {
 2021                                zlog::trace!(
 2022                                    logger =>
 2023                                    "Successfully captured {} edits that resulted from command {}",
 2024                                    transaction.edit_ids.len(),
 2025                                    &command.command,
 2026                                );
 2027                                let transaction_id_project_transaction = transaction.id;
 2028                                buffer.handle.update(cx, |buffer, _| {
 2029                                    // it may have been removed from history if push_to_history was
 2030                                    // false in deserialize_workspace_edit. If so push it so we
 2031                                    // can merge it with the format transaction
 2032                                    // and pop the combined transaction off the history stack
 2033                                    // later if push_to_history is false
 2034                                    if buffer.get_transaction(transaction.id).is_none() {
 2035                                        buffer.push_transaction(transaction, Instant::now());
 2036                                    }
 2037                                    buffer.merge_transactions(
 2038                                        transaction_id_project_transaction,
 2039                                        formatting_transaction_id,
 2040                                    );
 2041                                })?;
 2042                            }
 2043
 2044                            if !project_transaction_command.0.is_empty() {
 2045                                let mut extra_buffers = String::new();
 2046                                for buffer in project_transaction_command.0.keys() {
 2047                                    buffer
 2048                                        .read_with(cx, |b, cx| {
 2049                                            if let Some(path) = b.project_path(cx) {
 2050                                                if !extra_buffers.is_empty() {
 2051                                                    extra_buffers.push_str(", ");
 2052                                                }
 2053                                                extra_buffers.push_str(path.path.as_unix_str());
 2054                                            }
 2055                                        })
 2056                                        .ok();
 2057                                }
 2058                                zlog::warn!(
 2059                                    logger =>
 2060                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2061                                    &command.command,
 2062                                    extra_buffers,
 2063                                );
 2064                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2065                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2066                                // add it so it's included, and merge it into the format transaction when its created later
 2067                            }
 2068                        }
 2069                    }
 2070                }
 2071            }
 2072        }
 2073
 2074        Ok(())
 2075    }
 2076
 2077    pub async fn format_ranges_via_lsp(
 2078        this: &WeakEntity<LspStore>,
 2079        buffer_handle: &Entity<Buffer>,
 2080        ranges: &[Range<Anchor>],
 2081        abs_path: &Path,
 2082        language_server: &Arc<LanguageServer>,
 2083        settings: &LanguageSettings,
 2084        cx: &mut AsyncApp,
 2085    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2086        let capabilities = &language_server.capabilities();
 2087        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2088        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2089            anyhow::bail!(
 2090                "{} language server does not support range formatting",
 2091                language_server.name()
 2092            );
 2093        }
 2094
 2095        let uri = file_path_to_lsp_url(abs_path)?;
 2096        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2097
 2098        let lsp_edits = {
 2099            let mut lsp_ranges = Vec::new();
 2100            this.update(cx, |_this, cx| {
 2101                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2102                // not have been sent to the language server. This seems like a fairly systemic
 2103                // issue, though, the resolution probably is not specific to formatting.
 2104                //
 2105                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2106                // LSP.
 2107                let snapshot = buffer_handle.read(cx).snapshot();
 2108                for range in ranges {
 2109                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2110                }
 2111                anyhow::Ok(())
 2112            })??;
 2113
 2114            let mut edits = None;
 2115            for range in lsp_ranges {
 2116                if let Some(mut edit) = language_server
 2117                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2118                        text_document: text_document.clone(),
 2119                        range,
 2120                        options: lsp_command::lsp_formatting_options(settings),
 2121                        work_done_progress_params: Default::default(),
 2122                    })
 2123                    .await
 2124                    .into_response()?
 2125                {
 2126                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2127                }
 2128            }
 2129            edits
 2130        };
 2131
 2132        if let Some(lsp_edits) = lsp_edits {
 2133            this.update(cx, |this, cx| {
 2134                this.as_local_mut().unwrap().edits_from_lsp(
 2135                    buffer_handle,
 2136                    lsp_edits,
 2137                    language_server.server_id(),
 2138                    None,
 2139                    cx,
 2140                )
 2141            })?
 2142            .await
 2143        } else {
 2144            Ok(Vec::with_capacity(0))
 2145        }
 2146    }
 2147
 2148    async fn format_via_lsp(
 2149        this: &WeakEntity<LspStore>,
 2150        buffer: &Entity<Buffer>,
 2151        abs_path: &Path,
 2152        language_server: &Arc<LanguageServer>,
 2153        settings: &LanguageSettings,
 2154        cx: &mut AsyncApp,
 2155    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2156        let logger = zlog::scoped!("lsp_format");
 2157        zlog::debug!(logger => "Formatting via LSP");
 2158
 2159        let uri = file_path_to_lsp_url(abs_path)?;
 2160        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2161        let capabilities = &language_server.capabilities();
 2162
 2163        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2164        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2165
 2166        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2167            let _timer = zlog::time!(logger => "format-full");
 2168            language_server
 2169                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2170                    text_document,
 2171                    options: lsp_command::lsp_formatting_options(settings),
 2172                    work_done_progress_params: Default::default(),
 2173                })
 2174                .await
 2175                .into_response()?
 2176        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2177            let _timer = zlog::time!(logger => "format-range");
 2178            let buffer_start = lsp::Position::new(0, 0);
 2179            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2180            language_server
 2181                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2182                    text_document: text_document.clone(),
 2183                    range: lsp::Range::new(buffer_start, buffer_end),
 2184                    options: lsp_command::lsp_formatting_options(settings),
 2185                    work_done_progress_params: Default::default(),
 2186                })
 2187                .await
 2188                .into_response()?
 2189        } else {
 2190            None
 2191        };
 2192
 2193        if let Some(lsp_edits) = lsp_edits {
 2194            this.update(cx, |this, cx| {
 2195                this.as_local_mut().unwrap().edits_from_lsp(
 2196                    buffer,
 2197                    lsp_edits,
 2198                    language_server.server_id(),
 2199                    None,
 2200                    cx,
 2201                )
 2202            })?
 2203            .await
 2204        } else {
 2205            Ok(Vec::with_capacity(0))
 2206        }
 2207    }
 2208
 2209    async fn format_via_external_command(
 2210        buffer: &FormattableBuffer,
 2211        command: &str,
 2212        arguments: Option<&[String]>,
 2213        cx: &mut AsyncApp,
 2214    ) -> Result<Option<Diff>> {
 2215        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2216            let file = File::from_dyn(buffer.file())?;
 2217            let worktree = file.worktree.read(cx);
 2218            let mut worktree_path = worktree.abs_path().to_path_buf();
 2219            if worktree.root_entry()?.is_file() {
 2220                worktree_path.pop();
 2221            }
 2222            Some(worktree_path)
 2223        })?;
 2224
 2225        let mut child = util::command::new_smol_command(command);
 2226
 2227        if let Some(buffer_env) = buffer.env.as_ref() {
 2228            child.envs(buffer_env);
 2229        }
 2230
 2231        if let Some(working_dir_path) = working_dir_path {
 2232            child.current_dir(working_dir_path);
 2233        }
 2234
 2235        if let Some(arguments) = arguments {
 2236            child.args(arguments.iter().map(|arg| {
 2237                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2238                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2239                } else {
 2240                    arg.replace("{buffer_path}", "Untitled")
 2241                }
 2242            }));
 2243        }
 2244
 2245        let mut child = child
 2246            .stdin(smol::process::Stdio::piped())
 2247            .stdout(smol::process::Stdio::piped())
 2248            .stderr(smol::process::Stdio::piped())
 2249            .spawn()?;
 2250
 2251        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2252        let text = buffer
 2253            .handle
 2254            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2255        for chunk in text.chunks() {
 2256            stdin.write_all(chunk.as_bytes()).await?;
 2257        }
 2258        stdin.flush().await?;
 2259
 2260        let output = child.output().await?;
 2261        anyhow::ensure!(
 2262            output.status.success(),
 2263            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2264            output.status.code(),
 2265            String::from_utf8_lossy(&output.stdout),
 2266            String::from_utf8_lossy(&output.stderr),
 2267        );
 2268
 2269        let stdout = String::from_utf8(output.stdout)?;
 2270        Ok(Some(
 2271            buffer
 2272                .handle
 2273                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2274                .await,
 2275        ))
 2276    }
 2277
 2278    async fn try_resolve_code_action(
 2279        lang_server: &LanguageServer,
 2280        action: &mut CodeAction,
 2281    ) -> anyhow::Result<()> {
 2282        match &mut action.lsp_action {
 2283            LspAction::Action(lsp_action) => {
 2284                if !action.resolved
 2285                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2286                    && lsp_action.data.is_some()
 2287                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2288                {
 2289                    **lsp_action = lang_server
 2290                        .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2291                        .await
 2292                        .into_response()?;
 2293                }
 2294            }
 2295            LspAction::CodeLens(lens) => {
 2296                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2297                    *lens = lang_server
 2298                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2299                        .await
 2300                        .into_response()?;
 2301                }
 2302            }
 2303            LspAction::Command(_) => {}
 2304        }
 2305
 2306        action.resolved = true;
 2307        anyhow::Ok(())
 2308    }
 2309
 2310    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2311        let buffer = buffer_handle.read(cx);
 2312
 2313        let file = buffer.file().cloned();
 2314
 2315        let Some(file) = File::from_dyn(file.as_ref()) else {
 2316            return;
 2317        };
 2318        if !file.is_local() {
 2319            return;
 2320        }
 2321        let path = ProjectPath::from_file(file, cx);
 2322        let worktree_id = file.worktree_id(cx);
 2323        let language = buffer.language().cloned();
 2324
 2325        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2326            for (server_id, diagnostics) in
 2327                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2328            {
 2329                self.update_buffer_diagnostics(
 2330                    buffer_handle,
 2331                    server_id,
 2332                    None,
 2333                    None,
 2334                    None,
 2335                    Vec::new(),
 2336                    diagnostics,
 2337                    cx,
 2338                )
 2339                .log_err();
 2340            }
 2341        }
 2342        let Some(language) = language else {
 2343            return;
 2344        };
 2345        let Some(snapshot) = self
 2346            .worktree_store
 2347            .read(cx)
 2348            .worktree_for_id(worktree_id, cx)
 2349            .map(|worktree| worktree.read(cx).snapshot())
 2350        else {
 2351            return;
 2352        };
 2353        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2354
 2355        for server_id in
 2356            self.lsp_tree
 2357                .get(path, language.name(), language.manifest(), &delegate, cx)
 2358        {
 2359            let server = self
 2360                .language_servers
 2361                .get(&server_id)
 2362                .and_then(|server_state| {
 2363                    if let LanguageServerState::Running { server, .. } = server_state {
 2364                        Some(server.clone())
 2365                    } else {
 2366                        None
 2367                    }
 2368                });
 2369            let server = match server {
 2370                Some(server) => server,
 2371                None => continue,
 2372            };
 2373
 2374            buffer_handle.update(cx, |buffer, cx| {
 2375                buffer.set_completion_triggers(
 2376                    server.server_id(),
 2377                    server
 2378                        .capabilities()
 2379                        .completion_provider
 2380                        .as_ref()
 2381                        .and_then(|provider| {
 2382                            provider
 2383                                .trigger_characters
 2384                                .as_ref()
 2385                                .map(|characters| characters.iter().cloned().collect())
 2386                        })
 2387                        .unwrap_or_default(),
 2388                    cx,
 2389                );
 2390            });
 2391        }
 2392    }
 2393
 2394    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2395        buffer.update(cx, |buffer, cx| {
 2396            let Some(language) = buffer.language() else {
 2397                return;
 2398            };
 2399            let path = ProjectPath {
 2400                worktree_id: old_file.worktree_id(cx),
 2401                path: old_file.path.clone(),
 2402            };
 2403            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2404                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2405                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2406            }
 2407        });
 2408    }
 2409
 2410    fn update_buffer_diagnostics(
 2411        &mut self,
 2412        buffer: &Entity<Buffer>,
 2413        server_id: LanguageServerId,
 2414        registration_id: Option<Option<SharedString>>,
 2415        result_id: Option<SharedString>,
 2416        version: Option<i32>,
 2417        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2418        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2419        cx: &mut Context<LspStore>,
 2420    ) -> Result<()> {
 2421        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2422            Ordering::Equal
 2423                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2424                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2425                .then_with(|| a.severity.cmp(&b.severity))
 2426                .then_with(|| a.message.cmp(&b.message))
 2427        }
 2428
 2429        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2430        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2431        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2432
 2433        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2434            Ordering::Equal
 2435                .then_with(|| a.range.start.cmp(&b.range.start))
 2436                .then_with(|| b.range.end.cmp(&a.range.end))
 2437                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2438        });
 2439
 2440        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2441
 2442        let edits_since_save = std::cell::LazyCell::new(|| {
 2443            let saved_version = buffer.read(cx).saved_version();
 2444            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2445        });
 2446
 2447        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2448
 2449        for (new_diagnostic, entry) in diagnostics {
 2450            let start;
 2451            let end;
 2452            if new_diagnostic && entry.diagnostic.is_disk_based {
 2453                // Some diagnostics are based on files on disk instead of buffers'
 2454                // current contents. Adjust these diagnostics' ranges to reflect
 2455                // any unsaved edits.
 2456                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2457                // and were properly adjusted on reuse.
 2458                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2459                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2460            } else {
 2461                start = entry.range.start;
 2462                end = entry.range.end;
 2463            }
 2464
 2465            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2466                ..snapshot.clip_point_utf16(end, Bias::Right);
 2467
 2468            // Expand empty ranges by one codepoint
 2469            if range.start == range.end {
 2470                // This will be go to the next boundary when being clipped
 2471                range.end.column += 1;
 2472                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2473                if range.start == range.end && range.end.column > 0 {
 2474                    range.start.column -= 1;
 2475                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2476                }
 2477            }
 2478
 2479            sanitized_diagnostics.push(DiagnosticEntry {
 2480                range,
 2481                diagnostic: entry.diagnostic,
 2482            });
 2483        }
 2484        drop(edits_since_save);
 2485
 2486        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2487        buffer.update(cx, |buffer, cx| {
 2488            if let Some(registration_id) = registration_id {
 2489                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2490                    self.buffer_pull_diagnostics_result_ids
 2491                        .entry(server_id)
 2492                        .or_default()
 2493                        .entry(registration_id)
 2494                        .or_default()
 2495                        .insert(abs_path, result_id);
 2496                }
 2497            }
 2498
 2499            buffer.update_diagnostics(server_id, set, cx)
 2500        });
 2501
 2502        Ok(())
 2503    }
 2504
 2505    fn register_language_server_for_invisible_worktree(
 2506        &mut self,
 2507        worktree: &Entity<Worktree>,
 2508        language_server_id: LanguageServerId,
 2509        cx: &mut App,
 2510    ) {
 2511        let worktree = worktree.read(cx);
 2512        let worktree_id = worktree.id();
 2513        debug_assert!(!worktree.is_visible());
 2514        let Some(mut origin_seed) = self
 2515            .language_server_ids
 2516            .iter()
 2517            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2518        else {
 2519            return;
 2520        };
 2521        origin_seed.worktree_id = worktree_id;
 2522        self.language_server_ids
 2523            .entry(origin_seed)
 2524            .or_insert_with(|| UnifiedLanguageServer {
 2525                id: language_server_id,
 2526                project_roots: Default::default(),
 2527            });
 2528    }
 2529
 2530    fn register_buffer_with_language_servers(
 2531        &mut self,
 2532        buffer_handle: &Entity<Buffer>,
 2533        only_register_servers: HashSet<LanguageServerSelector>,
 2534        cx: &mut Context<LspStore>,
 2535    ) {
 2536        let buffer = buffer_handle.read(cx);
 2537        let buffer_id = buffer.remote_id();
 2538
 2539        let Some(file) = File::from_dyn(buffer.file()) else {
 2540            return;
 2541        };
 2542        if !file.is_local() {
 2543            return;
 2544        }
 2545
 2546        let abs_path = file.abs_path(cx);
 2547        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2548            return;
 2549        };
 2550        let initial_snapshot = buffer.text_snapshot();
 2551        let worktree_id = file.worktree_id(cx);
 2552
 2553        let Some(language) = buffer.language().cloned() else {
 2554            return;
 2555        };
 2556        let path: Arc<RelPath> = file
 2557            .path()
 2558            .parent()
 2559            .map(Arc::from)
 2560            .unwrap_or_else(|| file.path().clone());
 2561        let Some(worktree) = self
 2562            .worktree_store
 2563            .read(cx)
 2564            .worktree_for_id(worktree_id, cx)
 2565        else {
 2566            return;
 2567        };
 2568        let language_name = language.name();
 2569        let (reused, delegate, servers) = self
 2570            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2571            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2572            .unwrap_or_else(|| {
 2573                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2574                let delegate: Arc<dyn ManifestDelegate> =
 2575                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2576
 2577                let servers = self
 2578                    .lsp_tree
 2579                    .walk(
 2580                        ProjectPath { worktree_id, path },
 2581                        language.name(),
 2582                        language.manifest(),
 2583                        &delegate,
 2584                        cx,
 2585                    )
 2586                    .collect::<Vec<_>>();
 2587                (false, lsp_delegate, servers)
 2588            });
 2589        let servers_and_adapters = servers
 2590            .into_iter()
 2591            .filter_map(|server_node| {
 2592                if reused && server_node.server_id().is_none() {
 2593                    return None;
 2594                }
 2595                if !only_register_servers.is_empty() {
 2596                    if let Some(server_id) = server_node.server_id()
 2597                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2598                    {
 2599                        return None;
 2600                    }
 2601                    if let Some(name) = server_node.name()
 2602                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2603                    {
 2604                        return None;
 2605                    }
 2606                }
 2607
 2608                let server_id = server_node.server_id_or_init(|disposition| {
 2609                    let path = &disposition.path;
 2610
 2611                    {
 2612                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2613
 2614                        let server_id = self.get_or_insert_language_server(
 2615                            &worktree,
 2616                            delegate.clone(),
 2617                            disposition,
 2618                            &language_name,
 2619                            cx,
 2620                        );
 2621
 2622                        if let Some(state) = self.language_servers.get(&server_id)
 2623                            && let Ok(uri) = uri
 2624                        {
 2625                            state.add_workspace_folder(uri);
 2626                        };
 2627                        server_id
 2628                    }
 2629                })?;
 2630                let server_state = self.language_servers.get(&server_id)?;
 2631                if let LanguageServerState::Running {
 2632                    server, adapter, ..
 2633                } = server_state
 2634                {
 2635                    Some((server.clone(), adapter.clone()))
 2636                } else {
 2637                    None
 2638                }
 2639            })
 2640            .collect::<Vec<_>>();
 2641        for (server, adapter) in servers_and_adapters {
 2642            buffer_handle.update(cx, |buffer, cx| {
 2643                buffer.set_completion_triggers(
 2644                    server.server_id(),
 2645                    server
 2646                        .capabilities()
 2647                        .completion_provider
 2648                        .as_ref()
 2649                        .and_then(|provider| {
 2650                            provider
 2651                                .trigger_characters
 2652                                .as_ref()
 2653                                .map(|characters| characters.iter().cloned().collect())
 2654                        })
 2655                        .unwrap_or_default(),
 2656                    cx,
 2657                );
 2658            });
 2659
 2660            let snapshot = LspBufferSnapshot {
 2661                version: 0,
 2662                snapshot: initial_snapshot.clone(),
 2663            };
 2664
 2665            let mut registered = false;
 2666            self.buffer_snapshots
 2667                .entry(buffer_id)
 2668                .or_default()
 2669                .entry(server.server_id())
 2670                .or_insert_with(|| {
 2671                    registered = true;
 2672                    server.register_buffer(
 2673                        uri.clone(),
 2674                        adapter.language_id(&language.name()),
 2675                        0,
 2676                        initial_snapshot.text(),
 2677                    );
 2678
 2679                    vec![snapshot]
 2680                });
 2681
 2682            self.buffers_opened_in_servers
 2683                .entry(buffer_id)
 2684                .or_default()
 2685                .insert(server.server_id());
 2686            if registered {
 2687                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2688                    language_server_id: server.server_id(),
 2689                    name: None,
 2690                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2691                        proto::RegisteredForBuffer {
 2692                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2693                            buffer_id: buffer_id.to_proto(),
 2694                        },
 2695                    ),
 2696                });
 2697            }
 2698        }
 2699    }
 2700
 2701    fn reuse_existing_language_server<'lang_name>(
 2702        &self,
 2703        server_tree: &LanguageServerTree,
 2704        worktree: &Entity<Worktree>,
 2705        language_name: &'lang_name LanguageName,
 2706        cx: &mut App,
 2707    ) -> Option<(
 2708        Arc<LocalLspAdapterDelegate>,
 2709        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2710    )> {
 2711        if worktree.read(cx).is_visible() {
 2712            return None;
 2713        }
 2714
 2715        let worktree_store = self.worktree_store.read(cx);
 2716        let servers = server_tree
 2717            .instances
 2718            .iter()
 2719            .filter(|(worktree_id, _)| {
 2720                worktree_store
 2721                    .worktree_for_id(**worktree_id, cx)
 2722                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2723            })
 2724            .flat_map(|(worktree_id, servers)| {
 2725                servers
 2726                    .roots
 2727                    .iter()
 2728                    .flat_map(|(_, language_servers)| language_servers)
 2729                    .map(move |(_, (server_node, server_languages))| {
 2730                        (worktree_id, server_node, server_languages)
 2731                    })
 2732                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2733                    .map(|(worktree_id, server_node, _)| {
 2734                        (
 2735                            *worktree_id,
 2736                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2737                        )
 2738                    })
 2739            })
 2740            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2741                acc.entry(worktree_id)
 2742                    .or_insert_with(Vec::new)
 2743                    .push(server_node);
 2744                acc
 2745            })
 2746            .into_values()
 2747            .max_by_key(|servers| servers.len())?;
 2748
 2749        let worktree_id = worktree.read(cx).id();
 2750        let apply = move |tree: &mut LanguageServerTree| {
 2751            for server_node in &servers {
 2752                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2753            }
 2754            servers
 2755        };
 2756
 2757        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2758        Some((delegate, apply))
 2759    }
 2760
 2761    pub(crate) fn unregister_old_buffer_from_language_servers(
 2762        &mut self,
 2763        buffer: &Entity<Buffer>,
 2764        old_file: &File,
 2765        cx: &mut App,
 2766    ) {
 2767        let old_path = match old_file.as_local() {
 2768            Some(local) => local.abs_path(cx),
 2769            None => return,
 2770        };
 2771
 2772        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2773            debug_panic!("{old_path:?} is not parseable as an URI");
 2774            return;
 2775        };
 2776        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2777    }
 2778
 2779    pub(crate) fn unregister_buffer_from_language_servers(
 2780        &mut self,
 2781        buffer: &Entity<Buffer>,
 2782        file_url: &lsp::Uri,
 2783        cx: &mut App,
 2784    ) {
 2785        buffer.update(cx, |buffer, cx| {
 2786            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2787
 2788            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2789                if snapshots
 2790                    .as_mut()
 2791                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2792                {
 2793                    language_server.unregister_buffer(file_url.clone());
 2794                }
 2795            }
 2796        });
 2797    }
 2798
 2799    fn buffer_snapshot_for_lsp_version(
 2800        &mut self,
 2801        buffer: &Entity<Buffer>,
 2802        server_id: LanguageServerId,
 2803        version: Option<i32>,
 2804        cx: &App,
 2805    ) -> Result<TextBufferSnapshot> {
 2806        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2807
 2808        if let Some(version) = version {
 2809            let buffer_id = buffer.read(cx).remote_id();
 2810            let snapshots = if let Some(snapshots) = self
 2811                .buffer_snapshots
 2812                .get_mut(&buffer_id)
 2813                .and_then(|m| m.get_mut(&server_id))
 2814            {
 2815                snapshots
 2816            } else if version == 0 {
 2817                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2818                // We detect this case and treat it as if the version was `None`.
 2819                return Ok(buffer.read(cx).text_snapshot());
 2820            } else {
 2821                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2822            };
 2823
 2824            let found_snapshot = snapshots
 2825                    .binary_search_by_key(&version, |e| e.version)
 2826                    .map(|ix| snapshots[ix].snapshot.clone())
 2827                    .map_err(|_| {
 2828                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2829                    })?;
 2830
 2831            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2832            Ok(found_snapshot)
 2833        } else {
 2834            Ok((buffer.read(cx)).text_snapshot())
 2835        }
 2836    }
 2837
 2838    async fn get_server_code_actions_from_action_kinds(
 2839        lsp_store: &WeakEntity<LspStore>,
 2840        language_server_id: LanguageServerId,
 2841        code_action_kinds: Vec<lsp::CodeActionKind>,
 2842        buffer: &Entity<Buffer>,
 2843        cx: &mut AsyncApp,
 2844    ) -> Result<Vec<CodeAction>> {
 2845        let actions = lsp_store
 2846            .update(cx, move |this, cx| {
 2847                let request = GetCodeActions {
 2848                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 2849                    kinds: Some(code_action_kinds),
 2850                };
 2851                let server = LanguageServerToQuery::Other(language_server_id);
 2852                this.request_lsp(buffer.clone(), server, request, cx)
 2853            })?
 2854            .await?;
 2855        Ok(actions)
 2856    }
 2857
 2858    pub async fn execute_code_actions_on_server(
 2859        lsp_store: &WeakEntity<LspStore>,
 2860        language_server: &Arc<LanguageServer>,
 2861
 2862        actions: Vec<CodeAction>,
 2863        push_to_history: bool,
 2864        project_transaction: &mut ProjectTransaction,
 2865        cx: &mut AsyncApp,
 2866    ) -> anyhow::Result<()> {
 2867        for mut action in actions {
 2868            Self::try_resolve_code_action(language_server, &mut action)
 2869                .await
 2870                .context("resolving a formatting code action")?;
 2871
 2872            if let Some(edit) = action.lsp_action.edit() {
 2873                if edit.changes.is_none() && edit.document_changes.is_none() {
 2874                    continue;
 2875                }
 2876
 2877                let new = Self::deserialize_workspace_edit(
 2878                    lsp_store.upgrade().context("project dropped")?,
 2879                    edit.clone(),
 2880                    push_to_history,
 2881                    language_server.clone(),
 2882                    cx,
 2883                )
 2884                .await?;
 2885                project_transaction.0.extend(new.0);
 2886            }
 2887
 2888            if let Some(command) = action.lsp_action.command() {
 2889                let server_capabilities = language_server.capabilities();
 2890                let available_commands = server_capabilities
 2891                    .execute_command_provider
 2892                    .as_ref()
 2893                    .map(|options| options.commands.as_slice())
 2894                    .unwrap_or_default();
 2895                if available_commands.contains(&command.command) {
 2896                    lsp_store.update(cx, |lsp_store, _| {
 2897                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2898                            mode.last_workspace_edits_by_language_server
 2899                                .remove(&language_server.server_id());
 2900                        }
 2901                    })?;
 2902
 2903                    language_server
 2904                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2905                            command: command.command.clone(),
 2906                            arguments: command.arguments.clone().unwrap_or_default(),
 2907                            ..Default::default()
 2908                        })
 2909                        .await
 2910                        .into_response()
 2911                        .context("execute command")?;
 2912
 2913                    lsp_store.update(cx, |this, _| {
 2914                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2915                            project_transaction.0.extend(
 2916                                mode.last_workspace_edits_by_language_server
 2917                                    .remove(&language_server.server_id())
 2918                                    .unwrap_or_default()
 2919                                    .0,
 2920                            )
 2921                        }
 2922                    })?;
 2923                } else {
 2924                    log::warn!(
 2925                        "Cannot execute a command {} not listed in the language server capabilities",
 2926                        command.command
 2927                    )
 2928                }
 2929            }
 2930        }
 2931        Ok(())
 2932    }
 2933
 2934    pub async fn deserialize_text_edits(
 2935        this: Entity<LspStore>,
 2936        buffer_to_edit: Entity<Buffer>,
 2937        edits: Vec<lsp::TextEdit>,
 2938        push_to_history: bool,
 2939        _: Arc<CachedLspAdapter>,
 2940        language_server: Arc<LanguageServer>,
 2941        cx: &mut AsyncApp,
 2942    ) -> Result<Option<Transaction>> {
 2943        let edits = this
 2944            .update(cx, |this, cx| {
 2945                this.as_local_mut().unwrap().edits_from_lsp(
 2946                    &buffer_to_edit,
 2947                    edits,
 2948                    language_server.server_id(),
 2949                    None,
 2950                    cx,
 2951                )
 2952            })?
 2953            .await?;
 2954
 2955        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2956            buffer.finalize_last_transaction();
 2957            buffer.start_transaction();
 2958            for (range, text) in edits {
 2959                buffer.edit([(range, text)], None, cx);
 2960            }
 2961
 2962            if buffer.end_transaction(cx).is_some() {
 2963                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2964                if !push_to_history {
 2965                    buffer.forget_transaction(transaction.id);
 2966                }
 2967                Some(transaction)
 2968            } else {
 2969                None
 2970            }
 2971        })?;
 2972
 2973        Ok(transaction)
 2974    }
 2975
 2976    #[allow(clippy::type_complexity)]
 2977    pub(crate) fn edits_from_lsp(
 2978        &mut self,
 2979        buffer: &Entity<Buffer>,
 2980        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2981        server_id: LanguageServerId,
 2982        version: Option<i32>,
 2983        cx: &mut Context<LspStore>,
 2984    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2985        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2986        cx.background_spawn(async move {
 2987            let snapshot = snapshot?;
 2988            let mut lsp_edits = lsp_edits
 2989                .into_iter()
 2990                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2991                .collect::<Vec<_>>();
 2992
 2993            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2994
 2995            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2996            let mut edits = Vec::new();
 2997            while let Some((range, mut new_text)) = lsp_edits.next() {
 2998                // Clip invalid ranges provided by the language server.
 2999                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3000                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3001
 3002                // Combine any LSP edits that are adjacent.
 3003                //
 3004                // Also, combine LSP edits that are separated from each other by only
 3005                // a newline. This is important because for some code actions,
 3006                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3007                // are separated by unchanged newline characters.
 3008                //
 3009                // In order for the diffing logic below to work properly, any edits that
 3010                // cancel each other out must be combined into one.
 3011                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3012                    if next_range.start.0 > range.end {
 3013                        if next_range.start.0.row > range.end.row + 1
 3014                            || next_range.start.0.column > 0
 3015                            || snapshot.clip_point_utf16(
 3016                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3017                                Bias::Left,
 3018                            ) > range.end
 3019                        {
 3020                            break;
 3021                        }
 3022                        new_text.push('\n');
 3023                    }
 3024                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3025                    new_text.push_str(next_text);
 3026                    lsp_edits.next();
 3027                }
 3028
 3029                // For multiline edits, perform a diff of the old and new text so that
 3030                // we can identify the changes more precisely, preserving the locations
 3031                // of any anchors positioned in the unchanged regions.
 3032                if range.end.row > range.start.row {
 3033                    let offset = range.start.to_offset(&snapshot);
 3034                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3035                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3036                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3037                        (
 3038                            snapshot.anchor_after(offset + range.start)
 3039                                ..snapshot.anchor_before(offset + range.end),
 3040                            replacement,
 3041                        )
 3042                    }));
 3043                } else if range.end == range.start {
 3044                    let anchor = snapshot.anchor_after(range.start);
 3045                    edits.push((anchor..anchor, new_text.into()));
 3046                } else {
 3047                    let edit_start = snapshot.anchor_after(range.start);
 3048                    let edit_end = snapshot.anchor_before(range.end);
 3049                    edits.push((edit_start..edit_end, new_text.into()));
 3050                }
 3051            }
 3052
 3053            Ok(edits)
 3054        })
 3055    }
 3056
 3057    pub(crate) async fn deserialize_workspace_edit(
 3058        this: Entity<LspStore>,
 3059        edit: lsp::WorkspaceEdit,
 3060        push_to_history: bool,
 3061        language_server: Arc<LanguageServer>,
 3062        cx: &mut AsyncApp,
 3063    ) -> Result<ProjectTransaction> {
 3064        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 3065
 3066        let mut operations = Vec::new();
 3067        if let Some(document_changes) = edit.document_changes {
 3068            match document_changes {
 3069                lsp::DocumentChanges::Edits(edits) => {
 3070                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3071                }
 3072                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3073            }
 3074        } else if let Some(changes) = edit.changes {
 3075            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3076                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3077                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3078                        uri,
 3079                        version: None,
 3080                    },
 3081                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3082                })
 3083            }));
 3084        }
 3085
 3086        let mut project_transaction = ProjectTransaction::default();
 3087        for operation in operations {
 3088            match operation {
 3089                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3090                    let abs_path = op
 3091                        .uri
 3092                        .to_file_path()
 3093                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3094
 3095                    if let Some(parent_path) = abs_path.parent() {
 3096                        fs.create_dir(parent_path).await?;
 3097                    }
 3098                    if abs_path.ends_with("/") {
 3099                        fs.create_dir(&abs_path).await?;
 3100                    } else {
 3101                        fs.create_file(
 3102                            &abs_path,
 3103                            op.options
 3104                                .map(|options| fs::CreateOptions {
 3105                                    overwrite: options.overwrite.unwrap_or(false),
 3106                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3107                                })
 3108                                .unwrap_or_default(),
 3109                        )
 3110                        .await?;
 3111                    }
 3112                }
 3113
 3114                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3115                    let source_abs_path = op
 3116                        .old_uri
 3117                        .to_file_path()
 3118                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3119                    let target_abs_path = op
 3120                        .new_uri
 3121                        .to_file_path()
 3122                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3123
 3124                    let options = fs::RenameOptions {
 3125                        overwrite: op
 3126                            .options
 3127                            .as_ref()
 3128                            .and_then(|options| options.overwrite)
 3129                            .unwrap_or(false),
 3130                        ignore_if_exists: op
 3131                            .options
 3132                            .as_ref()
 3133                            .and_then(|options| options.ignore_if_exists)
 3134                            .unwrap_or(false),
 3135                        create_parents: true,
 3136                    };
 3137
 3138                    fs.rename(&source_abs_path, &target_abs_path, options)
 3139                        .await?;
 3140                }
 3141
 3142                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3143                    let abs_path = op
 3144                        .uri
 3145                        .to_file_path()
 3146                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3147                    let options = op
 3148                        .options
 3149                        .map(|options| fs::RemoveOptions {
 3150                            recursive: options.recursive.unwrap_or(false),
 3151                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3152                        })
 3153                        .unwrap_or_default();
 3154                    if abs_path.ends_with("/") {
 3155                        fs.remove_dir(&abs_path, options).await?;
 3156                    } else {
 3157                        fs.remove_file(&abs_path, options).await?;
 3158                    }
 3159                }
 3160
 3161                lsp::DocumentChangeOperation::Edit(op) => {
 3162                    let buffer_to_edit = this
 3163                        .update(cx, |this, cx| {
 3164                            this.open_local_buffer_via_lsp(
 3165                                op.text_document.uri.clone(),
 3166                                language_server.server_id(),
 3167                                cx,
 3168                            )
 3169                        })?
 3170                        .await?;
 3171
 3172                    let edits = this
 3173                        .update(cx, |this, cx| {
 3174                            let path = buffer_to_edit.read(cx).project_path(cx);
 3175                            let active_entry = this.active_entry;
 3176                            let is_active_entry = path.is_some_and(|project_path| {
 3177                                this.worktree_store
 3178                                    .read(cx)
 3179                                    .entry_for_path(&project_path, cx)
 3180                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3181                            });
 3182                            let local = this.as_local_mut().unwrap();
 3183
 3184                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3185                            for edit in op.edits {
 3186                                match edit {
 3187                                    Edit::Plain(edit) => {
 3188                                        if !edits.contains(&edit) {
 3189                                            edits.push(edit)
 3190                                        }
 3191                                    }
 3192                                    Edit::Annotated(edit) => {
 3193                                        if !edits.contains(&edit.text_edit) {
 3194                                            edits.push(edit.text_edit)
 3195                                        }
 3196                                    }
 3197                                    Edit::Snippet(edit) => {
 3198                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3199                                        else {
 3200                                            continue;
 3201                                        };
 3202
 3203                                        if is_active_entry {
 3204                                            snippet_edits.push((edit.range, snippet));
 3205                                        } else {
 3206                                            // Since this buffer is not focused, apply a normal edit.
 3207                                            let new_edit = TextEdit {
 3208                                                range: edit.range,
 3209                                                new_text: snippet.text,
 3210                                            };
 3211                                            if !edits.contains(&new_edit) {
 3212                                                edits.push(new_edit);
 3213                                            }
 3214                                        }
 3215                                    }
 3216                                }
 3217                            }
 3218                            if !snippet_edits.is_empty() {
 3219                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3220                                let version = if let Some(buffer_version) = op.text_document.version
 3221                                {
 3222                                    local
 3223                                        .buffer_snapshot_for_lsp_version(
 3224                                            &buffer_to_edit,
 3225                                            language_server.server_id(),
 3226                                            Some(buffer_version),
 3227                                            cx,
 3228                                        )
 3229                                        .ok()
 3230                                        .map(|snapshot| snapshot.version)
 3231                                } else {
 3232                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3233                                };
 3234
 3235                                let most_recent_edit =
 3236                                    version.and_then(|version| version.most_recent());
 3237                                // Check if the edit that triggered that edit has been made by this participant.
 3238
 3239                                if let Some(most_recent_edit) = most_recent_edit {
 3240                                    cx.emit(LspStoreEvent::SnippetEdit {
 3241                                        buffer_id,
 3242                                        edits: snippet_edits,
 3243                                        most_recent_edit,
 3244                                    });
 3245                                }
 3246                            }
 3247
 3248                            local.edits_from_lsp(
 3249                                &buffer_to_edit,
 3250                                edits,
 3251                                language_server.server_id(),
 3252                                op.text_document.version,
 3253                                cx,
 3254                            )
 3255                        })?
 3256                        .await?;
 3257
 3258                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3259                        buffer.finalize_last_transaction();
 3260                        buffer.start_transaction();
 3261                        for (range, text) in edits {
 3262                            buffer.edit([(range, text)], None, cx);
 3263                        }
 3264
 3265                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3266                            if push_to_history {
 3267                                buffer.finalize_last_transaction();
 3268                                buffer.get_transaction(transaction_id).cloned()
 3269                            } else {
 3270                                buffer.forget_transaction(transaction_id)
 3271                            }
 3272                        })
 3273                    })?;
 3274                    if let Some(transaction) = transaction {
 3275                        project_transaction.0.insert(buffer_to_edit, transaction);
 3276                    }
 3277                }
 3278            }
 3279        }
 3280
 3281        Ok(project_transaction)
 3282    }
 3283
 3284    async fn on_lsp_workspace_edit(
 3285        this: WeakEntity<LspStore>,
 3286        params: lsp::ApplyWorkspaceEditParams,
 3287        server_id: LanguageServerId,
 3288        cx: &mut AsyncApp,
 3289    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3290        let this = this.upgrade().context("project project closed")?;
 3291        let language_server = this
 3292            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3293            .context("language server not found")?;
 3294        let transaction = Self::deserialize_workspace_edit(
 3295            this.clone(),
 3296            params.edit,
 3297            true,
 3298            language_server.clone(),
 3299            cx,
 3300        )
 3301        .await
 3302        .log_err();
 3303        this.update(cx, |this, _| {
 3304            if let Some(transaction) = transaction {
 3305                this.as_local_mut()
 3306                    .unwrap()
 3307                    .last_workspace_edits_by_language_server
 3308                    .insert(server_id, transaction);
 3309            }
 3310        })?;
 3311        Ok(lsp::ApplyWorkspaceEditResponse {
 3312            applied: true,
 3313            failed_change: None,
 3314            failure_reason: None,
 3315        })
 3316    }
 3317
 3318    fn remove_worktree(
 3319        &mut self,
 3320        id_to_remove: WorktreeId,
 3321        cx: &mut Context<LspStore>,
 3322    ) -> Vec<LanguageServerId> {
 3323        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3324        self.diagnostics.remove(&id_to_remove);
 3325        self.prettier_store.update(cx, |prettier_store, cx| {
 3326            prettier_store.remove_worktree(id_to_remove, cx);
 3327        });
 3328
 3329        let mut servers_to_remove = BTreeSet::default();
 3330        let mut servers_to_preserve = HashSet::default();
 3331        for (seed, state) in &self.language_server_ids {
 3332            if seed.worktree_id == id_to_remove {
 3333                servers_to_remove.insert(state.id);
 3334            } else {
 3335                servers_to_preserve.insert(state.id);
 3336            }
 3337        }
 3338        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3339        self.language_server_ids
 3340            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3341        for server_id_to_remove in &servers_to_remove {
 3342            self.language_server_watched_paths
 3343                .remove(server_id_to_remove);
 3344            self.language_server_paths_watched_for_rename
 3345                .remove(server_id_to_remove);
 3346            self.last_workspace_edits_by_language_server
 3347                .remove(server_id_to_remove);
 3348            self.language_servers.remove(server_id_to_remove);
 3349            self.buffer_pull_diagnostics_result_ids
 3350                .remove(server_id_to_remove);
 3351            self.workspace_pull_diagnostics_result_ids
 3352                .remove(server_id_to_remove);
 3353            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3354                buffer_servers.remove(server_id_to_remove);
 3355            }
 3356            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3357        }
 3358        servers_to_remove.into_iter().collect()
 3359    }
 3360
 3361    fn rebuild_watched_paths_inner<'a>(
 3362        &'a self,
 3363        language_server_id: LanguageServerId,
 3364        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3365        cx: &mut Context<LspStore>,
 3366    ) -> LanguageServerWatchedPathsBuilder {
 3367        let worktrees = self
 3368            .worktree_store
 3369            .read(cx)
 3370            .worktrees()
 3371            .filter_map(|worktree| {
 3372                self.language_servers_for_worktree(worktree.read(cx).id())
 3373                    .find(|server| server.server_id() == language_server_id)
 3374                    .map(|_| worktree)
 3375            })
 3376            .collect::<Vec<_>>();
 3377
 3378        let mut worktree_globs = HashMap::default();
 3379        let mut abs_globs = HashMap::default();
 3380        log::trace!(
 3381            "Processing new watcher paths for language server with id {}",
 3382            language_server_id
 3383        );
 3384
 3385        for watcher in watchers {
 3386            if let Some((worktree, literal_prefix, pattern)) =
 3387                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3388            {
 3389                worktree.update(cx, |worktree, _| {
 3390                    if let Some((tree, glob)) =
 3391                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3392                    {
 3393                        tree.add_path_prefix_to_scan(literal_prefix);
 3394                        worktree_globs
 3395                            .entry(tree.id())
 3396                            .or_insert_with(GlobSetBuilder::new)
 3397                            .add(glob);
 3398                    }
 3399                });
 3400            } else {
 3401                let (path, pattern) = match &watcher.glob_pattern {
 3402                    lsp::GlobPattern::String(s) => {
 3403                        let watcher_path = SanitizedPath::new(s);
 3404                        let path = glob_literal_prefix(watcher_path.as_path());
 3405                        let pattern = watcher_path
 3406                            .as_path()
 3407                            .strip_prefix(&path)
 3408                            .map(|p| p.to_string_lossy().into_owned())
 3409                            .unwrap_or_else(|e| {
 3410                                debug_panic!(
 3411                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3412                                    s,
 3413                                    path.display(),
 3414                                    e
 3415                                );
 3416                                watcher_path.as_path().to_string_lossy().into_owned()
 3417                            });
 3418                        (path, pattern)
 3419                    }
 3420                    lsp::GlobPattern::Relative(rp) => {
 3421                        let Ok(mut base_uri) = match &rp.base_uri {
 3422                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3423                            lsp::OneOf::Right(base_uri) => base_uri,
 3424                        }
 3425                        .to_file_path() else {
 3426                            continue;
 3427                        };
 3428
 3429                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3430                        let pattern = Path::new(&rp.pattern)
 3431                            .strip_prefix(&path)
 3432                            .map(|p| p.to_string_lossy().into_owned())
 3433                            .unwrap_or_else(|e| {
 3434                                debug_panic!(
 3435                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3436                                    rp.pattern,
 3437                                    path.display(),
 3438                                    e
 3439                                );
 3440                                rp.pattern.clone()
 3441                            });
 3442                        base_uri.push(path);
 3443                        (base_uri, pattern)
 3444                    }
 3445                };
 3446
 3447                if let Some(glob) = Glob::new(&pattern).log_err() {
 3448                    if !path
 3449                        .components()
 3450                        .any(|c| matches!(c, path::Component::Normal(_)))
 3451                    {
 3452                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3453                        // rather than adding a new watcher for `/`.
 3454                        for worktree in &worktrees {
 3455                            worktree_globs
 3456                                .entry(worktree.read(cx).id())
 3457                                .or_insert_with(GlobSetBuilder::new)
 3458                                .add(glob.clone());
 3459                        }
 3460                    } else {
 3461                        abs_globs
 3462                            .entry(path.into())
 3463                            .or_insert_with(GlobSetBuilder::new)
 3464                            .add(glob);
 3465                    }
 3466                }
 3467            }
 3468        }
 3469
 3470        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3471        for (worktree_id, builder) in worktree_globs {
 3472            if let Ok(globset) = builder.build() {
 3473                watch_builder.watch_worktree(worktree_id, globset);
 3474            }
 3475        }
 3476        for (abs_path, builder) in abs_globs {
 3477            if let Ok(globset) = builder.build() {
 3478                watch_builder.watch_abs_path(abs_path, globset);
 3479            }
 3480        }
 3481        watch_builder
 3482    }
 3483
 3484    fn worktree_and_path_for_file_watcher(
 3485        worktrees: &[Entity<Worktree>],
 3486        watcher: &FileSystemWatcher,
 3487        cx: &App,
 3488    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3489        worktrees.iter().find_map(|worktree| {
 3490            let tree = worktree.read(cx);
 3491            let worktree_root_path = tree.abs_path();
 3492            let path_style = tree.path_style();
 3493            match &watcher.glob_pattern {
 3494                lsp::GlobPattern::String(s) => {
 3495                    let watcher_path = SanitizedPath::new(s);
 3496                    let relative = watcher_path
 3497                        .as_path()
 3498                        .strip_prefix(&worktree_root_path)
 3499                        .ok()?;
 3500                    let literal_prefix = glob_literal_prefix(relative);
 3501                    Some((
 3502                        worktree.clone(),
 3503                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3504                        relative.to_string_lossy().into_owned(),
 3505                    ))
 3506                }
 3507                lsp::GlobPattern::Relative(rp) => {
 3508                    let base_uri = match &rp.base_uri {
 3509                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3510                        lsp::OneOf::Right(base_uri) => base_uri,
 3511                    }
 3512                    .to_file_path()
 3513                    .ok()?;
 3514                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3515                    let mut literal_prefix = relative.to_owned();
 3516                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3517                    Some((
 3518                        worktree.clone(),
 3519                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3520                        rp.pattern.clone(),
 3521                    ))
 3522                }
 3523            }
 3524        })
 3525    }
 3526
 3527    fn rebuild_watched_paths(
 3528        &mut self,
 3529        language_server_id: LanguageServerId,
 3530        cx: &mut Context<LspStore>,
 3531    ) {
 3532        let Some(registrations) = self
 3533            .language_server_dynamic_registrations
 3534            .get(&language_server_id)
 3535        else {
 3536            return;
 3537        };
 3538
 3539        let watch_builder = self.rebuild_watched_paths_inner(
 3540            language_server_id,
 3541            registrations.did_change_watched_files.values().flatten(),
 3542            cx,
 3543        );
 3544        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3545        self.language_server_watched_paths
 3546            .insert(language_server_id, watcher);
 3547
 3548        cx.notify();
 3549    }
 3550
 3551    fn on_lsp_did_change_watched_files(
 3552        &mut self,
 3553        language_server_id: LanguageServerId,
 3554        registration_id: &str,
 3555        params: DidChangeWatchedFilesRegistrationOptions,
 3556        cx: &mut Context<LspStore>,
 3557    ) {
 3558        let registrations = self
 3559            .language_server_dynamic_registrations
 3560            .entry(language_server_id)
 3561            .or_default();
 3562
 3563        registrations
 3564            .did_change_watched_files
 3565            .insert(registration_id.to_string(), params.watchers);
 3566
 3567        self.rebuild_watched_paths(language_server_id, cx);
 3568    }
 3569
 3570    fn on_lsp_unregister_did_change_watched_files(
 3571        &mut self,
 3572        language_server_id: LanguageServerId,
 3573        registration_id: &str,
 3574        cx: &mut Context<LspStore>,
 3575    ) {
 3576        let registrations = self
 3577            .language_server_dynamic_registrations
 3578            .entry(language_server_id)
 3579            .or_default();
 3580
 3581        if registrations
 3582            .did_change_watched_files
 3583            .remove(registration_id)
 3584            .is_some()
 3585        {
 3586            log::info!(
 3587                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3588                language_server_id,
 3589                registration_id
 3590            );
 3591        } else {
 3592            log::warn!(
 3593                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3594                language_server_id,
 3595                registration_id
 3596            );
 3597        }
 3598
 3599        self.rebuild_watched_paths(language_server_id, cx);
 3600    }
 3601
 3602    async fn initialization_options_for_adapter(
 3603        adapter: Arc<dyn LspAdapter>,
 3604        delegate: &Arc<dyn LspAdapterDelegate>,
 3605    ) -> Result<Option<serde_json::Value>> {
 3606        let Some(mut initialization_config) =
 3607            adapter.clone().initialization_options(delegate).await?
 3608        else {
 3609            return Ok(None);
 3610        };
 3611
 3612        for other_adapter in delegate.registered_lsp_adapters() {
 3613            if other_adapter.name() == adapter.name() {
 3614                continue;
 3615            }
 3616            if let Ok(Some(target_config)) = other_adapter
 3617                .clone()
 3618                .additional_initialization_options(adapter.name(), delegate)
 3619                .await
 3620            {
 3621                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3622            }
 3623        }
 3624
 3625        Ok(Some(initialization_config))
 3626    }
 3627
 3628    async fn workspace_configuration_for_adapter(
 3629        adapter: Arc<dyn LspAdapter>,
 3630        delegate: &Arc<dyn LspAdapterDelegate>,
 3631        toolchain: Option<Toolchain>,
 3632        requested_uri: Option<Uri>,
 3633        cx: &mut AsyncApp,
 3634    ) -> Result<serde_json::Value> {
 3635        let mut workspace_config = adapter
 3636            .clone()
 3637            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3638            .await?;
 3639
 3640        for other_adapter in delegate.registered_lsp_adapters() {
 3641            if other_adapter.name() == adapter.name() {
 3642                continue;
 3643            }
 3644            if let Ok(Some(target_config)) = other_adapter
 3645                .clone()
 3646                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3647                .await
 3648            {
 3649                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3650            }
 3651        }
 3652
 3653        Ok(workspace_config)
 3654    }
 3655
 3656    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3657        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3658            Some(server.clone())
 3659        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3660            Some(Arc::clone(server))
 3661        } else {
 3662            None
 3663        }
 3664    }
 3665}
 3666
 3667fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3668    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3669        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3670            language_server_id: server.server_id(),
 3671            name: Some(server.name()),
 3672            message: proto::update_language_server::Variant::MetadataUpdated(
 3673                proto::ServerMetadataUpdated {
 3674                    capabilities: Some(capabilities),
 3675                    binary: Some(proto::LanguageServerBinaryInfo {
 3676                        path: server.binary().path.to_string_lossy().into_owned(),
 3677                        arguments: server
 3678                            .binary()
 3679                            .arguments
 3680                            .iter()
 3681                            .map(|arg| arg.to_string_lossy().into_owned())
 3682                            .collect(),
 3683                    }),
 3684                    configuration: serde_json::to_string(server.configuration()).ok(),
 3685                    workspace_folders: server
 3686                        .workspace_folders()
 3687                        .iter()
 3688                        .map(|uri| uri.to_string())
 3689                        .collect(),
 3690                },
 3691            ),
 3692        });
 3693    }
 3694}
 3695
 3696#[derive(Debug)]
 3697pub struct FormattableBuffer {
 3698    handle: Entity<Buffer>,
 3699    abs_path: Option<PathBuf>,
 3700    env: Option<HashMap<String, String>>,
 3701    ranges: Option<Vec<Range<Anchor>>>,
 3702}
 3703
 3704pub struct RemoteLspStore {
 3705    upstream_client: Option<AnyProtoClient>,
 3706    upstream_project_id: u64,
 3707}
 3708
 3709pub(crate) enum LspStoreMode {
 3710    Local(LocalLspStore),   // ssh host and collab host
 3711    Remote(RemoteLspStore), // collab guest
 3712}
 3713
 3714impl LspStoreMode {
 3715    fn is_local(&self) -> bool {
 3716        matches!(self, LspStoreMode::Local(_))
 3717    }
 3718}
 3719
 3720pub struct LspStore {
 3721    mode: LspStoreMode,
 3722    last_formatting_failure: Option<String>,
 3723    downstream_client: Option<(AnyProtoClient, u64)>,
 3724    nonce: u128,
 3725    buffer_store: Entity<BufferStore>,
 3726    worktree_store: Entity<WorktreeStore>,
 3727    pub languages: Arc<LanguageRegistry>,
 3728    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3729    active_entry: Option<ProjectEntryId>,
 3730    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3731    _maintain_buffer_languages: Task<()>,
 3732    diagnostic_summaries:
 3733        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3734    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3735    lsp_data: HashMap<BufferId, BufferLspData>,
 3736    next_hint_id: Arc<AtomicUsize>,
 3737}
 3738
 3739#[derive(Debug)]
 3740pub struct BufferLspData {
 3741    buffer_version: Global,
 3742    document_colors: Option<DocumentColorData>,
 3743    code_lens: Option<CodeLensData>,
 3744    inlay_hints: BufferInlayHints,
 3745    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3746    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3747}
 3748
 3749#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3750struct LspKey {
 3751    request_type: TypeId,
 3752    server_queried: Option<LanguageServerId>,
 3753}
 3754
 3755impl BufferLspData {
 3756    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3757        Self {
 3758            buffer_version: buffer.read(cx).version(),
 3759            document_colors: None,
 3760            code_lens: None,
 3761            inlay_hints: BufferInlayHints::new(buffer, cx),
 3762            lsp_requests: HashMap::default(),
 3763            chunk_lsp_requests: HashMap::default(),
 3764        }
 3765    }
 3766
 3767    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3768        if let Some(document_colors) = &mut self.document_colors {
 3769            document_colors.colors.remove(&for_server);
 3770            document_colors.cache_version += 1;
 3771        }
 3772
 3773        if let Some(code_lens) = &mut self.code_lens {
 3774            code_lens.lens.remove(&for_server);
 3775        }
 3776
 3777        self.inlay_hints.remove_server_data(for_server);
 3778    }
 3779
 3780    #[cfg(any(test, feature = "test-support"))]
 3781    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3782        &self.inlay_hints
 3783    }
 3784}
 3785
 3786#[derive(Debug, Default, Clone)]
 3787pub struct DocumentColors {
 3788    pub colors: HashSet<DocumentColor>,
 3789    pub cache_version: Option<usize>,
 3790}
 3791
 3792type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3793type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3794
 3795#[derive(Debug, Default)]
 3796struct DocumentColorData {
 3797    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3798    cache_version: usize,
 3799    colors_update: Option<(Global, DocumentColorTask)>,
 3800}
 3801
 3802#[derive(Debug, Default)]
 3803struct CodeLensData {
 3804    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3805    update: Option<(Global, CodeLensTask)>,
 3806}
 3807
 3808#[derive(Debug)]
 3809pub enum LspStoreEvent {
 3810    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3811    LanguageServerRemoved(LanguageServerId),
 3812    LanguageServerUpdate {
 3813        language_server_id: LanguageServerId,
 3814        name: Option<LanguageServerName>,
 3815        message: proto::update_language_server::Variant,
 3816    },
 3817    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3818    LanguageServerPrompt(LanguageServerPromptRequest),
 3819    LanguageDetected {
 3820        buffer: Entity<Buffer>,
 3821        new_language: Option<Arc<Language>>,
 3822    },
 3823    Notification(String),
 3824    RefreshInlayHints {
 3825        server_id: LanguageServerId,
 3826        request_id: Option<usize>,
 3827    },
 3828    RefreshCodeLens,
 3829    DiagnosticsUpdated {
 3830        server_id: LanguageServerId,
 3831        paths: Vec<ProjectPath>,
 3832    },
 3833    DiskBasedDiagnosticsStarted {
 3834        language_server_id: LanguageServerId,
 3835    },
 3836    DiskBasedDiagnosticsFinished {
 3837        language_server_id: LanguageServerId,
 3838    },
 3839    SnippetEdit {
 3840        buffer_id: BufferId,
 3841        edits: Vec<(lsp::Range, Snippet)>,
 3842        most_recent_edit: clock::Lamport,
 3843    },
 3844}
 3845
 3846#[derive(Clone, Debug, Serialize)]
 3847pub struct LanguageServerStatus {
 3848    pub name: LanguageServerName,
 3849    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3850    pub has_pending_diagnostic_updates: bool,
 3851    pub progress_tokens: HashSet<ProgressToken>,
 3852    pub worktree: Option<WorktreeId>,
 3853    pub binary: Option<LanguageServerBinary>,
 3854    pub configuration: Option<Value>,
 3855    pub workspace_folders: BTreeSet<Uri>,
 3856}
 3857
 3858#[derive(Clone, Debug)]
 3859struct CoreSymbol {
 3860    pub language_server_name: LanguageServerName,
 3861    pub source_worktree_id: WorktreeId,
 3862    pub source_language_server_id: LanguageServerId,
 3863    pub path: SymbolLocation,
 3864    pub name: String,
 3865    pub kind: lsp::SymbolKind,
 3866    pub range: Range<Unclipped<PointUtf16>>,
 3867}
 3868
 3869#[derive(Clone, Debug, PartialEq, Eq)]
 3870pub enum SymbolLocation {
 3871    InProject(ProjectPath),
 3872    OutsideProject {
 3873        abs_path: Arc<Path>,
 3874        signature: [u8; 32],
 3875    },
 3876}
 3877
 3878impl SymbolLocation {
 3879    fn file_name(&self) -> Option<&str> {
 3880        match self {
 3881            Self::InProject(path) => path.path.file_name(),
 3882            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3883        }
 3884    }
 3885}
 3886
 3887impl LspStore {
 3888    pub fn init(client: &AnyProtoClient) {
 3889        client.add_entity_request_handler(Self::handle_lsp_query);
 3890        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3891        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3892        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3893        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3894        client.add_entity_message_handler(Self::handle_start_language_server);
 3895        client.add_entity_message_handler(Self::handle_update_language_server);
 3896        client.add_entity_message_handler(Self::handle_language_server_log);
 3897        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3898        client.add_entity_request_handler(Self::handle_format_buffers);
 3899        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3900        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3901        client.add_entity_request_handler(Self::handle_apply_code_action);
 3902        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3903        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3904        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3905        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3906        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3907        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3908        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3909        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3910        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3911        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3912        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3913        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3914        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3915        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3916        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3917        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3918        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3919
 3920        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3921        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3922        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3923        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3924        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3925        client.add_entity_request_handler(
 3926            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3927        );
 3928        client.add_entity_request_handler(
 3929            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3930        );
 3931        client.add_entity_request_handler(
 3932            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3933        );
 3934    }
 3935
 3936    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3937        match &self.mode {
 3938            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3939            _ => None,
 3940        }
 3941    }
 3942
 3943    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3944        match &self.mode {
 3945            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3946            _ => None,
 3947        }
 3948    }
 3949
 3950    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3951        match &mut self.mode {
 3952            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3953            _ => None,
 3954        }
 3955    }
 3956
 3957    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3958        match &self.mode {
 3959            LspStoreMode::Remote(RemoteLspStore {
 3960                upstream_client: Some(upstream_client),
 3961                upstream_project_id,
 3962                ..
 3963            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3964
 3965            LspStoreMode::Remote(RemoteLspStore {
 3966                upstream_client: None,
 3967                ..
 3968            }) => None,
 3969            LspStoreMode::Local(_) => None,
 3970        }
 3971    }
 3972
 3973    pub fn new_local(
 3974        buffer_store: Entity<BufferStore>,
 3975        worktree_store: Entity<WorktreeStore>,
 3976        prettier_store: Entity<PrettierStore>,
 3977        toolchain_store: Entity<LocalToolchainStore>,
 3978        environment: Entity<ProjectEnvironment>,
 3979        manifest_tree: Entity<ManifestTree>,
 3980        languages: Arc<LanguageRegistry>,
 3981        http_client: Arc<dyn HttpClient>,
 3982        fs: Arc<dyn Fs>,
 3983        cx: &mut Context<Self>,
 3984    ) -> Self {
 3985        let yarn = YarnPathStore::new(fs.clone(), cx);
 3986        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3987            .detach();
 3988        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3989            .detach();
 3990        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3991            .detach();
 3992        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3993            .detach();
 3994        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3995            .detach();
 3996        subscribe_to_binary_statuses(&languages, cx).detach();
 3997
 3998        let _maintain_workspace_config = {
 3999            let (sender, receiver) = watch::channel();
 4000            (Self::maintain_workspace_config(receiver, cx), sender)
 4001        };
 4002
 4003        Self {
 4004            mode: LspStoreMode::Local(LocalLspStore {
 4005                weak: cx.weak_entity(),
 4006                worktree_store: worktree_store.clone(),
 4007
 4008                supplementary_language_servers: Default::default(),
 4009                languages: languages.clone(),
 4010                language_server_ids: Default::default(),
 4011                language_servers: Default::default(),
 4012                last_workspace_edits_by_language_server: Default::default(),
 4013                language_server_watched_paths: Default::default(),
 4014                language_server_paths_watched_for_rename: Default::default(),
 4015                language_server_dynamic_registrations: Default::default(),
 4016                buffers_being_formatted: Default::default(),
 4017                buffer_snapshots: Default::default(),
 4018                prettier_store,
 4019                environment,
 4020                http_client,
 4021                fs,
 4022                yarn,
 4023                next_diagnostic_group_id: Default::default(),
 4024                diagnostics: Default::default(),
 4025                _subscription: cx.on_app_quit(|this, cx| {
 4026                    this.as_local_mut()
 4027                        .unwrap()
 4028                        .shutdown_language_servers_on_quit(cx)
 4029                }),
 4030                lsp_tree: LanguageServerTree::new(
 4031                    manifest_tree,
 4032                    languages.clone(),
 4033                    toolchain_store.clone(),
 4034                ),
 4035                toolchain_store,
 4036                registered_buffers: HashMap::default(),
 4037                buffers_opened_in_servers: HashMap::default(),
 4038                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4039                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4040                restricted_worktrees_tasks: HashMap::default(),
 4041                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4042                    .manifest_file_names(),
 4043            }),
 4044            last_formatting_failure: None,
 4045            downstream_client: None,
 4046            buffer_store,
 4047            worktree_store,
 4048            languages: languages.clone(),
 4049            language_server_statuses: Default::default(),
 4050            nonce: StdRng::from_os_rng().random(),
 4051            diagnostic_summaries: HashMap::default(),
 4052            lsp_server_capabilities: HashMap::default(),
 4053            lsp_data: HashMap::default(),
 4054            next_hint_id: Arc::default(),
 4055            active_entry: None,
 4056            _maintain_workspace_config,
 4057            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4058        }
 4059    }
 4060
 4061    fn send_lsp_proto_request<R: LspCommand>(
 4062        &self,
 4063        buffer: Entity<Buffer>,
 4064        client: AnyProtoClient,
 4065        upstream_project_id: u64,
 4066        request: R,
 4067        cx: &mut Context<LspStore>,
 4068    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4069        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4070            return Task::ready(Ok(R::Response::default()));
 4071        }
 4072        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4073        cx.spawn(async move |this, cx| {
 4074            let response = client.request(message).await?;
 4075            let this = this.upgrade().context("project dropped")?;
 4076            request
 4077                .response_from_proto(response, this, buffer, cx.clone())
 4078                .await
 4079        })
 4080    }
 4081
 4082    pub(super) fn new_remote(
 4083        buffer_store: Entity<BufferStore>,
 4084        worktree_store: Entity<WorktreeStore>,
 4085        languages: Arc<LanguageRegistry>,
 4086        upstream_client: AnyProtoClient,
 4087        project_id: u64,
 4088        cx: &mut Context<Self>,
 4089    ) -> Self {
 4090        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4091            .detach();
 4092        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4093            .detach();
 4094        subscribe_to_binary_statuses(&languages, cx).detach();
 4095        let _maintain_workspace_config = {
 4096            let (sender, receiver) = watch::channel();
 4097            (Self::maintain_workspace_config(receiver, cx), sender)
 4098        };
 4099        Self {
 4100            mode: LspStoreMode::Remote(RemoteLspStore {
 4101                upstream_client: Some(upstream_client),
 4102                upstream_project_id: project_id,
 4103            }),
 4104            downstream_client: None,
 4105            last_formatting_failure: None,
 4106            buffer_store,
 4107            worktree_store,
 4108            languages: languages.clone(),
 4109            language_server_statuses: Default::default(),
 4110            nonce: StdRng::from_os_rng().random(),
 4111            diagnostic_summaries: HashMap::default(),
 4112            lsp_server_capabilities: HashMap::default(),
 4113            next_hint_id: Arc::default(),
 4114            lsp_data: HashMap::default(),
 4115            active_entry: None,
 4116
 4117            _maintain_workspace_config,
 4118            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4119        }
 4120    }
 4121
 4122    fn on_buffer_store_event(
 4123        &mut self,
 4124        _: Entity<BufferStore>,
 4125        event: &BufferStoreEvent,
 4126        cx: &mut Context<Self>,
 4127    ) {
 4128        match event {
 4129            BufferStoreEvent::BufferAdded(buffer) => {
 4130                self.on_buffer_added(buffer, cx).log_err();
 4131            }
 4132            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4133                let buffer_id = buffer.read(cx).remote_id();
 4134                if let Some(local) = self.as_local_mut()
 4135                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4136                {
 4137                    local.reset_buffer(buffer, old_file, cx);
 4138
 4139                    if local.registered_buffers.contains_key(&buffer_id) {
 4140                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4141                    }
 4142                }
 4143
 4144                self.detect_language_for_buffer(buffer, cx);
 4145                if let Some(local) = self.as_local_mut() {
 4146                    local.initialize_buffer(buffer, cx);
 4147                    if local.registered_buffers.contains_key(&buffer_id) {
 4148                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4149                    }
 4150                }
 4151            }
 4152            _ => {}
 4153        }
 4154    }
 4155
 4156    fn on_worktree_store_event(
 4157        &mut self,
 4158        _: Entity<WorktreeStore>,
 4159        event: &WorktreeStoreEvent,
 4160        cx: &mut Context<Self>,
 4161    ) {
 4162        match event {
 4163            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4164                if !worktree.read(cx).is_local() {
 4165                    return;
 4166                }
 4167                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4168                    worktree::Event::UpdatedEntries(changes) => {
 4169                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4170                    }
 4171                    worktree::Event::UpdatedGitRepositories(_)
 4172                    | worktree::Event::DeletedEntry(_) => {}
 4173                })
 4174                .detach()
 4175            }
 4176            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4177            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4178                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4179            }
 4180            WorktreeStoreEvent::WorktreeReleased(..)
 4181            | WorktreeStoreEvent::WorktreeOrderChanged
 4182            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4183            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4184            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4185        }
 4186    }
 4187
 4188    fn on_prettier_store_event(
 4189        &mut self,
 4190        _: Entity<PrettierStore>,
 4191        event: &PrettierStoreEvent,
 4192        cx: &mut Context<Self>,
 4193    ) {
 4194        match event {
 4195            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4196                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4197            }
 4198            PrettierStoreEvent::LanguageServerAdded {
 4199                new_server_id,
 4200                name,
 4201                prettier_server,
 4202            } => {
 4203                self.register_supplementary_language_server(
 4204                    *new_server_id,
 4205                    name.clone(),
 4206                    prettier_server.clone(),
 4207                    cx,
 4208                );
 4209            }
 4210        }
 4211    }
 4212
 4213    fn on_toolchain_store_event(
 4214        &mut self,
 4215        _: Entity<LocalToolchainStore>,
 4216        event: &ToolchainStoreEvent,
 4217        _: &mut Context<Self>,
 4218    ) {
 4219        if let ToolchainStoreEvent::ToolchainActivated = event {
 4220            self.request_workspace_config_refresh()
 4221        }
 4222    }
 4223
 4224    fn request_workspace_config_refresh(&mut self) {
 4225        *self._maintain_workspace_config.1.borrow_mut() = ();
 4226    }
 4227
 4228    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4229        self.as_local().map(|local| local.prettier_store.clone())
 4230    }
 4231
 4232    fn on_buffer_event(
 4233        &mut self,
 4234        buffer: Entity<Buffer>,
 4235        event: &language::BufferEvent,
 4236        cx: &mut Context<Self>,
 4237    ) {
 4238        match event {
 4239            language::BufferEvent::Edited => {
 4240                self.on_buffer_edited(buffer, cx);
 4241            }
 4242
 4243            language::BufferEvent::Saved => {
 4244                self.on_buffer_saved(buffer, cx);
 4245            }
 4246
 4247            _ => {}
 4248        }
 4249    }
 4250
 4251    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4252        buffer
 4253            .read(cx)
 4254            .set_language_registry(self.languages.clone());
 4255
 4256        cx.subscribe(buffer, |this, buffer, event, cx| {
 4257            this.on_buffer_event(buffer, event, cx);
 4258        })
 4259        .detach();
 4260
 4261        self.detect_language_for_buffer(buffer, cx);
 4262        if let Some(local) = self.as_local_mut() {
 4263            local.initialize_buffer(buffer, cx);
 4264        }
 4265
 4266        Ok(())
 4267    }
 4268
 4269    pub(crate) fn register_buffer_with_language_servers(
 4270        &mut self,
 4271        buffer: &Entity<Buffer>,
 4272        only_register_servers: HashSet<LanguageServerSelector>,
 4273        ignore_refcounts: bool,
 4274        cx: &mut Context<Self>,
 4275    ) -> OpenLspBufferHandle {
 4276        let buffer_id = buffer.read(cx).remote_id();
 4277        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4278        if let Some(local) = self.as_local_mut() {
 4279            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4280            if !ignore_refcounts {
 4281                *refcount += 1;
 4282            }
 4283
 4284            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4285            // 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
 4286            // 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
 4287            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4288            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4289                return handle;
 4290            };
 4291            if !file.is_local() {
 4292                return handle;
 4293            }
 4294
 4295            if ignore_refcounts || *refcount == 1 {
 4296                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4297            }
 4298            if !ignore_refcounts {
 4299                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4300                    let refcount = {
 4301                        let local = lsp_store.as_local_mut().unwrap();
 4302                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4303                            debug_panic!("bad refcounting");
 4304                            return;
 4305                        };
 4306
 4307                        *refcount -= 1;
 4308                        *refcount
 4309                    };
 4310                    if refcount == 0 {
 4311                        lsp_store.lsp_data.remove(&buffer_id);
 4312                        let local = lsp_store.as_local_mut().unwrap();
 4313                        local.registered_buffers.remove(&buffer_id);
 4314
 4315                        local.buffers_opened_in_servers.remove(&buffer_id);
 4316                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4317                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4318
 4319                            let buffer_abs_path = file.abs_path(cx);
 4320                            for (_, buffer_pull_diagnostics_result_ids) in
 4321                                &mut local.buffer_pull_diagnostics_result_ids
 4322                            {
 4323                                buffer_pull_diagnostics_result_ids.retain(
 4324                                    |_, buffer_result_ids| {
 4325                                        buffer_result_ids.remove(&buffer_abs_path);
 4326                                        !buffer_result_ids.is_empty()
 4327                                    },
 4328                                );
 4329                            }
 4330
 4331                            let diagnostic_updates = local
 4332                                .language_servers
 4333                                .keys()
 4334                                .cloned()
 4335                                .map(|server_id| DocumentDiagnosticsUpdate {
 4336                                    diagnostics: DocumentDiagnostics {
 4337                                        document_abs_path: buffer_abs_path.clone(),
 4338                                        version: None,
 4339                                        diagnostics: Vec::new(),
 4340                                    },
 4341                                    result_id: None,
 4342                                    registration_id: None,
 4343                                    server_id: server_id,
 4344                                    disk_based_sources: Cow::Borrowed(&[]),
 4345                                })
 4346                                .collect::<Vec<_>>();
 4347
 4348                            lsp_store
 4349                                .merge_diagnostic_entries(
 4350                                    diagnostic_updates,
 4351                                    |_, diagnostic, _| {
 4352                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4353                                    },
 4354                                    cx,
 4355                                )
 4356                                .context("Clearing diagnostics for the closed buffer")
 4357                                .log_err();
 4358                        }
 4359                    }
 4360                })
 4361                .detach();
 4362            }
 4363        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4364            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4365            cx.background_spawn(async move {
 4366                upstream_client
 4367                    .request(proto::RegisterBufferWithLanguageServers {
 4368                        project_id: upstream_project_id,
 4369                        buffer_id,
 4370                        only_servers: only_register_servers
 4371                            .into_iter()
 4372                            .map(|selector| {
 4373                                let selector = match selector {
 4374                                    LanguageServerSelector::Id(language_server_id) => {
 4375                                        proto::language_server_selector::Selector::ServerId(
 4376                                            language_server_id.to_proto(),
 4377                                        )
 4378                                    }
 4379                                    LanguageServerSelector::Name(language_server_name) => {
 4380                                        proto::language_server_selector::Selector::Name(
 4381                                            language_server_name.to_string(),
 4382                                        )
 4383                                    }
 4384                                };
 4385                                proto::LanguageServerSelector {
 4386                                    selector: Some(selector),
 4387                                }
 4388                            })
 4389                            .collect(),
 4390                    })
 4391                    .await
 4392            })
 4393            .detach();
 4394        } else {
 4395            // Our remote connection got closed
 4396        }
 4397        handle
 4398    }
 4399
 4400    fn maintain_buffer_languages(
 4401        languages: Arc<LanguageRegistry>,
 4402        cx: &mut Context<Self>,
 4403    ) -> Task<()> {
 4404        let mut subscription = languages.subscribe();
 4405        let mut prev_reload_count = languages.reload_count();
 4406        cx.spawn(async move |this, cx| {
 4407            while let Some(()) = subscription.next().await {
 4408                if let Some(this) = this.upgrade() {
 4409                    // If the language registry has been reloaded, then remove and
 4410                    // re-assign the languages on all open buffers.
 4411                    let reload_count = languages.reload_count();
 4412                    if reload_count > prev_reload_count {
 4413                        prev_reload_count = reload_count;
 4414                        this.update(cx, |this, cx| {
 4415                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4416                                for buffer in buffer_store.buffers() {
 4417                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4418                                    {
 4419                                        buffer.update(cx, |buffer, cx| {
 4420                                            buffer.set_language_async(None, cx)
 4421                                        });
 4422                                        if let Some(local) = this.as_local_mut() {
 4423                                            local.reset_buffer(&buffer, &f, cx);
 4424
 4425                                            if local
 4426                                                .registered_buffers
 4427                                                .contains_key(&buffer.read(cx).remote_id())
 4428                                                && let Some(file_url) =
 4429                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4430                                            {
 4431                                                local.unregister_buffer_from_language_servers(
 4432                                                    &buffer, &file_url, cx,
 4433                                                );
 4434                                            }
 4435                                        }
 4436                                    }
 4437                                }
 4438                            });
 4439                        })
 4440                        .ok();
 4441                    }
 4442
 4443                    this.update(cx, |this, cx| {
 4444                        let mut plain_text_buffers = Vec::new();
 4445                        let mut buffers_with_unknown_injections = Vec::new();
 4446                        for handle in this.buffer_store.read(cx).buffers() {
 4447                            let buffer = handle.read(cx);
 4448                            if buffer.language().is_none()
 4449                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4450                            {
 4451                                plain_text_buffers.push(handle);
 4452                            } else if buffer.contains_unknown_injections() {
 4453                                buffers_with_unknown_injections.push(handle);
 4454                            }
 4455                        }
 4456
 4457                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4458                        // and reused later in the invisible worktrees.
 4459                        plain_text_buffers.sort_by_key(|buffer| {
 4460                            Reverse(
 4461                                File::from_dyn(buffer.read(cx).file())
 4462                                    .map(|file| file.worktree.read(cx).is_visible()),
 4463                            )
 4464                        });
 4465
 4466                        for buffer in plain_text_buffers {
 4467                            this.detect_language_for_buffer(&buffer, cx);
 4468                            if let Some(local) = this.as_local_mut() {
 4469                                local.initialize_buffer(&buffer, cx);
 4470                                if local
 4471                                    .registered_buffers
 4472                                    .contains_key(&buffer.read(cx).remote_id())
 4473                                {
 4474                                    local.register_buffer_with_language_servers(
 4475                                        &buffer,
 4476                                        HashSet::default(),
 4477                                        cx,
 4478                                    );
 4479                                }
 4480                            }
 4481                        }
 4482
 4483                        for buffer in buffers_with_unknown_injections {
 4484                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4485                        }
 4486                    })
 4487                    .ok();
 4488                }
 4489            }
 4490        })
 4491    }
 4492
 4493    fn detect_language_for_buffer(
 4494        &mut self,
 4495        buffer_handle: &Entity<Buffer>,
 4496        cx: &mut Context<Self>,
 4497    ) -> Option<language::AvailableLanguage> {
 4498        // If the buffer has a language, set it and start the language server if we haven't already.
 4499        let buffer = buffer_handle.read(cx);
 4500        let file = buffer.file()?;
 4501
 4502        let content = buffer.as_rope();
 4503        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4504        if let Some(available_language) = &available_language {
 4505            if let Some(Ok(Ok(new_language))) = self
 4506                .languages
 4507                .load_language(available_language)
 4508                .now_or_never()
 4509            {
 4510                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4511            }
 4512        } else {
 4513            cx.emit(LspStoreEvent::LanguageDetected {
 4514                buffer: buffer_handle.clone(),
 4515                new_language: None,
 4516            });
 4517        }
 4518
 4519        available_language
 4520    }
 4521
 4522    pub(crate) fn set_language_for_buffer(
 4523        &mut self,
 4524        buffer_entity: &Entity<Buffer>,
 4525        new_language: Arc<Language>,
 4526        cx: &mut Context<Self>,
 4527    ) {
 4528        let buffer = buffer_entity.read(cx);
 4529        let buffer_file = buffer.file().cloned();
 4530        let buffer_id = buffer.remote_id();
 4531        if let Some(local_store) = self.as_local_mut()
 4532            && local_store.registered_buffers.contains_key(&buffer_id)
 4533            && let Some(abs_path) =
 4534                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4535            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4536        {
 4537            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4538        }
 4539        buffer_entity.update(cx, |buffer, cx| {
 4540            if buffer
 4541                .language()
 4542                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4543            {
 4544                buffer.set_language_async(Some(new_language.clone()), cx);
 4545            }
 4546        });
 4547
 4548        let settings =
 4549            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4550        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4551
 4552        let worktree_id = if let Some(file) = buffer_file {
 4553            let worktree = file.worktree.clone();
 4554
 4555            if let Some(local) = self.as_local_mut()
 4556                && local.registered_buffers.contains_key(&buffer_id)
 4557            {
 4558                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4559            }
 4560            Some(worktree.read(cx).id())
 4561        } else {
 4562            None
 4563        };
 4564
 4565        if settings.prettier.allowed
 4566            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4567        {
 4568            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4569            if let Some(prettier_store) = prettier_store {
 4570                prettier_store.update(cx, |prettier_store, cx| {
 4571                    prettier_store.install_default_prettier(
 4572                        worktree_id,
 4573                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4574                        cx,
 4575                    )
 4576                })
 4577            }
 4578        }
 4579
 4580        cx.emit(LspStoreEvent::LanguageDetected {
 4581            buffer: buffer_entity.clone(),
 4582            new_language: Some(new_language),
 4583        })
 4584    }
 4585
 4586    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4587        self.buffer_store.clone()
 4588    }
 4589
 4590    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4591        self.active_entry = active_entry;
 4592    }
 4593
 4594    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4595        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4596            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4597        {
 4598            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4599                summaries
 4600                    .iter()
 4601                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4602            });
 4603            if let Some(summary) = summaries.next() {
 4604                client
 4605                    .send(proto::UpdateDiagnosticSummary {
 4606                        project_id: downstream_project_id,
 4607                        worktree_id: worktree.id().to_proto(),
 4608                        summary: Some(summary),
 4609                        more_summaries: summaries.collect(),
 4610                    })
 4611                    .log_err();
 4612            }
 4613        }
 4614    }
 4615
 4616    fn is_capable_for_proto_request<R>(
 4617        &self,
 4618        buffer: &Entity<Buffer>,
 4619        request: &R,
 4620        cx: &App,
 4621    ) -> bool
 4622    where
 4623        R: LspCommand,
 4624    {
 4625        self.check_if_capable_for_proto_request(
 4626            buffer,
 4627            |capabilities| {
 4628                request.check_capabilities(AdapterServerCapabilities {
 4629                    server_capabilities: capabilities.clone(),
 4630                    code_action_kinds: None,
 4631                })
 4632            },
 4633            cx,
 4634        )
 4635    }
 4636
 4637    fn check_if_capable_for_proto_request<F>(
 4638        &self,
 4639        buffer: &Entity<Buffer>,
 4640        check: F,
 4641        cx: &App,
 4642    ) -> bool
 4643    where
 4644        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4645    {
 4646        let Some(language) = buffer.read(cx).language().cloned() else {
 4647            return false;
 4648        };
 4649        let relevant_language_servers = self
 4650            .languages
 4651            .lsp_adapters(&language.name())
 4652            .into_iter()
 4653            .map(|lsp_adapter| lsp_adapter.name())
 4654            .collect::<HashSet<_>>();
 4655        self.language_server_statuses
 4656            .iter()
 4657            .filter_map(|(server_id, server_status)| {
 4658                relevant_language_servers
 4659                    .contains(&server_status.name)
 4660                    .then_some(server_id)
 4661            })
 4662            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4663            .any(check)
 4664    }
 4665
 4666    fn all_capable_for_proto_request<F>(
 4667        &self,
 4668        buffer: &Entity<Buffer>,
 4669        mut check: F,
 4670        cx: &App,
 4671    ) -> Vec<lsp::LanguageServerId>
 4672    where
 4673        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4674    {
 4675        let Some(language) = buffer.read(cx).language().cloned() else {
 4676            return Vec::default();
 4677        };
 4678        let relevant_language_servers = self
 4679            .languages
 4680            .lsp_adapters(&language.name())
 4681            .into_iter()
 4682            .map(|lsp_adapter| lsp_adapter.name())
 4683            .collect::<HashSet<_>>();
 4684        self.language_server_statuses
 4685            .iter()
 4686            .filter_map(|(server_id, server_status)| {
 4687                relevant_language_servers
 4688                    .contains(&server_status.name)
 4689                    .then_some((server_id, &server_status.name))
 4690            })
 4691            .filter_map(|(server_id, server_name)| {
 4692                self.lsp_server_capabilities
 4693                    .get(server_id)
 4694                    .map(|c| (server_id, server_name, c))
 4695            })
 4696            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4697            .map(|(server_id, _, _)| *server_id)
 4698            .collect()
 4699    }
 4700
 4701    pub fn request_lsp<R>(
 4702        &mut self,
 4703        buffer: Entity<Buffer>,
 4704        server: LanguageServerToQuery,
 4705        request: R,
 4706        cx: &mut Context<Self>,
 4707    ) -> Task<Result<R::Response>>
 4708    where
 4709        R: LspCommand,
 4710        <R::LspRequest as lsp::request::Request>::Result: Send,
 4711        <R::LspRequest as lsp::request::Request>::Params: Send,
 4712    {
 4713        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4714            return self.send_lsp_proto_request(
 4715                buffer,
 4716                upstream_client,
 4717                upstream_project_id,
 4718                request,
 4719                cx,
 4720            );
 4721        }
 4722
 4723        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4724            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4725                local
 4726                    .language_servers_for_buffer(buffer, cx)
 4727                    .find(|(_, server)| {
 4728                        request.check_capabilities(server.adapter_server_capabilities())
 4729                    })
 4730                    .map(|(_, server)| server.clone())
 4731            }),
 4732            LanguageServerToQuery::Other(id) => self
 4733                .language_server_for_local_buffer(buffer, id, cx)
 4734                .and_then(|(_, server)| {
 4735                    request
 4736                        .check_capabilities(server.adapter_server_capabilities())
 4737                        .then(|| Arc::clone(server))
 4738                }),
 4739        }) else {
 4740            return Task::ready(Ok(Default::default()));
 4741        };
 4742
 4743        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4744
 4745        let Some(file) = file else {
 4746            return Task::ready(Ok(Default::default()));
 4747        };
 4748
 4749        let lsp_params = match request.to_lsp_params_or_response(
 4750            &file.abs_path(cx),
 4751            buffer.read(cx),
 4752            &language_server,
 4753            cx,
 4754        ) {
 4755            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4756            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4757            Err(err) => {
 4758                let message = format!(
 4759                    "{} via {} failed: {}",
 4760                    request.display_name(),
 4761                    language_server.name(),
 4762                    err
 4763                );
 4764                // rust-analyzer likes to error with this when its still loading up
 4765                if !message.ends_with("content modified") {
 4766                    log::warn!("{message}");
 4767                }
 4768                return Task::ready(Err(anyhow!(message)));
 4769            }
 4770        };
 4771
 4772        let status = request.status();
 4773        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4774            return Task::ready(Ok(Default::default()));
 4775        }
 4776        cx.spawn(async move |this, cx| {
 4777            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4778
 4779            let id = lsp_request.id();
 4780            let _cleanup = if status.is_some() {
 4781                cx.update(|cx| {
 4782                    this.update(cx, |this, cx| {
 4783                        this.on_lsp_work_start(
 4784                            language_server.server_id(),
 4785                            ProgressToken::Number(id),
 4786                            LanguageServerProgress {
 4787                                is_disk_based_diagnostics_progress: false,
 4788                                is_cancellable: false,
 4789                                title: None,
 4790                                message: status.clone(),
 4791                                percentage: None,
 4792                                last_update_at: cx.background_executor().now(),
 4793                            },
 4794                            cx,
 4795                        );
 4796                    })
 4797                })
 4798                .log_err();
 4799
 4800                Some(defer(|| {
 4801                    cx.update(|cx| {
 4802                        this.update(cx, |this, cx| {
 4803                            this.on_lsp_work_end(
 4804                                language_server.server_id(),
 4805                                ProgressToken::Number(id),
 4806                                cx,
 4807                            );
 4808                        })
 4809                    })
 4810                    .log_err();
 4811                }))
 4812            } else {
 4813                None
 4814            };
 4815
 4816            let result = lsp_request.await.into_response();
 4817
 4818            let response = result.map_err(|err| {
 4819                let message = format!(
 4820                    "{} via {} failed: {}",
 4821                    request.display_name(),
 4822                    language_server.name(),
 4823                    err
 4824                );
 4825                // rust-analyzer likes to error with this when its still loading up
 4826                if !message.ends_with("content modified") {
 4827                    log::warn!("{message}");
 4828                }
 4829                anyhow::anyhow!(message)
 4830            })?;
 4831
 4832            request
 4833                .response_from_lsp(
 4834                    response,
 4835                    this.upgrade().context("no app context")?,
 4836                    buffer,
 4837                    language_server.server_id(),
 4838                    cx.clone(),
 4839                )
 4840                .await
 4841        })
 4842    }
 4843
 4844    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4845        let mut language_formatters_to_check = Vec::new();
 4846        for buffer in self.buffer_store.read(cx).buffers() {
 4847            let buffer = buffer.read(cx);
 4848            let buffer_file = File::from_dyn(buffer.file());
 4849            let buffer_language = buffer.language();
 4850            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4851            if buffer_language.is_some() {
 4852                language_formatters_to_check.push((
 4853                    buffer_file.map(|f| f.worktree_id(cx)),
 4854                    settings.into_owned(),
 4855                ));
 4856            }
 4857        }
 4858
 4859        self.request_workspace_config_refresh();
 4860
 4861        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4862            prettier_store.update(cx, |prettier_store, cx| {
 4863                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4864            })
 4865        }
 4866
 4867        cx.notify();
 4868    }
 4869
 4870    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4871        let buffer_store = self.buffer_store.clone();
 4872        let Some(local) = self.as_local_mut() else {
 4873            return;
 4874        };
 4875        let mut adapters = BTreeMap::default();
 4876        let get_adapter = {
 4877            let languages = local.languages.clone();
 4878            let environment = local.environment.clone();
 4879            let weak = local.weak.clone();
 4880            let worktree_store = local.worktree_store.clone();
 4881            let http_client = local.http_client.clone();
 4882            let fs = local.fs.clone();
 4883            move |worktree_id, cx: &mut App| {
 4884                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4885                Some(LocalLspAdapterDelegate::new(
 4886                    languages.clone(),
 4887                    &environment,
 4888                    weak.clone(),
 4889                    &worktree,
 4890                    http_client.clone(),
 4891                    fs.clone(),
 4892                    cx,
 4893                ))
 4894            }
 4895        };
 4896
 4897        let mut messages_to_report = Vec::new();
 4898        let (new_tree, to_stop) = {
 4899            let mut rebase = local.lsp_tree.rebase();
 4900            let buffers = buffer_store
 4901                .read(cx)
 4902                .buffers()
 4903                .filter_map(|buffer| {
 4904                    let raw_buffer = buffer.read(cx);
 4905                    if !local
 4906                        .registered_buffers
 4907                        .contains_key(&raw_buffer.remote_id())
 4908                    {
 4909                        return None;
 4910                    }
 4911                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4912                    let language = raw_buffer.language().cloned()?;
 4913                    Some((file, language, raw_buffer.remote_id()))
 4914                })
 4915                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4916            for (file, language, buffer_id) in buffers {
 4917                let worktree_id = file.worktree_id(cx);
 4918                let Some(worktree) = local
 4919                    .worktree_store
 4920                    .read(cx)
 4921                    .worktree_for_id(worktree_id, cx)
 4922                else {
 4923                    continue;
 4924                };
 4925
 4926                if let Some((_, apply)) = local.reuse_existing_language_server(
 4927                    rebase.server_tree(),
 4928                    &worktree,
 4929                    &language.name(),
 4930                    cx,
 4931                ) {
 4932                    (apply)(rebase.server_tree());
 4933                } else if let Some(lsp_delegate) = adapters
 4934                    .entry(worktree_id)
 4935                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4936                    .clone()
 4937                {
 4938                    let delegate =
 4939                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4940                    let path = file
 4941                        .path()
 4942                        .parent()
 4943                        .map(Arc::from)
 4944                        .unwrap_or_else(|| file.path().clone());
 4945                    let worktree_path = ProjectPath { worktree_id, path };
 4946                    let abs_path = file.abs_path(cx);
 4947                    let nodes = rebase
 4948                        .walk(
 4949                            worktree_path,
 4950                            language.name(),
 4951                            language.manifest(),
 4952                            delegate.clone(),
 4953                            cx,
 4954                        )
 4955                        .collect::<Vec<_>>();
 4956                    for node in nodes {
 4957                        let server_id = node.server_id_or_init(|disposition| {
 4958                            let path = &disposition.path;
 4959                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4960                            let key = LanguageServerSeed {
 4961                                worktree_id,
 4962                                name: disposition.server_name.clone(),
 4963                                settings: disposition.settings.clone(),
 4964                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4965                                    path.worktree_id,
 4966                                    &path.path,
 4967                                    language.name(),
 4968                                ),
 4969                            };
 4970                            local.language_server_ids.remove(&key);
 4971
 4972                            let server_id = local.get_or_insert_language_server(
 4973                                &worktree,
 4974                                lsp_delegate.clone(),
 4975                                disposition,
 4976                                &language.name(),
 4977                                cx,
 4978                            );
 4979                            if let Some(state) = local.language_servers.get(&server_id)
 4980                                && let Ok(uri) = uri
 4981                            {
 4982                                state.add_workspace_folder(uri);
 4983                            };
 4984                            server_id
 4985                        });
 4986
 4987                        if let Some(language_server_id) = server_id {
 4988                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4989                                language_server_id,
 4990                                name: node.name(),
 4991                                message:
 4992                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4993                                        proto::RegisteredForBuffer {
 4994                                            buffer_abs_path: abs_path
 4995                                                .to_string_lossy()
 4996                                                .into_owned(),
 4997                                            buffer_id: buffer_id.to_proto(),
 4998                                        },
 4999                                    ),
 5000                            });
 5001                        }
 5002                    }
 5003                } else {
 5004                    continue;
 5005                }
 5006            }
 5007            rebase.finish()
 5008        };
 5009        for message in messages_to_report {
 5010            cx.emit(message);
 5011        }
 5012        local.lsp_tree = new_tree;
 5013        for (id, _) in to_stop {
 5014            self.stop_local_language_server(id, cx).detach();
 5015        }
 5016    }
 5017
 5018    pub fn apply_code_action(
 5019        &self,
 5020        buffer_handle: Entity<Buffer>,
 5021        mut action: CodeAction,
 5022        push_to_history: bool,
 5023        cx: &mut Context<Self>,
 5024    ) -> Task<Result<ProjectTransaction>> {
 5025        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5026            let request = proto::ApplyCodeAction {
 5027                project_id,
 5028                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5029                action: Some(Self::serialize_code_action(&action)),
 5030            };
 5031            let buffer_store = self.buffer_store();
 5032            cx.spawn(async move |_, cx| {
 5033                let response = upstream_client
 5034                    .request(request)
 5035                    .await?
 5036                    .transaction
 5037                    .context("missing transaction")?;
 5038
 5039                buffer_store
 5040                    .update(cx, |buffer_store, cx| {
 5041                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5042                    })?
 5043                    .await
 5044            })
 5045        } else if self.mode.is_local() {
 5046            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 5047                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5048                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 5049            }) else {
 5050                return Task::ready(Ok(ProjectTransaction::default()));
 5051            };
 5052            cx.spawn(async move |this,  cx| {
 5053                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 5054                    .await
 5055                    .context("resolving a code action")?;
 5056                if let Some(edit) = action.lsp_action.edit()
 5057                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5058                        return LocalLspStore::deserialize_workspace_edit(
 5059                            this.upgrade().context("no app present")?,
 5060                            edit.clone(),
 5061                            push_to_history,
 5062
 5063                            lang_server.clone(),
 5064                            cx,
 5065                        )
 5066                        .await;
 5067                    }
 5068
 5069                if let Some(command) = action.lsp_action.command() {
 5070                    let server_capabilities = lang_server.capabilities();
 5071                    let available_commands = server_capabilities
 5072                        .execute_command_provider
 5073                        .as_ref()
 5074                        .map(|options| options.commands.as_slice())
 5075                        .unwrap_or_default();
 5076                    if available_commands.contains(&command.command) {
 5077                        this.update(cx, |this, _| {
 5078                            this.as_local_mut()
 5079                                .unwrap()
 5080                                .last_workspace_edits_by_language_server
 5081                                .remove(&lang_server.server_id());
 5082                        })?;
 5083
 5084                        let _result = lang_server
 5085                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5086                                command: command.command.clone(),
 5087                                arguments: command.arguments.clone().unwrap_or_default(),
 5088                                ..lsp::ExecuteCommandParams::default()
 5089                            })
 5090                            .await.into_response()
 5091                            .context("execute command")?;
 5092
 5093                        return this.update(cx, |this, _| {
 5094                            this.as_local_mut()
 5095                                .unwrap()
 5096                                .last_workspace_edits_by_language_server
 5097                                .remove(&lang_server.server_id())
 5098                                .unwrap_or_default()
 5099                        });
 5100                    } else {
 5101                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5102                    }
 5103                }
 5104
 5105                Ok(ProjectTransaction::default())
 5106            })
 5107        } else {
 5108            Task::ready(Err(anyhow!("no upstream client and not local")))
 5109        }
 5110    }
 5111
 5112    pub fn apply_code_action_kind(
 5113        &mut self,
 5114        buffers: HashSet<Entity<Buffer>>,
 5115        kind: CodeActionKind,
 5116        push_to_history: bool,
 5117        cx: &mut Context<Self>,
 5118    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5119        if self.as_local().is_some() {
 5120            cx.spawn(async move |lsp_store, cx| {
 5121                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5122                let result = LocalLspStore::execute_code_action_kind_locally(
 5123                    lsp_store.clone(),
 5124                    buffers,
 5125                    kind,
 5126                    push_to_history,
 5127                    cx,
 5128                )
 5129                .await;
 5130                lsp_store.update(cx, |lsp_store, _| {
 5131                    lsp_store.update_last_formatting_failure(&result);
 5132                })?;
 5133                result
 5134            })
 5135        } else if let Some((client, project_id)) = self.upstream_client() {
 5136            let buffer_store = self.buffer_store();
 5137            cx.spawn(async move |lsp_store, cx| {
 5138                let result = client
 5139                    .request(proto::ApplyCodeActionKind {
 5140                        project_id,
 5141                        kind: kind.as_str().to_owned(),
 5142                        buffer_ids: buffers
 5143                            .iter()
 5144                            .map(|buffer| {
 5145                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5146                            })
 5147                            .collect::<Result<_>>()?,
 5148                    })
 5149                    .await
 5150                    .and_then(|result| result.transaction.context("missing transaction"));
 5151                lsp_store.update(cx, |lsp_store, _| {
 5152                    lsp_store.update_last_formatting_failure(&result);
 5153                })?;
 5154
 5155                let transaction_response = result?;
 5156                buffer_store
 5157                    .update(cx, |buffer_store, cx| {
 5158                        buffer_store.deserialize_project_transaction(
 5159                            transaction_response,
 5160                            push_to_history,
 5161                            cx,
 5162                        )
 5163                    })?
 5164                    .await
 5165            })
 5166        } else {
 5167            Task::ready(Ok(ProjectTransaction::default()))
 5168        }
 5169    }
 5170
 5171    pub fn resolved_hint(
 5172        &mut self,
 5173        buffer_id: BufferId,
 5174        id: InlayId,
 5175        cx: &mut Context<Self>,
 5176    ) -> Option<ResolvedHint> {
 5177        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5178
 5179        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5180        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5181        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5182        let (server_id, resolve_data) = match &hint.resolve_state {
 5183            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5184            ResolveState::Resolving => {
 5185                return Some(ResolvedHint::Resolving(
 5186                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5187                ));
 5188            }
 5189            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5190        };
 5191
 5192        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5193        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5194        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5195            id,
 5196            cx.spawn(async move |lsp_store, cx| {
 5197                let resolved_hint = resolve_task.await;
 5198                lsp_store
 5199                    .update(cx, |lsp_store, _| {
 5200                        if let Some(old_inlay_hint) = lsp_store
 5201                            .lsp_data
 5202                            .get_mut(&buffer_id)
 5203                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5204                        {
 5205                            match resolved_hint {
 5206                                Ok(resolved_hint) => {
 5207                                    *old_inlay_hint = resolved_hint;
 5208                                }
 5209                                Err(e) => {
 5210                                    old_inlay_hint.resolve_state =
 5211                                        ResolveState::CanResolve(server_id, resolve_data);
 5212                                    log::error!("Inlay hint resolve failed: {e:#}");
 5213                                }
 5214                            }
 5215                        }
 5216                    })
 5217                    .ok();
 5218            })
 5219            .shared(),
 5220        );
 5221        debug_assert!(
 5222            previous_task.is_none(),
 5223            "Did not change hint's resolve state after spawning its resolve"
 5224        );
 5225        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5226        None
 5227    }
 5228
 5229    fn resolve_inlay_hint(
 5230        &self,
 5231        mut hint: InlayHint,
 5232        buffer: Entity<Buffer>,
 5233        server_id: LanguageServerId,
 5234        cx: &mut Context<Self>,
 5235    ) -> Task<anyhow::Result<InlayHint>> {
 5236        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5237            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5238            {
 5239                hint.resolve_state = ResolveState::Resolved;
 5240                return Task::ready(Ok(hint));
 5241            }
 5242            let request = proto::ResolveInlayHint {
 5243                project_id,
 5244                buffer_id: buffer.read(cx).remote_id().into(),
 5245                language_server_id: server_id.0 as u64,
 5246                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5247            };
 5248            cx.background_spawn(async move {
 5249                let response = upstream_client
 5250                    .request(request)
 5251                    .await
 5252                    .context("inlay hints proto request")?;
 5253                match response.hint {
 5254                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5255                        .context("inlay hints proto resolve response conversion"),
 5256                    None => Ok(hint),
 5257                }
 5258            })
 5259        } else {
 5260            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5261                self.language_server_for_local_buffer(buffer, server_id, cx)
 5262                    .map(|(_, server)| server.clone())
 5263            }) else {
 5264                return Task::ready(Ok(hint));
 5265            };
 5266            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5267                return Task::ready(Ok(hint));
 5268            }
 5269            let buffer_snapshot = buffer.read(cx).snapshot();
 5270            cx.spawn(async move |_, cx| {
 5271                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5272                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5273                );
 5274                let resolved_hint = resolve_task
 5275                    .await
 5276                    .into_response()
 5277                    .context("inlay hint resolve LSP request")?;
 5278                let resolved_hint = InlayHints::lsp_to_project_hint(
 5279                    resolved_hint,
 5280                    &buffer,
 5281                    server_id,
 5282                    ResolveState::Resolved,
 5283                    false,
 5284                    cx,
 5285                )
 5286                .await?;
 5287                Ok(resolved_hint)
 5288            })
 5289        }
 5290    }
 5291
 5292    pub fn resolve_color_presentation(
 5293        &mut self,
 5294        mut color: DocumentColor,
 5295        buffer: Entity<Buffer>,
 5296        server_id: LanguageServerId,
 5297        cx: &mut Context<Self>,
 5298    ) -> Task<Result<DocumentColor>> {
 5299        if color.resolved {
 5300            return Task::ready(Ok(color));
 5301        }
 5302
 5303        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5304            let start = color.lsp_range.start;
 5305            let end = color.lsp_range.end;
 5306            let request = proto::GetColorPresentation {
 5307                project_id,
 5308                server_id: server_id.to_proto(),
 5309                buffer_id: buffer.read(cx).remote_id().into(),
 5310                color: Some(proto::ColorInformation {
 5311                    red: color.color.red,
 5312                    green: color.color.green,
 5313                    blue: color.color.blue,
 5314                    alpha: color.color.alpha,
 5315                    lsp_range_start: Some(proto::PointUtf16 {
 5316                        row: start.line,
 5317                        column: start.character,
 5318                    }),
 5319                    lsp_range_end: Some(proto::PointUtf16 {
 5320                        row: end.line,
 5321                        column: end.character,
 5322                    }),
 5323                }),
 5324            };
 5325            cx.background_spawn(async move {
 5326                let response = upstream_client
 5327                    .request(request)
 5328                    .await
 5329                    .context("color presentation proto request")?;
 5330                color.resolved = true;
 5331                color.color_presentations = response
 5332                    .presentations
 5333                    .into_iter()
 5334                    .map(|presentation| ColorPresentation {
 5335                        label: SharedString::from(presentation.label),
 5336                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5337                        additional_text_edits: presentation
 5338                            .additional_text_edits
 5339                            .into_iter()
 5340                            .filter_map(deserialize_lsp_edit)
 5341                            .collect(),
 5342                    })
 5343                    .collect();
 5344                Ok(color)
 5345            })
 5346        } else {
 5347            let path = match buffer
 5348                .update(cx, |buffer, cx| {
 5349                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5350                })
 5351                .context("buffer with the missing path")
 5352            {
 5353                Ok(path) => path,
 5354                Err(e) => return Task::ready(Err(e)),
 5355            };
 5356            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5357                self.language_server_for_local_buffer(buffer, server_id, cx)
 5358                    .map(|(_, server)| server.clone())
 5359            }) else {
 5360                return Task::ready(Ok(color));
 5361            };
 5362            cx.background_spawn(async move {
 5363                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5364                    lsp::ColorPresentationParams {
 5365                        text_document: make_text_document_identifier(&path)?,
 5366                        color: color.color,
 5367                        range: color.lsp_range,
 5368                        work_done_progress_params: Default::default(),
 5369                        partial_result_params: Default::default(),
 5370                    },
 5371                );
 5372                color.color_presentations = resolve_task
 5373                    .await
 5374                    .into_response()
 5375                    .context("color presentation resolve LSP request")?
 5376                    .into_iter()
 5377                    .map(|presentation| ColorPresentation {
 5378                        label: SharedString::from(presentation.label),
 5379                        text_edit: presentation.text_edit,
 5380                        additional_text_edits: presentation
 5381                            .additional_text_edits
 5382                            .unwrap_or_default(),
 5383                    })
 5384                    .collect();
 5385                color.resolved = true;
 5386                Ok(color)
 5387            })
 5388        }
 5389    }
 5390
 5391    pub(crate) fn linked_edits(
 5392        &mut self,
 5393        buffer: &Entity<Buffer>,
 5394        position: Anchor,
 5395        cx: &mut Context<Self>,
 5396    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5397        let snapshot = buffer.read(cx).snapshot();
 5398        let scope = snapshot.language_scope_at(position);
 5399        let Some(server_id) = self
 5400            .as_local()
 5401            .and_then(|local| {
 5402                buffer.update(cx, |buffer, cx| {
 5403                    local
 5404                        .language_servers_for_buffer(buffer, cx)
 5405                        .filter(|(_, server)| {
 5406                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5407                        })
 5408                        .filter(|(adapter, _)| {
 5409                            scope
 5410                                .as_ref()
 5411                                .map(|scope| scope.language_allowed(&adapter.name))
 5412                                .unwrap_or(true)
 5413                        })
 5414                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5415                        .next()
 5416                })
 5417            })
 5418            .or_else(|| {
 5419                self.upstream_client()
 5420                    .is_some()
 5421                    .then_some(LanguageServerToQuery::FirstCapable)
 5422            })
 5423            .filter(|_| {
 5424                maybe!({
 5425                    let language = buffer.read(cx).language_at(position)?;
 5426                    Some(
 5427                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5428                            .linked_edits,
 5429                    )
 5430                }) == Some(true)
 5431            })
 5432        else {
 5433            return Task::ready(Ok(Vec::new()));
 5434        };
 5435
 5436        self.request_lsp(
 5437            buffer.clone(),
 5438            server_id,
 5439            LinkedEditingRange { position },
 5440            cx,
 5441        )
 5442    }
 5443
 5444    fn apply_on_type_formatting(
 5445        &mut self,
 5446        buffer: Entity<Buffer>,
 5447        position: Anchor,
 5448        trigger: String,
 5449        cx: &mut Context<Self>,
 5450    ) -> Task<Result<Option<Transaction>>> {
 5451        if let Some((client, project_id)) = self.upstream_client() {
 5452            if !self.check_if_capable_for_proto_request(
 5453                &buffer,
 5454                |capabilities| {
 5455                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5456                },
 5457                cx,
 5458            ) {
 5459                return Task::ready(Ok(None));
 5460            }
 5461            let request = proto::OnTypeFormatting {
 5462                project_id,
 5463                buffer_id: buffer.read(cx).remote_id().into(),
 5464                position: Some(serialize_anchor(&position)),
 5465                trigger,
 5466                version: serialize_version(&buffer.read(cx).version()),
 5467            };
 5468            cx.background_spawn(async move {
 5469                client
 5470                    .request(request)
 5471                    .await?
 5472                    .transaction
 5473                    .map(language::proto::deserialize_transaction)
 5474                    .transpose()
 5475            })
 5476        } else if let Some(local) = self.as_local_mut() {
 5477            let buffer_id = buffer.read(cx).remote_id();
 5478            local.buffers_being_formatted.insert(buffer_id);
 5479            cx.spawn(async move |this, cx| {
 5480                let _cleanup = defer({
 5481                    let this = this.clone();
 5482                    let mut cx = cx.clone();
 5483                    move || {
 5484                        this.update(&mut cx, |this, _| {
 5485                            if let Some(local) = this.as_local_mut() {
 5486                                local.buffers_being_formatted.remove(&buffer_id);
 5487                            }
 5488                        })
 5489                        .ok();
 5490                    }
 5491                });
 5492
 5493                buffer
 5494                    .update(cx, |buffer, _| {
 5495                        buffer.wait_for_edits(Some(position.timestamp))
 5496                    })?
 5497                    .await?;
 5498                this.update(cx, |this, cx| {
 5499                    let position = position.to_point_utf16(buffer.read(cx));
 5500                    this.on_type_format(buffer, position, trigger, false, cx)
 5501                })?
 5502                .await
 5503            })
 5504        } else {
 5505            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5506        }
 5507    }
 5508
 5509    pub fn on_type_format<T: ToPointUtf16>(
 5510        &mut self,
 5511        buffer: Entity<Buffer>,
 5512        position: T,
 5513        trigger: String,
 5514        push_to_history: bool,
 5515        cx: &mut Context<Self>,
 5516    ) -> Task<Result<Option<Transaction>>> {
 5517        let position = position.to_point_utf16(buffer.read(cx));
 5518        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5519    }
 5520
 5521    fn on_type_format_impl(
 5522        &mut self,
 5523        buffer: Entity<Buffer>,
 5524        position: PointUtf16,
 5525        trigger: String,
 5526        push_to_history: bool,
 5527        cx: &mut Context<Self>,
 5528    ) -> Task<Result<Option<Transaction>>> {
 5529        let options = buffer.update(cx, |buffer, cx| {
 5530            lsp_command::lsp_formatting_options(
 5531                language_settings(
 5532                    buffer.language_at(position).map(|l| l.name()),
 5533                    buffer.file(),
 5534                    cx,
 5535                )
 5536                .as_ref(),
 5537            )
 5538        });
 5539
 5540        cx.spawn(async move |this, cx| {
 5541            if let Some(waiter) =
 5542                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5543            {
 5544                waiter.await?;
 5545            }
 5546            cx.update(|cx| {
 5547                this.update(cx, |this, cx| {
 5548                    this.request_lsp(
 5549                        buffer.clone(),
 5550                        LanguageServerToQuery::FirstCapable,
 5551                        OnTypeFormatting {
 5552                            position,
 5553                            trigger,
 5554                            options,
 5555                            push_to_history,
 5556                        },
 5557                        cx,
 5558                    )
 5559                })
 5560            })??
 5561            .await
 5562        })
 5563    }
 5564
 5565    pub fn definitions(
 5566        &mut self,
 5567        buffer: &Entity<Buffer>,
 5568        position: PointUtf16,
 5569        cx: &mut Context<Self>,
 5570    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5571        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5572            let request = GetDefinitions { position };
 5573            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5574                return Task::ready(Ok(None));
 5575            }
 5576            let request_task = upstream_client.request_lsp(
 5577                project_id,
 5578                None,
 5579                LSP_REQUEST_TIMEOUT,
 5580                cx.background_executor().clone(),
 5581                request.to_proto(project_id, buffer.read(cx)),
 5582            );
 5583            let buffer = buffer.clone();
 5584            cx.spawn(async move |weak_lsp_store, cx| {
 5585                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5586                    return Ok(None);
 5587                };
 5588                let Some(responses) = request_task.await? else {
 5589                    return Ok(None);
 5590                };
 5591                let actions = join_all(responses.payload.into_iter().map(|response| {
 5592                    GetDefinitions { position }.response_from_proto(
 5593                        response.response,
 5594                        lsp_store.clone(),
 5595                        buffer.clone(),
 5596                        cx.clone(),
 5597                    )
 5598                }))
 5599                .await;
 5600
 5601                Ok(Some(
 5602                    actions
 5603                        .into_iter()
 5604                        .collect::<Result<Vec<Vec<_>>>>()?
 5605                        .into_iter()
 5606                        .flatten()
 5607                        .dedup()
 5608                        .collect(),
 5609                ))
 5610            })
 5611        } else {
 5612            let definitions_task = self.request_multiple_lsp_locally(
 5613                buffer,
 5614                Some(position),
 5615                GetDefinitions { position },
 5616                cx,
 5617            );
 5618            cx.background_spawn(async move {
 5619                Ok(Some(
 5620                    definitions_task
 5621                        .await
 5622                        .into_iter()
 5623                        .flat_map(|(_, definitions)| definitions)
 5624                        .dedup()
 5625                        .collect(),
 5626                ))
 5627            })
 5628        }
 5629    }
 5630
 5631    pub fn declarations(
 5632        &mut self,
 5633        buffer: &Entity<Buffer>,
 5634        position: PointUtf16,
 5635        cx: &mut Context<Self>,
 5636    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5637        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5638            let request = GetDeclarations { position };
 5639            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5640                return Task::ready(Ok(None));
 5641            }
 5642            let request_task = upstream_client.request_lsp(
 5643                project_id,
 5644                None,
 5645                LSP_REQUEST_TIMEOUT,
 5646                cx.background_executor().clone(),
 5647                request.to_proto(project_id, buffer.read(cx)),
 5648            );
 5649            let buffer = buffer.clone();
 5650            cx.spawn(async move |weak_lsp_store, cx| {
 5651                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5652                    return Ok(None);
 5653                };
 5654                let Some(responses) = request_task.await? else {
 5655                    return Ok(None);
 5656                };
 5657                let actions = join_all(responses.payload.into_iter().map(|response| {
 5658                    GetDeclarations { position }.response_from_proto(
 5659                        response.response,
 5660                        lsp_store.clone(),
 5661                        buffer.clone(),
 5662                        cx.clone(),
 5663                    )
 5664                }))
 5665                .await;
 5666
 5667                Ok(Some(
 5668                    actions
 5669                        .into_iter()
 5670                        .collect::<Result<Vec<Vec<_>>>>()?
 5671                        .into_iter()
 5672                        .flatten()
 5673                        .dedup()
 5674                        .collect(),
 5675                ))
 5676            })
 5677        } else {
 5678            let declarations_task = self.request_multiple_lsp_locally(
 5679                buffer,
 5680                Some(position),
 5681                GetDeclarations { position },
 5682                cx,
 5683            );
 5684            cx.background_spawn(async move {
 5685                Ok(Some(
 5686                    declarations_task
 5687                        .await
 5688                        .into_iter()
 5689                        .flat_map(|(_, declarations)| declarations)
 5690                        .dedup()
 5691                        .collect(),
 5692                ))
 5693            })
 5694        }
 5695    }
 5696
 5697    pub fn type_definitions(
 5698        &mut self,
 5699        buffer: &Entity<Buffer>,
 5700        position: PointUtf16,
 5701        cx: &mut Context<Self>,
 5702    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5703        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5704            let request = GetTypeDefinitions { position };
 5705            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5706                return Task::ready(Ok(None));
 5707            }
 5708            let request_task = upstream_client.request_lsp(
 5709                project_id,
 5710                None,
 5711                LSP_REQUEST_TIMEOUT,
 5712                cx.background_executor().clone(),
 5713                request.to_proto(project_id, buffer.read(cx)),
 5714            );
 5715            let buffer = buffer.clone();
 5716            cx.spawn(async move |weak_lsp_store, cx| {
 5717                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5718                    return Ok(None);
 5719                };
 5720                let Some(responses) = request_task.await? else {
 5721                    return Ok(None);
 5722                };
 5723                let actions = join_all(responses.payload.into_iter().map(|response| {
 5724                    GetTypeDefinitions { position }.response_from_proto(
 5725                        response.response,
 5726                        lsp_store.clone(),
 5727                        buffer.clone(),
 5728                        cx.clone(),
 5729                    )
 5730                }))
 5731                .await;
 5732
 5733                Ok(Some(
 5734                    actions
 5735                        .into_iter()
 5736                        .collect::<Result<Vec<Vec<_>>>>()?
 5737                        .into_iter()
 5738                        .flatten()
 5739                        .dedup()
 5740                        .collect(),
 5741                ))
 5742            })
 5743        } else {
 5744            let type_definitions_task = self.request_multiple_lsp_locally(
 5745                buffer,
 5746                Some(position),
 5747                GetTypeDefinitions { position },
 5748                cx,
 5749            );
 5750            cx.background_spawn(async move {
 5751                Ok(Some(
 5752                    type_definitions_task
 5753                        .await
 5754                        .into_iter()
 5755                        .flat_map(|(_, type_definitions)| type_definitions)
 5756                        .dedup()
 5757                        .collect(),
 5758                ))
 5759            })
 5760        }
 5761    }
 5762
 5763    pub fn implementations(
 5764        &mut self,
 5765        buffer: &Entity<Buffer>,
 5766        position: PointUtf16,
 5767        cx: &mut Context<Self>,
 5768    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5769        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5770            let request = GetImplementations { position };
 5771            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5772                return Task::ready(Ok(None));
 5773            }
 5774            let request_task = upstream_client.request_lsp(
 5775                project_id,
 5776                None,
 5777                LSP_REQUEST_TIMEOUT,
 5778                cx.background_executor().clone(),
 5779                request.to_proto(project_id, buffer.read(cx)),
 5780            );
 5781            let buffer = buffer.clone();
 5782            cx.spawn(async move |weak_lsp_store, cx| {
 5783                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5784                    return Ok(None);
 5785                };
 5786                let Some(responses) = request_task.await? else {
 5787                    return Ok(None);
 5788                };
 5789                let actions = join_all(responses.payload.into_iter().map(|response| {
 5790                    GetImplementations { position }.response_from_proto(
 5791                        response.response,
 5792                        lsp_store.clone(),
 5793                        buffer.clone(),
 5794                        cx.clone(),
 5795                    )
 5796                }))
 5797                .await;
 5798
 5799                Ok(Some(
 5800                    actions
 5801                        .into_iter()
 5802                        .collect::<Result<Vec<Vec<_>>>>()?
 5803                        .into_iter()
 5804                        .flatten()
 5805                        .dedup()
 5806                        .collect(),
 5807                ))
 5808            })
 5809        } else {
 5810            let implementations_task = self.request_multiple_lsp_locally(
 5811                buffer,
 5812                Some(position),
 5813                GetImplementations { position },
 5814                cx,
 5815            );
 5816            cx.background_spawn(async move {
 5817                Ok(Some(
 5818                    implementations_task
 5819                        .await
 5820                        .into_iter()
 5821                        .flat_map(|(_, implementations)| implementations)
 5822                        .dedup()
 5823                        .collect(),
 5824                ))
 5825            })
 5826        }
 5827    }
 5828
 5829    pub fn references(
 5830        &mut self,
 5831        buffer: &Entity<Buffer>,
 5832        position: PointUtf16,
 5833        cx: &mut Context<Self>,
 5834    ) -> Task<Result<Option<Vec<Location>>>> {
 5835        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5836            let request = GetReferences { position };
 5837            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5838                return Task::ready(Ok(None));
 5839            }
 5840
 5841            let request_task = upstream_client.request_lsp(
 5842                project_id,
 5843                None,
 5844                LSP_REQUEST_TIMEOUT,
 5845                cx.background_executor().clone(),
 5846                request.to_proto(project_id, buffer.read(cx)),
 5847            );
 5848            let buffer = buffer.clone();
 5849            cx.spawn(async move |weak_lsp_store, cx| {
 5850                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5851                    return Ok(None);
 5852                };
 5853                let Some(responses) = request_task.await? else {
 5854                    return Ok(None);
 5855                };
 5856
 5857                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5858                    GetReferences { position }.response_from_proto(
 5859                        lsp_response.response,
 5860                        lsp_store.clone(),
 5861                        buffer.clone(),
 5862                        cx.clone(),
 5863                    )
 5864                }))
 5865                .await
 5866                .into_iter()
 5867                .collect::<Result<Vec<Vec<_>>>>()?
 5868                .into_iter()
 5869                .flatten()
 5870                .dedup()
 5871                .collect();
 5872                Ok(Some(locations))
 5873            })
 5874        } else {
 5875            let references_task = self.request_multiple_lsp_locally(
 5876                buffer,
 5877                Some(position),
 5878                GetReferences { position },
 5879                cx,
 5880            );
 5881            cx.background_spawn(async move {
 5882                Ok(Some(
 5883                    references_task
 5884                        .await
 5885                        .into_iter()
 5886                        .flat_map(|(_, references)| references)
 5887                        .dedup()
 5888                        .collect(),
 5889                ))
 5890            })
 5891        }
 5892    }
 5893
 5894    pub fn code_actions(
 5895        &mut self,
 5896        buffer: &Entity<Buffer>,
 5897        range: Range<Anchor>,
 5898        kinds: Option<Vec<CodeActionKind>>,
 5899        cx: &mut Context<Self>,
 5900    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5901        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5902            let request = GetCodeActions {
 5903                range: range.clone(),
 5904                kinds: kinds.clone(),
 5905            };
 5906            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5907                return Task::ready(Ok(None));
 5908            }
 5909            let request_task = upstream_client.request_lsp(
 5910                project_id,
 5911                None,
 5912                LSP_REQUEST_TIMEOUT,
 5913                cx.background_executor().clone(),
 5914                request.to_proto(project_id, buffer.read(cx)),
 5915            );
 5916            let buffer = buffer.clone();
 5917            cx.spawn(async move |weak_lsp_store, cx| {
 5918                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5919                    return Ok(None);
 5920                };
 5921                let Some(responses) = request_task.await? else {
 5922                    return Ok(None);
 5923                };
 5924                let actions = join_all(responses.payload.into_iter().map(|response| {
 5925                    GetCodeActions {
 5926                        range: range.clone(),
 5927                        kinds: kinds.clone(),
 5928                    }
 5929                    .response_from_proto(
 5930                        response.response,
 5931                        lsp_store.clone(),
 5932                        buffer.clone(),
 5933                        cx.clone(),
 5934                    )
 5935                }))
 5936                .await;
 5937
 5938                Ok(Some(
 5939                    actions
 5940                        .into_iter()
 5941                        .collect::<Result<Vec<Vec<_>>>>()?
 5942                        .into_iter()
 5943                        .flatten()
 5944                        .collect(),
 5945                ))
 5946            })
 5947        } else {
 5948            let all_actions_task = self.request_multiple_lsp_locally(
 5949                buffer,
 5950                Some(range.start),
 5951                GetCodeActions { range, kinds },
 5952                cx,
 5953            );
 5954            cx.background_spawn(async move {
 5955                Ok(Some(
 5956                    all_actions_task
 5957                        .await
 5958                        .into_iter()
 5959                        .flat_map(|(_, actions)| actions)
 5960                        .collect(),
 5961                ))
 5962            })
 5963        }
 5964    }
 5965
 5966    pub fn code_lens_actions(
 5967        &mut self,
 5968        buffer: &Entity<Buffer>,
 5969        cx: &mut Context<Self>,
 5970    ) -> CodeLensTask {
 5971        let version_queried_for = buffer.read(cx).version();
 5972        let buffer_id = buffer.read(cx).remote_id();
 5973        let existing_servers = self.as_local().map(|local| {
 5974            local
 5975                .buffers_opened_in_servers
 5976                .get(&buffer_id)
 5977                .cloned()
 5978                .unwrap_or_default()
 5979        });
 5980
 5981        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 5982            if let Some(cached_lens) = &lsp_data.code_lens {
 5983                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 5984                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 5985                        existing_servers != cached_lens.lens.keys().copied().collect()
 5986                    });
 5987                    if !has_different_servers {
 5988                        return Task::ready(Ok(Some(
 5989                            cached_lens.lens.values().flatten().cloned().collect(),
 5990                        )))
 5991                        .shared();
 5992                    }
 5993                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 5994                    if !version_queried_for.changed_since(updating_for) {
 5995                        return running_update.clone();
 5996                    }
 5997                }
 5998            }
 5999        }
 6000
 6001        let lens_lsp_data = self
 6002            .latest_lsp_data(buffer, cx)
 6003            .code_lens
 6004            .get_or_insert_default();
 6005        let buffer = buffer.clone();
 6006        let query_version_queried_for = version_queried_for.clone();
 6007        let new_task = cx
 6008            .spawn(async move |lsp_store, cx| {
 6009                cx.background_executor()
 6010                    .timer(Duration::from_millis(30))
 6011                    .await;
 6012                let fetched_lens = lsp_store
 6013                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 6014                    .map_err(Arc::new)?
 6015                    .await
 6016                    .context("fetching code lens")
 6017                    .map_err(Arc::new);
 6018                let fetched_lens = match fetched_lens {
 6019                    Ok(fetched_lens) => fetched_lens,
 6020                    Err(e) => {
 6021                        lsp_store
 6022                            .update(cx, |lsp_store, _| {
 6023                                if let Some(lens_lsp_data) = lsp_store
 6024                                    .lsp_data
 6025                                    .get_mut(&buffer_id)
 6026                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 6027                                {
 6028                                    lens_lsp_data.update = None;
 6029                                }
 6030                            })
 6031                            .ok();
 6032                        return Err(e);
 6033                    }
 6034                };
 6035
 6036                lsp_store
 6037                    .update(cx, |lsp_store, _| {
 6038                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 6039                        let code_lens = lsp_data.code_lens.as_mut()?;
 6040                        if let Some(fetched_lens) = fetched_lens {
 6041                            if lsp_data.buffer_version == query_version_queried_for {
 6042                                code_lens.lens.extend(fetched_lens);
 6043                            } else if !lsp_data
 6044                                .buffer_version
 6045                                .changed_since(&query_version_queried_for)
 6046                            {
 6047                                lsp_data.buffer_version = query_version_queried_for;
 6048                                code_lens.lens = fetched_lens;
 6049                            }
 6050                        }
 6051                        code_lens.update = None;
 6052                        Some(code_lens.lens.values().flatten().cloned().collect())
 6053                    })
 6054                    .map_err(Arc::new)
 6055            })
 6056            .shared();
 6057        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 6058        new_task
 6059    }
 6060
 6061    fn fetch_code_lens(
 6062        &mut self,
 6063        buffer: &Entity<Buffer>,
 6064        cx: &mut Context<Self>,
 6065    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 6066        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6067            let request = GetCodeLens;
 6068            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6069                return Task::ready(Ok(None));
 6070            }
 6071            let request_task = upstream_client.request_lsp(
 6072                project_id,
 6073                None,
 6074                LSP_REQUEST_TIMEOUT,
 6075                cx.background_executor().clone(),
 6076                request.to_proto(project_id, buffer.read(cx)),
 6077            );
 6078            let buffer = buffer.clone();
 6079            cx.spawn(async move |weak_lsp_store, cx| {
 6080                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6081                    return Ok(None);
 6082                };
 6083                let Some(responses) = request_task.await? else {
 6084                    return Ok(None);
 6085                };
 6086
 6087                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 6088                    let lsp_store = lsp_store.clone();
 6089                    let buffer = buffer.clone();
 6090                    let cx = cx.clone();
 6091                    async move {
 6092                        (
 6093                            LanguageServerId::from_proto(response.server_id),
 6094                            GetCodeLens
 6095                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6096                                .await,
 6097                        )
 6098                    }
 6099                }))
 6100                .await;
 6101
 6102                let mut has_errors = false;
 6103                let code_lens_actions = code_lens_actions
 6104                    .into_iter()
 6105                    .filter_map(|(server_id, code_lens)| match code_lens {
 6106                        Ok(code_lens) => Some((server_id, code_lens)),
 6107                        Err(e) => {
 6108                            has_errors = true;
 6109                            log::error!("{e:#}");
 6110                            None
 6111                        }
 6112                    })
 6113                    .collect::<HashMap<_, _>>();
 6114                anyhow::ensure!(
 6115                    !has_errors || !code_lens_actions.is_empty(),
 6116                    "Failed to fetch code lens"
 6117                );
 6118                Ok(Some(code_lens_actions))
 6119            })
 6120        } else {
 6121            let code_lens_actions_task =
 6122                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 6123            cx.background_spawn(async move {
 6124                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 6125            })
 6126        }
 6127    }
 6128
 6129    #[inline(never)]
 6130    pub fn completions(
 6131        &self,
 6132        buffer: &Entity<Buffer>,
 6133        position: PointUtf16,
 6134        context: CompletionContext,
 6135        cx: &mut Context<Self>,
 6136    ) -> Task<Result<Vec<CompletionResponse>>> {
 6137        let language_registry = self.languages.clone();
 6138
 6139        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6140            let snapshot = buffer.read(cx).snapshot();
 6141            let offset = position.to_offset(&snapshot);
 6142            let scope = snapshot.language_scope_at(offset);
 6143            let capable_lsps = self.all_capable_for_proto_request(
 6144                buffer,
 6145                |server_name, capabilities| {
 6146                    capabilities.completion_provider.is_some()
 6147                        && scope
 6148                            .as_ref()
 6149                            .map(|scope| scope.language_allowed(server_name))
 6150                            .unwrap_or(true)
 6151                },
 6152                cx,
 6153            );
 6154            if capable_lsps.is_empty() {
 6155                return Task::ready(Ok(Vec::new()));
 6156            }
 6157
 6158            let language = buffer.read(cx).language().cloned();
 6159
 6160            // In the future, we should provide project guests with the names of LSP adapters,
 6161            // so that they can use the correct LSP adapter when computing labels. For now,
 6162            // guests just use the first LSP adapter associated with the buffer's language.
 6163            let lsp_adapter = language.as_ref().and_then(|language| {
 6164                language_registry
 6165                    .lsp_adapters(&language.name())
 6166                    .first()
 6167                    .cloned()
 6168            });
 6169
 6170            let buffer = buffer.clone();
 6171
 6172            cx.spawn(async move |this, cx| {
 6173                let requests = join_all(
 6174                    capable_lsps
 6175                        .into_iter()
 6176                        .map(|id| {
 6177                            let request = GetCompletions {
 6178                                position,
 6179                                context: context.clone(),
 6180                                server_id: Some(id),
 6181                            };
 6182                            let buffer = buffer.clone();
 6183                            let language = language.clone();
 6184                            let lsp_adapter = lsp_adapter.clone();
 6185                            let upstream_client = upstream_client.clone();
 6186                            let response = this
 6187                                .update(cx, |this, cx| {
 6188                                    this.send_lsp_proto_request(
 6189                                        buffer,
 6190                                        upstream_client,
 6191                                        project_id,
 6192                                        request,
 6193                                        cx,
 6194                                    )
 6195                                })
 6196                                .log_err();
 6197                            async move {
 6198                                let response = response?.await.log_err()?;
 6199
 6200                                let completions = populate_labels_for_completions(
 6201                                    response.completions,
 6202                                    language,
 6203                                    lsp_adapter,
 6204                                )
 6205                                .await;
 6206
 6207                                Some(CompletionResponse {
 6208                                    completions,
 6209                                    display_options: CompletionDisplayOptions::default(),
 6210                                    is_incomplete: response.is_incomplete,
 6211                                })
 6212                            }
 6213                        })
 6214                        .collect::<Vec<_>>(),
 6215                );
 6216                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6217            })
 6218        } else if let Some(local) = self.as_local() {
 6219            let snapshot = buffer.read(cx).snapshot();
 6220            let offset = position.to_offset(&snapshot);
 6221            let scope = snapshot.language_scope_at(offset);
 6222            let language = snapshot.language().cloned();
 6223            let completion_settings = language_settings(
 6224                language.as_ref().map(|language| language.name()),
 6225                buffer.read(cx).file(),
 6226                cx,
 6227            )
 6228            .completions
 6229            .clone();
 6230            if !completion_settings.lsp {
 6231                return Task::ready(Ok(Vec::new()));
 6232            }
 6233
 6234            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6235                local
 6236                    .language_servers_for_buffer(buffer, cx)
 6237                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6238                    .filter(|(adapter, _)| {
 6239                        scope
 6240                            .as_ref()
 6241                            .map(|scope| scope.language_allowed(&adapter.name))
 6242                            .unwrap_or(true)
 6243                    })
 6244                    .map(|(_, server)| server.server_id())
 6245                    .collect()
 6246            });
 6247
 6248            let buffer = buffer.clone();
 6249            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6250            let lsp_timeout = if lsp_timeout > 0 {
 6251                Some(Duration::from_millis(lsp_timeout))
 6252            } else {
 6253                None
 6254            };
 6255            cx.spawn(async move |this,  cx| {
 6256                let mut tasks = Vec::with_capacity(server_ids.len());
 6257                this.update(cx, |lsp_store, cx| {
 6258                    for server_id in server_ids {
 6259                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6260                        let lsp_timeout = lsp_timeout
 6261                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6262                        let mut timeout = cx.background_spawn(async move {
 6263                            match lsp_timeout {
 6264                                Some(lsp_timeout) => {
 6265                                    lsp_timeout.await;
 6266                                    true
 6267                                },
 6268                                None => false,
 6269                            }
 6270                        }).fuse();
 6271                        let mut lsp_request = lsp_store.request_lsp(
 6272                            buffer.clone(),
 6273                            LanguageServerToQuery::Other(server_id),
 6274                            GetCompletions {
 6275                                position,
 6276                                context: context.clone(),
 6277                                server_id: Some(server_id),
 6278                            },
 6279                            cx,
 6280                        ).fuse();
 6281                        let new_task = cx.background_spawn(async move {
 6282                            select_biased! {
 6283                                response = lsp_request => anyhow::Ok(Some(response?)),
 6284                                timeout_happened = timeout => {
 6285                                    if timeout_happened {
 6286                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6287                                        Ok(None)
 6288                                    } else {
 6289                                        let completions = lsp_request.await?;
 6290                                        Ok(Some(completions))
 6291                                    }
 6292                                },
 6293                            }
 6294                        });
 6295                        tasks.push((lsp_adapter, new_task));
 6296                    }
 6297                })?;
 6298
 6299                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6300                    let completion_response = task.await.ok()??;
 6301                    let completions = populate_labels_for_completions(
 6302                            completion_response.completions,
 6303                            language.clone(),
 6304                            lsp_adapter,
 6305                        )
 6306                        .await;
 6307                    Some(CompletionResponse {
 6308                        completions,
 6309                        display_options: CompletionDisplayOptions::default(),
 6310                        is_incomplete: completion_response.is_incomplete,
 6311                    })
 6312                });
 6313
 6314                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6315
 6316                Ok(responses.into_iter().flatten().collect())
 6317            })
 6318        } else {
 6319            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6320        }
 6321    }
 6322
 6323    pub fn resolve_completions(
 6324        &self,
 6325        buffer: Entity<Buffer>,
 6326        completion_indices: Vec<usize>,
 6327        completions: Rc<RefCell<Box<[Completion]>>>,
 6328        cx: &mut Context<Self>,
 6329    ) -> Task<Result<bool>> {
 6330        let client = self.upstream_client();
 6331        let buffer_id = buffer.read(cx).remote_id();
 6332        let buffer_snapshot = buffer.read(cx).snapshot();
 6333
 6334        if !self.check_if_capable_for_proto_request(
 6335            &buffer,
 6336            GetCompletions::can_resolve_completions,
 6337            cx,
 6338        ) {
 6339            return Task::ready(Ok(false));
 6340        }
 6341        cx.spawn(async move |lsp_store, cx| {
 6342            let mut did_resolve = false;
 6343            if let Some((client, project_id)) = client {
 6344                for completion_index in completion_indices {
 6345                    let server_id = {
 6346                        let completion = &completions.borrow()[completion_index];
 6347                        completion.source.server_id()
 6348                    };
 6349                    if let Some(server_id) = server_id {
 6350                        if Self::resolve_completion_remote(
 6351                            project_id,
 6352                            server_id,
 6353                            buffer_id,
 6354                            completions.clone(),
 6355                            completion_index,
 6356                            client.clone(),
 6357                        )
 6358                        .await
 6359                        .log_err()
 6360                        .is_some()
 6361                        {
 6362                            did_resolve = true;
 6363                        }
 6364                    } else {
 6365                        resolve_word_completion(
 6366                            &buffer_snapshot,
 6367                            &mut completions.borrow_mut()[completion_index],
 6368                        );
 6369                    }
 6370                }
 6371            } else {
 6372                for completion_index in completion_indices {
 6373                    let server_id = {
 6374                        let completion = &completions.borrow()[completion_index];
 6375                        completion.source.server_id()
 6376                    };
 6377                    if let Some(server_id) = server_id {
 6378                        let server_and_adapter = lsp_store
 6379                            .read_with(cx, |lsp_store, _| {
 6380                                let server = lsp_store.language_server_for_id(server_id)?;
 6381                                let adapter =
 6382                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6383                                Some((server, adapter))
 6384                            })
 6385                            .ok()
 6386                            .flatten();
 6387                        let Some((server, adapter)) = server_and_adapter else {
 6388                            continue;
 6389                        };
 6390
 6391                        let resolved = Self::resolve_completion_local(
 6392                            server,
 6393                            completions.clone(),
 6394                            completion_index,
 6395                        )
 6396                        .await
 6397                        .log_err()
 6398                        .is_some();
 6399                        if resolved {
 6400                            Self::regenerate_completion_labels(
 6401                                adapter,
 6402                                &buffer_snapshot,
 6403                                completions.clone(),
 6404                                completion_index,
 6405                            )
 6406                            .await
 6407                            .log_err();
 6408                            did_resolve = true;
 6409                        }
 6410                    } else {
 6411                        resolve_word_completion(
 6412                            &buffer_snapshot,
 6413                            &mut completions.borrow_mut()[completion_index],
 6414                        );
 6415                    }
 6416                }
 6417            }
 6418
 6419            Ok(did_resolve)
 6420        })
 6421    }
 6422
 6423    async fn resolve_completion_local(
 6424        server: Arc<lsp::LanguageServer>,
 6425        completions: Rc<RefCell<Box<[Completion]>>>,
 6426        completion_index: usize,
 6427    ) -> Result<()> {
 6428        let server_id = server.server_id();
 6429        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6430            return Ok(());
 6431        }
 6432
 6433        let request = {
 6434            let completion = &completions.borrow()[completion_index];
 6435            match &completion.source {
 6436                CompletionSource::Lsp {
 6437                    lsp_completion,
 6438                    resolved,
 6439                    server_id: completion_server_id,
 6440                    ..
 6441                } => {
 6442                    if *resolved {
 6443                        return Ok(());
 6444                    }
 6445                    anyhow::ensure!(
 6446                        server_id == *completion_server_id,
 6447                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6448                    );
 6449                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6450                }
 6451                CompletionSource::BufferWord { .. }
 6452                | CompletionSource::Dap { .. }
 6453                | CompletionSource::Custom => {
 6454                    return Ok(());
 6455                }
 6456            }
 6457        };
 6458        let resolved_completion = request
 6459            .await
 6460            .into_response()
 6461            .context("resolve completion")?;
 6462
 6463        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6464        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6465
 6466        let mut completions = completions.borrow_mut();
 6467        let completion = &mut completions[completion_index];
 6468        if let CompletionSource::Lsp {
 6469            lsp_completion,
 6470            resolved,
 6471            server_id: completion_server_id,
 6472            ..
 6473        } = &mut completion.source
 6474        {
 6475            if *resolved {
 6476                return Ok(());
 6477            }
 6478            anyhow::ensure!(
 6479                server_id == *completion_server_id,
 6480                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6481            );
 6482            **lsp_completion = resolved_completion;
 6483            *resolved = true;
 6484        }
 6485        Ok(())
 6486    }
 6487
 6488    async fn regenerate_completion_labels(
 6489        adapter: Arc<CachedLspAdapter>,
 6490        snapshot: &BufferSnapshot,
 6491        completions: Rc<RefCell<Box<[Completion]>>>,
 6492        completion_index: usize,
 6493    ) -> Result<()> {
 6494        let completion_item = completions.borrow()[completion_index]
 6495            .source
 6496            .lsp_completion(true)
 6497            .map(Cow::into_owned);
 6498        if let Some(lsp_documentation) = completion_item
 6499            .as_ref()
 6500            .and_then(|completion_item| completion_item.documentation.clone())
 6501        {
 6502            let mut completions = completions.borrow_mut();
 6503            let completion = &mut completions[completion_index];
 6504            completion.documentation = Some(lsp_documentation.into());
 6505        } else {
 6506            let mut completions = completions.borrow_mut();
 6507            let completion = &mut completions[completion_index];
 6508            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6509        }
 6510
 6511        let mut new_label = match completion_item {
 6512            Some(completion_item) => {
 6513                // 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
 6514                // So we have to update the label here anyway...
 6515                let language = snapshot.language();
 6516                match language {
 6517                    Some(language) => {
 6518                        adapter
 6519                            .labels_for_completions(
 6520                                std::slice::from_ref(&completion_item),
 6521                                language,
 6522                            )
 6523                            .await?
 6524                    }
 6525                    None => Vec::new(),
 6526                }
 6527                .pop()
 6528                .flatten()
 6529                .unwrap_or_else(|| {
 6530                    CodeLabel::fallback_for_completion(
 6531                        &completion_item,
 6532                        language.map(|language| language.as_ref()),
 6533                    )
 6534                })
 6535            }
 6536            None => CodeLabel::plain(
 6537                completions.borrow()[completion_index].new_text.clone(),
 6538                None,
 6539            ),
 6540        };
 6541        ensure_uniform_list_compatible_label(&mut new_label);
 6542
 6543        let mut completions = completions.borrow_mut();
 6544        let completion = &mut completions[completion_index];
 6545        if completion.label.filter_text() == new_label.filter_text() {
 6546            completion.label = new_label;
 6547        } else {
 6548            log::error!(
 6549                "Resolved completion changed display label from {} to {}. \
 6550                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6551                completion.label.text(),
 6552                new_label.text(),
 6553                completion.label.filter_text(),
 6554                new_label.filter_text()
 6555            );
 6556        }
 6557
 6558        Ok(())
 6559    }
 6560
 6561    async fn resolve_completion_remote(
 6562        project_id: u64,
 6563        server_id: LanguageServerId,
 6564        buffer_id: BufferId,
 6565        completions: Rc<RefCell<Box<[Completion]>>>,
 6566        completion_index: usize,
 6567        client: AnyProtoClient,
 6568    ) -> Result<()> {
 6569        let lsp_completion = {
 6570            let completion = &completions.borrow()[completion_index];
 6571            match &completion.source {
 6572                CompletionSource::Lsp {
 6573                    lsp_completion,
 6574                    resolved,
 6575                    server_id: completion_server_id,
 6576                    ..
 6577                } => {
 6578                    anyhow::ensure!(
 6579                        server_id == *completion_server_id,
 6580                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6581                    );
 6582                    if *resolved {
 6583                        return Ok(());
 6584                    }
 6585                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6586                }
 6587                CompletionSource::Custom
 6588                | CompletionSource::Dap { .. }
 6589                | CompletionSource::BufferWord { .. } => {
 6590                    return Ok(());
 6591                }
 6592            }
 6593        };
 6594        let request = proto::ResolveCompletionDocumentation {
 6595            project_id,
 6596            language_server_id: server_id.0 as u64,
 6597            lsp_completion,
 6598            buffer_id: buffer_id.into(),
 6599        };
 6600
 6601        let response = client
 6602            .request(request)
 6603            .await
 6604            .context("completion documentation resolve proto request")?;
 6605        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6606
 6607        let documentation = if response.documentation.is_empty() {
 6608            CompletionDocumentation::Undocumented
 6609        } else if response.documentation_is_markdown {
 6610            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6611        } else if response.documentation.lines().count() <= 1 {
 6612            CompletionDocumentation::SingleLine(response.documentation.into())
 6613        } else {
 6614            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6615        };
 6616
 6617        let mut completions = completions.borrow_mut();
 6618        let completion = &mut completions[completion_index];
 6619        completion.documentation = Some(documentation);
 6620        if let CompletionSource::Lsp {
 6621            insert_range,
 6622            lsp_completion,
 6623            resolved,
 6624            server_id: completion_server_id,
 6625            lsp_defaults: _,
 6626        } = &mut completion.source
 6627        {
 6628            let completion_insert_range = response
 6629                .old_insert_start
 6630                .and_then(deserialize_anchor)
 6631                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6632            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6633
 6634            if *resolved {
 6635                return Ok(());
 6636            }
 6637            anyhow::ensure!(
 6638                server_id == *completion_server_id,
 6639                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6640            );
 6641            **lsp_completion = resolved_lsp_completion;
 6642            *resolved = true;
 6643        }
 6644
 6645        let replace_range = response
 6646            .old_replace_start
 6647            .and_then(deserialize_anchor)
 6648            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6649        if let Some((old_replace_start, old_replace_end)) = replace_range
 6650            && !response.new_text.is_empty()
 6651        {
 6652            completion.new_text = response.new_text;
 6653            completion.replace_range = old_replace_start..old_replace_end;
 6654        }
 6655
 6656        Ok(())
 6657    }
 6658
 6659    pub fn apply_additional_edits_for_completion(
 6660        &self,
 6661        buffer_handle: Entity<Buffer>,
 6662        completions: Rc<RefCell<Box<[Completion]>>>,
 6663        completion_index: usize,
 6664        push_to_history: bool,
 6665        cx: &mut Context<Self>,
 6666    ) -> Task<Result<Option<Transaction>>> {
 6667        if let Some((client, project_id)) = self.upstream_client() {
 6668            let buffer = buffer_handle.read(cx);
 6669            let buffer_id = buffer.remote_id();
 6670            cx.spawn(async move |_, cx| {
 6671                let request = {
 6672                    let completion = completions.borrow()[completion_index].clone();
 6673                    proto::ApplyCompletionAdditionalEdits {
 6674                        project_id,
 6675                        buffer_id: buffer_id.into(),
 6676                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6677                            replace_range: completion.replace_range,
 6678                            new_text: completion.new_text,
 6679                            source: completion.source,
 6680                        })),
 6681                    }
 6682                };
 6683
 6684                if let Some(transaction) = client.request(request).await?.transaction {
 6685                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6686                    buffer_handle
 6687                        .update(cx, |buffer, _| {
 6688                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6689                        })?
 6690                        .await?;
 6691                    if push_to_history {
 6692                        buffer_handle.update(cx, |buffer, _| {
 6693                            buffer.push_transaction(transaction.clone(), Instant::now());
 6694                            buffer.finalize_last_transaction();
 6695                        })?;
 6696                    }
 6697                    Ok(Some(transaction))
 6698                } else {
 6699                    Ok(None)
 6700                }
 6701            })
 6702        } else {
 6703            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6704                let completion = &completions.borrow()[completion_index];
 6705                let server_id = completion.source.server_id()?;
 6706                Some(
 6707                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6708                        .1
 6709                        .clone(),
 6710                )
 6711            }) else {
 6712                return Task::ready(Ok(None));
 6713            };
 6714
 6715            cx.spawn(async move |this, cx| {
 6716                Self::resolve_completion_local(
 6717                    server.clone(),
 6718                    completions.clone(),
 6719                    completion_index,
 6720                )
 6721                .await
 6722                .context("resolving completion")?;
 6723                let completion = completions.borrow()[completion_index].clone();
 6724                let additional_text_edits = completion
 6725                    .source
 6726                    .lsp_completion(true)
 6727                    .as_ref()
 6728                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6729                if let Some(edits) = additional_text_edits {
 6730                    let edits = this
 6731                        .update(cx, |this, cx| {
 6732                            this.as_local_mut().unwrap().edits_from_lsp(
 6733                                &buffer_handle,
 6734                                edits,
 6735                                server.server_id(),
 6736                                None,
 6737                                cx,
 6738                            )
 6739                        })?
 6740                        .await?;
 6741
 6742                    buffer_handle.update(cx, |buffer, cx| {
 6743                        buffer.finalize_last_transaction();
 6744                        buffer.start_transaction();
 6745
 6746                        for (range, text) in edits {
 6747                            let primary = &completion.replace_range;
 6748
 6749                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6750                            // and the primary completion is just an insertion (empty range), then this is likely
 6751                            // an auto-import scenario and should not be considered overlapping
 6752                            // https://github.com/zed-industries/zed/issues/26136
 6753                            let is_file_start_auto_import = {
 6754                                let snapshot = buffer.snapshot();
 6755                                let primary_start_point = primary.start.to_point(&snapshot);
 6756                                let range_start_point = range.start.to_point(&snapshot);
 6757
 6758                                let result = primary_start_point.row == 0
 6759                                    && primary_start_point.column == 0
 6760                                    && range_start_point.row == 0
 6761                                    && range_start_point.column == 0;
 6762
 6763                                result
 6764                            };
 6765
 6766                            let has_overlap = if is_file_start_auto_import {
 6767                                false
 6768                            } else {
 6769                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6770                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6771                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6772                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6773                                let result = start_within || end_within;
 6774                                result
 6775                            };
 6776
 6777                            //Skip additional edits which overlap with the primary completion edit
 6778                            //https://github.com/zed-industries/zed/pull/1871
 6779                            if !has_overlap {
 6780                                buffer.edit([(range, text)], None, cx);
 6781                            }
 6782                        }
 6783
 6784                        let transaction = if buffer.end_transaction(cx).is_some() {
 6785                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6786                            if !push_to_history {
 6787                                buffer.forget_transaction(transaction.id);
 6788                            }
 6789                            Some(transaction)
 6790                        } else {
 6791                            None
 6792                        };
 6793                        Ok(transaction)
 6794                    })?
 6795                } else {
 6796                    Ok(None)
 6797                }
 6798            })
 6799        }
 6800    }
 6801
 6802    pub fn pull_diagnostics(
 6803        &mut self,
 6804        buffer: Entity<Buffer>,
 6805        cx: &mut Context<Self>,
 6806    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6807        let buffer_id = buffer.read(cx).remote_id();
 6808
 6809        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6810            let mut suitable_capabilities = None;
 6811            // Are we capable for proto request?
 6812            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6813                &buffer,
 6814                |capabilities| {
 6815                    if let Some(caps) = &capabilities.diagnostic_provider {
 6816                        suitable_capabilities = Some(caps.clone());
 6817                        true
 6818                    } else {
 6819                        false
 6820                    }
 6821                },
 6822                cx,
 6823            );
 6824            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6825            let Some(dynamic_caps) = suitable_capabilities else {
 6826                return Task::ready(Ok(None));
 6827            };
 6828            assert!(any_server_has_diagnostics_provider);
 6829
 6830            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6831            let request = GetDocumentDiagnostics {
 6832                previous_result_id: None,
 6833                identifier,
 6834                registration_id: None,
 6835            };
 6836            let request_task = client.request_lsp(
 6837                upstream_project_id,
 6838                None,
 6839                LSP_REQUEST_TIMEOUT,
 6840                cx.background_executor().clone(),
 6841                request.to_proto(upstream_project_id, buffer.read(cx)),
 6842            );
 6843            cx.background_spawn(async move {
 6844                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6845                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6846                // Do not attempt to further process the dummy responses here.
 6847                let _response = request_task.await?;
 6848                Ok(None)
 6849            })
 6850        } else {
 6851            let servers = buffer.update(cx, |buffer, cx| {
 6852                self.running_language_servers_for_local_buffer(buffer, cx)
 6853                    .map(|(_, server)| server.clone())
 6854                    .collect::<Vec<_>>()
 6855            });
 6856
 6857            let pull_diagnostics = servers
 6858                .into_iter()
 6859                .flat_map(|server| {
 6860                    let result = maybe!({
 6861                        let local = self.as_local()?;
 6862                        let server_id = server.server_id();
 6863                        let providers_with_identifiers = local
 6864                            .language_server_dynamic_registrations
 6865                            .get(&server_id)
 6866                            .into_iter()
 6867                            .flat_map(|registrations| registrations.diagnostics.clone())
 6868                            .collect::<Vec<_>>();
 6869                        Some(
 6870                            providers_with_identifiers
 6871                                .into_iter()
 6872                                .map(|(registration_id, dynamic_caps)| {
 6873                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6874                                    let registration_id = registration_id.map(SharedString::from);
 6875                                    let result_id = self.result_id_for_buffer_pull(
 6876                                        server_id,
 6877                                        buffer_id,
 6878                                        &registration_id,
 6879                                        cx,
 6880                                    );
 6881                                    self.request_lsp(
 6882                                        buffer.clone(),
 6883                                        LanguageServerToQuery::Other(server_id),
 6884                                        GetDocumentDiagnostics {
 6885                                            previous_result_id: result_id,
 6886                                            registration_id,
 6887                                            identifier,
 6888                                        },
 6889                                        cx,
 6890                                    )
 6891                                })
 6892                                .collect::<Vec<_>>(),
 6893                        )
 6894                    });
 6895
 6896                    result.unwrap_or_default()
 6897                })
 6898                .collect::<Vec<_>>();
 6899
 6900            cx.background_spawn(async move {
 6901                let mut responses = Vec::new();
 6902                for diagnostics in join_all(pull_diagnostics).await {
 6903                    responses.extend(diagnostics?);
 6904                }
 6905                Ok(Some(responses))
 6906            })
 6907        }
 6908    }
 6909
 6910    pub fn applicable_inlay_chunks(
 6911        &mut self,
 6912        buffer: &Entity<Buffer>,
 6913        ranges: &[Range<text::Anchor>],
 6914        cx: &mut Context<Self>,
 6915    ) -> Vec<Range<BufferRow>> {
 6916        let buffer_snapshot = buffer.read(cx).snapshot();
 6917        let ranges = ranges
 6918            .iter()
 6919            .map(|range| range.to_point(&buffer_snapshot))
 6920            .collect::<Vec<_>>();
 6921
 6922        self.latest_lsp_data(buffer, cx)
 6923            .inlay_hints
 6924            .applicable_chunks(ranges.as_slice())
 6925            .map(|chunk| chunk.row_range())
 6926            .collect()
 6927    }
 6928
 6929    pub fn invalidate_inlay_hints<'a>(
 6930        &'a mut self,
 6931        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6932    ) {
 6933        for buffer_id in for_buffers {
 6934            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6935                lsp_data.inlay_hints.clear();
 6936            }
 6937        }
 6938    }
 6939
 6940    pub fn inlay_hints(
 6941        &mut self,
 6942        invalidate: InvalidationStrategy,
 6943        buffer: Entity<Buffer>,
 6944        ranges: Vec<Range<text::Anchor>>,
 6945        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6946        cx: &mut Context<Self>,
 6947    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6948        let next_hint_id = self.next_hint_id.clone();
 6949        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6950        let query_version = lsp_data.buffer_version.clone();
 6951        let mut lsp_refresh_requested = false;
 6952        let for_server = if let InvalidationStrategy::RefreshRequested {
 6953            server_id,
 6954            request_id,
 6955        } = invalidate
 6956        {
 6957            let invalidated = lsp_data
 6958                .inlay_hints
 6959                .invalidate_for_server_refresh(server_id, request_id);
 6960            lsp_refresh_requested = invalidated;
 6961            Some(server_id)
 6962        } else {
 6963            None
 6964        };
 6965        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6966        let known_chunks = known_chunks
 6967            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6968            .map(|(_, known_chunks)| known_chunks)
 6969            .unwrap_or_default();
 6970
 6971        let buffer_snapshot = buffer.read(cx).snapshot();
 6972        let ranges = ranges
 6973            .iter()
 6974            .map(|range| range.to_point(&buffer_snapshot))
 6975            .collect::<Vec<_>>();
 6976
 6977        let mut hint_fetch_tasks = Vec::new();
 6978        let mut cached_inlay_hints = None;
 6979        let mut ranges_to_query = None;
 6980        let applicable_chunks = existing_inlay_hints
 6981            .applicable_chunks(ranges.as_slice())
 6982            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 6983            .collect::<Vec<_>>();
 6984        if applicable_chunks.is_empty() {
 6985            return HashMap::default();
 6986        }
 6987
 6988        for row_chunk in applicable_chunks {
 6989            match (
 6990                existing_inlay_hints
 6991                    .cached_hints(&row_chunk)
 6992                    .filter(|_| !lsp_refresh_requested)
 6993                    .cloned(),
 6994                existing_inlay_hints
 6995                    .fetched_hints(&row_chunk)
 6996                    .as_ref()
 6997                    .filter(|_| !lsp_refresh_requested)
 6998                    .cloned(),
 6999            ) {
 7000                (None, None) => {
 7001                    let chunk_range = row_chunk.anchor_range();
 7002                    ranges_to_query
 7003                        .get_or_insert_with(Vec::new)
 7004                        .push((row_chunk, chunk_range));
 7005                }
 7006                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7007                (Some(cached_hints), None) => {
 7008                    for (server_id, cached_hints) in cached_hints {
 7009                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7010                            cached_inlay_hints
 7011                                .get_or_insert_with(HashMap::default)
 7012                                .entry(row_chunk.row_range())
 7013                                .or_insert_with(HashMap::default)
 7014                                .entry(server_id)
 7015                                .or_insert_with(Vec::new)
 7016                                .extend(cached_hints);
 7017                        }
 7018                    }
 7019                }
 7020                (Some(cached_hints), Some(fetched_hints)) => {
 7021                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7022                    for (server_id, cached_hints) in cached_hints {
 7023                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7024                            cached_inlay_hints
 7025                                .get_or_insert_with(HashMap::default)
 7026                                .entry(row_chunk.row_range())
 7027                                .or_insert_with(HashMap::default)
 7028                                .entry(server_id)
 7029                                .or_insert_with(Vec::new)
 7030                                .extend(cached_hints);
 7031                        }
 7032                    }
 7033                }
 7034            }
 7035        }
 7036
 7037        if hint_fetch_tasks.is_empty()
 7038            && ranges_to_query
 7039                .as_ref()
 7040                .is_none_or(|ranges| ranges.is_empty())
 7041            && let Some(cached_inlay_hints) = cached_inlay_hints
 7042        {
 7043            cached_inlay_hints
 7044                .into_iter()
 7045                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7046                .collect()
 7047        } else {
 7048            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7049                let next_hint_id = next_hint_id.clone();
 7050                let buffer = buffer.clone();
 7051                let query_version = query_version.clone();
 7052                let new_inlay_hints = cx
 7053                    .spawn(async move |lsp_store, cx| {
 7054                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7055                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7056                        })?;
 7057                        new_fetch_task
 7058                            .await
 7059                            .and_then(|new_hints_by_server| {
 7060                                lsp_store.update(cx, |lsp_store, cx| {
 7061                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7062                                    let update_cache = lsp_data.buffer_version == query_version;
 7063                                    if new_hints_by_server.is_empty() {
 7064                                        if update_cache {
 7065                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7066                                        }
 7067                                        HashMap::default()
 7068                                    } else {
 7069                                        new_hints_by_server
 7070                                            .into_iter()
 7071                                            .map(|(server_id, new_hints)| {
 7072                                                let new_hints = new_hints
 7073                                                    .into_iter()
 7074                                                    .map(|new_hint| {
 7075                                                        (
 7076                                                            InlayId::Hint(next_hint_id.fetch_add(
 7077                                                                1,
 7078                                                                atomic::Ordering::AcqRel,
 7079                                                            )),
 7080                                                            new_hint,
 7081                                                        )
 7082                                                    })
 7083                                                    .collect::<Vec<_>>();
 7084                                                if update_cache {
 7085                                                    lsp_data.inlay_hints.insert_new_hints(
 7086                                                        chunk,
 7087                                                        server_id,
 7088                                                        new_hints.clone(),
 7089                                                    );
 7090                                                }
 7091                                                (server_id, new_hints)
 7092                                            })
 7093                                            .collect()
 7094                                    }
 7095                                })
 7096                            })
 7097                            .map_err(Arc::new)
 7098                    })
 7099                    .shared();
 7100
 7101                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7102                *fetch_task = Some(new_inlay_hints.clone());
 7103                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7104            }
 7105
 7106            cached_inlay_hints
 7107                .unwrap_or_default()
 7108                .into_iter()
 7109                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7110                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7111                    (
 7112                        chunk.row_range(),
 7113                        cx.spawn(async move |_, _| {
 7114                            hints_fetch.await.map_err(|e| {
 7115                                if e.error_code() != ErrorCode::Internal {
 7116                                    anyhow!(e.error_code())
 7117                                } else {
 7118                                    anyhow!("{e:#}")
 7119                                }
 7120                            })
 7121                        }),
 7122                    )
 7123                }))
 7124                .collect()
 7125        }
 7126    }
 7127
 7128    fn fetch_inlay_hints(
 7129        &mut self,
 7130        for_server: Option<LanguageServerId>,
 7131        buffer: &Entity<Buffer>,
 7132        range: Range<Anchor>,
 7133        cx: &mut Context<Self>,
 7134    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7135        let request = InlayHints {
 7136            range: range.clone(),
 7137        };
 7138        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7139            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7140                return Task::ready(Ok(HashMap::default()));
 7141            }
 7142            let request_task = upstream_client.request_lsp(
 7143                project_id,
 7144                for_server.map(|id| id.to_proto()),
 7145                LSP_REQUEST_TIMEOUT,
 7146                cx.background_executor().clone(),
 7147                request.to_proto(project_id, buffer.read(cx)),
 7148            );
 7149            let buffer = buffer.clone();
 7150            cx.spawn(async move |weak_lsp_store, cx| {
 7151                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7152                    return Ok(HashMap::default());
 7153                };
 7154                let Some(responses) = request_task.await? else {
 7155                    return Ok(HashMap::default());
 7156                };
 7157
 7158                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7159                    let lsp_store = lsp_store.clone();
 7160                    let buffer = buffer.clone();
 7161                    let cx = cx.clone();
 7162                    let request = request.clone();
 7163                    async move {
 7164                        (
 7165                            LanguageServerId::from_proto(response.server_id),
 7166                            request
 7167                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7168                                .await,
 7169                        )
 7170                    }
 7171                }))
 7172                .await;
 7173
 7174                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot())?;
 7175                let mut has_errors = false;
 7176                let inlay_hints = inlay_hints
 7177                    .into_iter()
 7178                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7179                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7180                        Err(e) => {
 7181                            has_errors = true;
 7182                            log::error!("{e:#}");
 7183                            None
 7184                        }
 7185                    })
 7186                    .map(|(server_id, mut new_hints)| {
 7187                        new_hints.retain(|hint| {
 7188                            hint.position.is_valid(&buffer_snapshot)
 7189                                && range.start.is_valid(&buffer_snapshot)
 7190                                && range.end.is_valid(&buffer_snapshot)
 7191                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7192                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7193                        });
 7194                        (server_id, new_hints)
 7195                    })
 7196                    .collect::<HashMap<_, _>>();
 7197                anyhow::ensure!(
 7198                    !has_errors || !inlay_hints.is_empty(),
 7199                    "Failed to fetch inlay hints"
 7200                );
 7201                Ok(inlay_hints)
 7202            })
 7203        } else {
 7204            let inlay_hints_task = match for_server {
 7205                Some(server_id) => {
 7206                    let server_task = self.request_lsp(
 7207                        buffer.clone(),
 7208                        LanguageServerToQuery::Other(server_id),
 7209                        request,
 7210                        cx,
 7211                    );
 7212                    cx.background_spawn(async move {
 7213                        let mut responses = Vec::new();
 7214                        match server_task.await {
 7215                            Ok(response) => responses.push((server_id, response)),
 7216                            // rust-analyzer likes to error with this when its still loading up
 7217                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7218                            Err(e) => log::error!(
 7219                                "Error handling response for inlay hints request: {e:#}"
 7220                            ),
 7221                        }
 7222                        responses
 7223                    })
 7224                }
 7225                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7226            };
 7227            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7228            cx.background_spawn(async move {
 7229                Ok(inlay_hints_task
 7230                    .await
 7231                    .into_iter()
 7232                    .map(|(server_id, mut new_hints)| {
 7233                        new_hints.retain(|hint| {
 7234                            hint.position.is_valid(&buffer_snapshot)
 7235                                && range.start.is_valid(&buffer_snapshot)
 7236                                && range.end.is_valid(&buffer_snapshot)
 7237                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7238                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7239                        });
 7240                        (server_id, new_hints)
 7241                    })
 7242                    .collect())
 7243            })
 7244        }
 7245    }
 7246
 7247    pub fn pull_diagnostics_for_buffer(
 7248        &mut self,
 7249        buffer: Entity<Buffer>,
 7250        cx: &mut Context<Self>,
 7251    ) -> Task<anyhow::Result<()>> {
 7252        let diagnostics = self.pull_diagnostics(buffer, cx);
 7253        cx.spawn(async move |lsp_store, cx| {
 7254            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7255                return Ok(());
 7256            };
 7257            lsp_store.update(cx, |lsp_store, cx| {
 7258                if lsp_store.as_local().is_none() {
 7259                    return;
 7260                }
 7261
 7262                let mut unchanged_buffers = HashMap::default();
 7263                let server_diagnostics_updates = diagnostics
 7264                    .into_iter()
 7265                    .filter_map(|diagnostics_set| match diagnostics_set {
 7266                        LspPullDiagnostics::Response {
 7267                            server_id,
 7268                            uri,
 7269                            diagnostics,
 7270                            registration_id,
 7271                        } => Some((server_id, uri, diagnostics, registration_id)),
 7272                        LspPullDiagnostics::Default => None,
 7273                    })
 7274                    .fold(
 7275                        HashMap::default(),
 7276                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7277                            let (result_id, diagnostics) = match diagnostics {
 7278                                PulledDiagnostics::Unchanged { result_id } => {
 7279                                    unchanged_buffers
 7280                                        .entry(new_registration_id.clone())
 7281                                        .or_insert_with(HashSet::default)
 7282                                        .insert(uri.clone());
 7283                                    (Some(result_id), Vec::new())
 7284                                }
 7285                                PulledDiagnostics::Changed {
 7286                                    result_id,
 7287                                    diagnostics,
 7288                                } => (result_id, diagnostics),
 7289                            };
 7290                            let disk_based_sources = Cow::Owned(
 7291                                lsp_store
 7292                                    .language_server_adapter_for_id(server_id)
 7293                                    .as_ref()
 7294                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7295                                    .unwrap_or(&[])
 7296                                    .to_vec(),
 7297                            );
 7298                            acc.entry(server_id)
 7299                                .or_insert_with(HashMap::default)
 7300                                .entry(new_registration_id.clone())
 7301                                .or_insert_with(Vec::new)
 7302                                .push(DocumentDiagnosticsUpdate {
 7303                                    server_id,
 7304                                    diagnostics: lsp::PublishDiagnosticsParams {
 7305                                        uri,
 7306                                        diagnostics,
 7307                                        version: None,
 7308                                    },
 7309                                    result_id,
 7310                                    disk_based_sources,
 7311                                    registration_id: new_registration_id,
 7312                                });
 7313                            acc
 7314                        },
 7315                    );
 7316
 7317                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7318                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7319                        lsp_store
 7320                            .merge_lsp_diagnostics(
 7321                                DiagnosticSourceKind::Pulled,
 7322                                diagnostic_updates,
 7323                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7324                                    DiagnosticSourceKind::Pulled => {
 7325                                        old_diagnostic.registration_id != registration_id
 7326                                            || unchanged_buffers
 7327                                                .get(&old_diagnostic.registration_id)
 7328                                                .is_some_and(|unchanged_buffers| {
 7329                                                    unchanged_buffers.contains(&document_uri)
 7330                                                })
 7331                                    }
 7332                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7333                                        true
 7334                                    }
 7335                                },
 7336                                cx,
 7337                            )
 7338                            .log_err();
 7339                    }
 7340                }
 7341            })
 7342        })
 7343    }
 7344
 7345    pub fn document_colors(
 7346        &mut self,
 7347        known_cache_version: Option<usize>,
 7348        buffer: Entity<Buffer>,
 7349        cx: &mut Context<Self>,
 7350    ) -> Option<DocumentColorTask> {
 7351        let version_queried_for = buffer.read(cx).version();
 7352        let buffer_id = buffer.read(cx).remote_id();
 7353
 7354        let current_language_servers = self.as_local().map(|local| {
 7355            local
 7356                .buffers_opened_in_servers
 7357                .get(&buffer_id)
 7358                .cloned()
 7359                .unwrap_or_default()
 7360        });
 7361
 7362        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7363            if let Some(cached_colors) = &lsp_data.document_colors {
 7364                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7365                    let has_different_servers =
 7366                        current_language_servers.is_some_and(|current_language_servers| {
 7367                            current_language_servers
 7368                                != cached_colors.colors.keys().copied().collect()
 7369                        });
 7370                    if !has_different_servers {
 7371                        let cache_version = cached_colors.cache_version;
 7372                        if Some(cache_version) == known_cache_version {
 7373                            return None;
 7374                        } else {
 7375                            return Some(
 7376                                Task::ready(Ok(DocumentColors {
 7377                                    colors: cached_colors
 7378                                        .colors
 7379                                        .values()
 7380                                        .flatten()
 7381                                        .cloned()
 7382                                        .collect(),
 7383                                    cache_version: Some(cache_version),
 7384                                }))
 7385                                .shared(),
 7386                            );
 7387                        }
 7388                    }
 7389                }
 7390            }
 7391        }
 7392
 7393        let color_lsp_data = self
 7394            .latest_lsp_data(&buffer, cx)
 7395            .document_colors
 7396            .get_or_insert_default();
 7397        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7398            && !version_queried_for.changed_since(updating_for)
 7399        {
 7400            return Some(running_update.clone());
 7401        }
 7402        let buffer_version_queried_for = version_queried_for.clone();
 7403        let new_task = cx
 7404            .spawn(async move |lsp_store, cx| {
 7405                cx.background_executor()
 7406                    .timer(Duration::from_millis(30))
 7407                    .await;
 7408                let fetched_colors = lsp_store
 7409                    .update(cx, |lsp_store, cx| {
 7410                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7411                    })?
 7412                    .await
 7413                    .context("fetching document colors")
 7414                    .map_err(Arc::new);
 7415                let fetched_colors = match fetched_colors {
 7416                    Ok(fetched_colors) => {
 7417                        if Some(true)
 7418                            == buffer
 7419                                .update(cx, |buffer, _| {
 7420                                    buffer.version() != buffer_version_queried_for
 7421                                })
 7422                                .ok()
 7423                        {
 7424                            return Ok(DocumentColors::default());
 7425                        }
 7426                        fetched_colors
 7427                    }
 7428                    Err(e) => {
 7429                        lsp_store
 7430                            .update(cx, |lsp_store, _| {
 7431                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7432                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7433                                        document_colors.colors_update = None;
 7434                                    }
 7435                                }
 7436                            })
 7437                            .ok();
 7438                        return Err(e);
 7439                    }
 7440                };
 7441
 7442                lsp_store
 7443                    .update(cx, |lsp_store, cx| {
 7444                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7445                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7446
 7447                        if let Some(fetched_colors) = fetched_colors {
 7448                            if lsp_data.buffer_version == buffer_version_queried_for {
 7449                                lsp_colors.colors.extend(fetched_colors);
 7450                                lsp_colors.cache_version += 1;
 7451                            } else if !lsp_data
 7452                                .buffer_version
 7453                                .changed_since(&buffer_version_queried_for)
 7454                            {
 7455                                lsp_data.buffer_version = buffer_version_queried_for;
 7456                                lsp_colors.colors = fetched_colors;
 7457                                lsp_colors.cache_version += 1;
 7458                            }
 7459                        }
 7460                        lsp_colors.colors_update = None;
 7461                        let colors = lsp_colors
 7462                            .colors
 7463                            .values()
 7464                            .flatten()
 7465                            .cloned()
 7466                            .collect::<HashSet<_>>();
 7467                        DocumentColors {
 7468                            colors,
 7469                            cache_version: Some(lsp_colors.cache_version),
 7470                        }
 7471                    })
 7472                    .map_err(Arc::new)
 7473            })
 7474            .shared();
 7475        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7476        Some(new_task)
 7477    }
 7478
 7479    fn fetch_document_colors_for_buffer(
 7480        &mut self,
 7481        buffer: &Entity<Buffer>,
 7482        cx: &mut Context<Self>,
 7483    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7484        if let Some((client, project_id)) = self.upstream_client() {
 7485            let request = GetDocumentColor {};
 7486            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7487                return Task::ready(Ok(None));
 7488            }
 7489
 7490            let request_task = client.request_lsp(
 7491                project_id,
 7492                None,
 7493                LSP_REQUEST_TIMEOUT,
 7494                cx.background_executor().clone(),
 7495                request.to_proto(project_id, buffer.read(cx)),
 7496            );
 7497            let buffer = buffer.clone();
 7498            cx.spawn(async move |lsp_store, cx| {
 7499                let Some(lsp_store) = lsp_store.upgrade() else {
 7500                    return Ok(None);
 7501                };
 7502                let colors = join_all(
 7503                    request_task
 7504                        .await
 7505                        .log_err()
 7506                        .flatten()
 7507                        .map(|response| response.payload)
 7508                        .unwrap_or_default()
 7509                        .into_iter()
 7510                        .map(|color_response| {
 7511                            let response = request.response_from_proto(
 7512                                color_response.response,
 7513                                lsp_store.clone(),
 7514                                buffer.clone(),
 7515                                cx.clone(),
 7516                            );
 7517                            async move {
 7518                                (
 7519                                    LanguageServerId::from_proto(color_response.server_id),
 7520                                    response.await.log_err().unwrap_or_default(),
 7521                                )
 7522                            }
 7523                        }),
 7524                )
 7525                .await
 7526                .into_iter()
 7527                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7528                    acc.entry(server_id)
 7529                        .or_insert_with(HashSet::default)
 7530                        .extend(colors);
 7531                    acc
 7532                });
 7533                Ok(Some(colors))
 7534            })
 7535        } else {
 7536            let document_colors_task =
 7537                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7538            cx.background_spawn(async move {
 7539                Ok(Some(
 7540                    document_colors_task
 7541                        .await
 7542                        .into_iter()
 7543                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7544                            acc.entry(server_id)
 7545                                .or_insert_with(HashSet::default)
 7546                                .extend(colors);
 7547                            acc
 7548                        })
 7549                        .into_iter()
 7550                        .collect(),
 7551                ))
 7552            })
 7553        }
 7554    }
 7555
 7556    pub fn signature_help<T: ToPointUtf16>(
 7557        &mut self,
 7558        buffer: &Entity<Buffer>,
 7559        position: T,
 7560        cx: &mut Context<Self>,
 7561    ) -> Task<Option<Vec<SignatureHelp>>> {
 7562        let position = position.to_point_utf16(buffer.read(cx));
 7563
 7564        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7565            let request = GetSignatureHelp { position };
 7566            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7567                return Task::ready(None);
 7568            }
 7569            let request_task = client.request_lsp(
 7570                upstream_project_id,
 7571                None,
 7572                LSP_REQUEST_TIMEOUT,
 7573                cx.background_executor().clone(),
 7574                request.to_proto(upstream_project_id, buffer.read(cx)),
 7575            );
 7576            let buffer = buffer.clone();
 7577            cx.spawn(async move |weak_lsp_store, cx| {
 7578                let lsp_store = weak_lsp_store.upgrade()?;
 7579                let signatures = join_all(
 7580                    request_task
 7581                        .await
 7582                        .log_err()
 7583                        .flatten()
 7584                        .map(|response| response.payload)
 7585                        .unwrap_or_default()
 7586                        .into_iter()
 7587                        .map(|response| {
 7588                            let response = GetSignatureHelp { position }.response_from_proto(
 7589                                response.response,
 7590                                lsp_store.clone(),
 7591                                buffer.clone(),
 7592                                cx.clone(),
 7593                            );
 7594                            async move { response.await.log_err().flatten() }
 7595                        }),
 7596                )
 7597                .await
 7598                .into_iter()
 7599                .flatten()
 7600                .collect();
 7601                Some(signatures)
 7602            })
 7603        } else {
 7604            let all_actions_task = self.request_multiple_lsp_locally(
 7605                buffer,
 7606                Some(position),
 7607                GetSignatureHelp { position },
 7608                cx,
 7609            );
 7610            cx.background_spawn(async move {
 7611                Some(
 7612                    all_actions_task
 7613                        .await
 7614                        .into_iter()
 7615                        .flat_map(|(_, actions)| actions)
 7616                        .collect::<Vec<_>>(),
 7617                )
 7618            })
 7619        }
 7620    }
 7621
 7622    pub fn hover(
 7623        &mut self,
 7624        buffer: &Entity<Buffer>,
 7625        position: PointUtf16,
 7626        cx: &mut Context<Self>,
 7627    ) -> Task<Option<Vec<Hover>>> {
 7628        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7629            let request = GetHover { position };
 7630            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7631                return Task::ready(None);
 7632            }
 7633            let request_task = client.request_lsp(
 7634                upstream_project_id,
 7635                None,
 7636                LSP_REQUEST_TIMEOUT,
 7637                cx.background_executor().clone(),
 7638                request.to_proto(upstream_project_id, buffer.read(cx)),
 7639            );
 7640            let buffer = buffer.clone();
 7641            cx.spawn(async move |weak_lsp_store, cx| {
 7642                let lsp_store = weak_lsp_store.upgrade()?;
 7643                let hovers = join_all(
 7644                    request_task
 7645                        .await
 7646                        .log_err()
 7647                        .flatten()
 7648                        .map(|response| response.payload)
 7649                        .unwrap_or_default()
 7650                        .into_iter()
 7651                        .map(|response| {
 7652                            let response = GetHover { position }.response_from_proto(
 7653                                response.response,
 7654                                lsp_store.clone(),
 7655                                buffer.clone(),
 7656                                cx.clone(),
 7657                            );
 7658                            async move {
 7659                                response
 7660                                    .await
 7661                                    .log_err()
 7662                                    .flatten()
 7663                                    .and_then(remove_empty_hover_blocks)
 7664                            }
 7665                        }),
 7666                )
 7667                .await
 7668                .into_iter()
 7669                .flatten()
 7670                .collect();
 7671                Some(hovers)
 7672            })
 7673        } else {
 7674            let all_actions_task = self.request_multiple_lsp_locally(
 7675                buffer,
 7676                Some(position),
 7677                GetHover { position },
 7678                cx,
 7679            );
 7680            cx.background_spawn(async move {
 7681                Some(
 7682                    all_actions_task
 7683                        .await
 7684                        .into_iter()
 7685                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7686                        .collect::<Vec<Hover>>(),
 7687                )
 7688            })
 7689        }
 7690    }
 7691
 7692    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7693        let language_registry = self.languages.clone();
 7694
 7695        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7696            let request = upstream_client.request(proto::GetProjectSymbols {
 7697                project_id: *project_id,
 7698                query: query.to_string(),
 7699            });
 7700            cx.foreground_executor().spawn(async move {
 7701                let response = request.await?;
 7702                let mut symbols = Vec::new();
 7703                let core_symbols = response
 7704                    .symbols
 7705                    .into_iter()
 7706                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7707                    .collect::<Vec<_>>();
 7708                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7709                    .await;
 7710                Ok(symbols)
 7711            })
 7712        } else if let Some(local) = self.as_local() {
 7713            struct WorkspaceSymbolsResult {
 7714                server_id: LanguageServerId,
 7715                lsp_adapter: Arc<CachedLspAdapter>,
 7716                worktree: WeakEntity<Worktree>,
 7717                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7718            }
 7719
 7720            let mut requests = Vec::new();
 7721            let mut requested_servers = BTreeSet::new();
 7722            for (seed, state) in local.language_server_ids.iter() {
 7723                let Some(worktree_handle) = self
 7724                    .worktree_store
 7725                    .read(cx)
 7726                    .worktree_for_id(seed.worktree_id, cx)
 7727                else {
 7728                    continue;
 7729                };
 7730                let worktree = worktree_handle.read(cx);
 7731                if !worktree.is_visible() {
 7732                    continue;
 7733                }
 7734
 7735                if !requested_servers.insert(state.id) {
 7736                    continue;
 7737                }
 7738
 7739                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7740                    Some(LanguageServerState::Running {
 7741                        adapter, server, ..
 7742                    }) => (adapter.clone(), server),
 7743
 7744                    _ => continue,
 7745                };
 7746                let supports_workspace_symbol_request =
 7747                    match server.capabilities().workspace_symbol_provider {
 7748                        Some(OneOf::Left(supported)) => supported,
 7749                        Some(OneOf::Right(_)) => true,
 7750                        None => false,
 7751                    };
 7752                if !supports_workspace_symbol_request {
 7753                    continue;
 7754                }
 7755                let worktree_handle = worktree_handle.clone();
 7756                let server_id = server.server_id();
 7757                requests.push(
 7758                        server
 7759                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7760                                lsp::WorkspaceSymbolParams {
 7761                                    query: query.to_string(),
 7762                                    ..Default::default()
 7763                                },
 7764                            )
 7765                            .map(move |response| {
 7766                                let lsp_symbols = response.into_response()
 7767                                    .context("workspace symbols request")
 7768                                    .log_err()
 7769                                    .flatten()
 7770                                    .map(|symbol_response| match symbol_response {
 7771                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7772                                            flat_responses.into_iter().map(|lsp_symbol| {
 7773                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7774                                            }).collect::<Vec<_>>()
 7775                                        }
 7776                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7777                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7778                                                let location = match lsp_symbol.location {
 7779                                                    OneOf::Left(location) => location,
 7780                                                    OneOf::Right(_) => {
 7781                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7782                                                        return None
 7783                                                    }
 7784                                                };
 7785                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7786                                            }).collect::<Vec<_>>()
 7787                                        }
 7788                                    }).unwrap_or_default();
 7789
 7790                                WorkspaceSymbolsResult {
 7791                                    server_id,
 7792                                    lsp_adapter,
 7793                                    worktree: worktree_handle.downgrade(),
 7794                                    lsp_symbols,
 7795                                }
 7796                            }),
 7797                    );
 7798            }
 7799
 7800            cx.spawn(async move |this, cx| {
 7801                let responses = futures::future::join_all(requests).await;
 7802                let this = match this.upgrade() {
 7803                    Some(this) => this,
 7804                    None => return Ok(Vec::new()),
 7805                };
 7806
 7807                let mut symbols = Vec::new();
 7808                for result in responses {
 7809                    let core_symbols = this.update(cx, |this, cx| {
 7810                        result
 7811                            .lsp_symbols
 7812                            .into_iter()
 7813                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7814                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7815                                let source_worktree = result.worktree.upgrade()?;
 7816                                let source_worktree_id = source_worktree.read(cx).id();
 7817
 7818                                let path = if let Some((tree, rel_path)) =
 7819                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7820                                {
 7821                                    let worktree_id = tree.read(cx).id();
 7822                                    SymbolLocation::InProject(ProjectPath {
 7823                                        worktree_id,
 7824                                        path: rel_path,
 7825                                    })
 7826                                } else {
 7827                                    SymbolLocation::OutsideProject {
 7828                                        signature: this.symbol_signature(&abs_path),
 7829                                        abs_path: abs_path.into(),
 7830                                    }
 7831                                };
 7832
 7833                                Some(CoreSymbol {
 7834                                    source_language_server_id: result.server_id,
 7835                                    language_server_name: result.lsp_adapter.name.clone(),
 7836                                    source_worktree_id,
 7837                                    path,
 7838                                    kind: symbol_kind,
 7839                                    name: symbol_name,
 7840                                    range: range_from_lsp(symbol_location.range),
 7841                                })
 7842                            })
 7843                            .collect()
 7844                    })?;
 7845
 7846                    populate_labels_for_symbols(
 7847                        core_symbols,
 7848                        &language_registry,
 7849                        Some(result.lsp_adapter),
 7850                        &mut symbols,
 7851                    )
 7852                    .await;
 7853                }
 7854
 7855                Ok(symbols)
 7856            })
 7857        } else {
 7858            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7859        }
 7860    }
 7861
 7862    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7863        let mut summary = DiagnosticSummary::default();
 7864        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7865            summary.error_count += path_summary.error_count;
 7866            summary.warning_count += path_summary.warning_count;
 7867        }
 7868        summary
 7869    }
 7870
 7871    /// Returns the diagnostic summary for a specific project path.
 7872    pub fn diagnostic_summary_for_path(
 7873        &self,
 7874        project_path: &ProjectPath,
 7875        _: &App,
 7876    ) -> DiagnosticSummary {
 7877        if let Some(summaries) = self
 7878            .diagnostic_summaries
 7879            .get(&project_path.worktree_id)
 7880            .and_then(|map| map.get(&project_path.path))
 7881        {
 7882            let (error_count, warning_count) = summaries.iter().fold(
 7883                (0, 0),
 7884                |(error_count, warning_count), (_language_server_id, summary)| {
 7885                    (
 7886                        error_count + summary.error_count,
 7887                        warning_count + summary.warning_count,
 7888                    )
 7889                },
 7890            );
 7891
 7892            DiagnosticSummary {
 7893                error_count,
 7894                warning_count,
 7895            }
 7896        } else {
 7897            DiagnosticSummary::default()
 7898        }
 7899    }
 7900
 7901    pub fn diagnostic_summaries<'a>(
 7902        &'a self,
 7903        include_ignored: bool,
 7904        cx: &'a App,
 7905    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7906        self.worktree_store
 7907            .read(cx)
 7908            .visible_worktrees(cx)
 7909            .filter_map(|worktree| {
 7910                let worktree = worktree.read(cx);
 7911                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7912            })
 7913            .flat_map(move |(worktree, summaries)| {
 7914                let worktree_id = worktree.id();
 7915                summaries
 7916                    .iter()
 7917                    .filter(move |(path, _)| {
 7918                        include_ignored
 7919                            || worktree
 7920                                .entry_for_path(path.as_ref())
 7921                                .is_some_and(|entry| !entry.is_ignored)
 7922                    })
 7923                    .flat_map(move |(path, summaries)| {
 7924                        summaries.iter().map(move |(server_id, summary)| {
 7925                            (
 7926                                ProjectPath {
 7927                                    worktree_id,
 7928                                    path: path.clone(),
 7929                                },
 7930                                *server_id,
 7931                                *summary,
 7932                            )
 7933                        })
 7934                    })
 7935            })
 7936    }
 7937
 7938    pub fn on_buffer_edited(
 7939        &mut self,
 7940        buffer: Entity<Buffer>,
 7941        cx: &mut Context<Self>,
 7942    ) -> Option<()> {
 7943        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7944            Some(
 7945                self.as_local()?
 7946                    .language_servers_for_buffer(buffer, cx)
 7947                    .map(|i| i.1.clone())
 7948                    .collect(),
 7949            )
 7950        })?;
 7951
 7952        let buffer = buffer.read(cx);
 7953        let file = File::from_dyn(buffer.file())?;
 7954        let abs_path = file.as_local()?.abs_path(cx);
 7955        let uri = lsp::Uri::from_file_path(&abs_path)
 7956            .ok()
 7957            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7958            .log_err()?;
 7959        let next_snapshot = buffer.text_snapshot();
 7960        for language_server in language_servers {
 7961            let language_server = language_server.clone();
 7962
 7963            let buffer_snapshots = self
 7964                .as_local_mut()?
 7965                .buffer_snapshots
 7966                .get_mut(&buffer.remote_id())
 7967                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7968            let previous_snapshot = buffer_snapshots.last()?;
 7969
 7970            let build_incremental_change = || {
 7971                buffer
 7972                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7973                        previous_snapshot.snapshot.version(),
 7974                    )
 7975                    .map(|edit| {
 7976                        let edit_start = edit.new.start.0;
 7977                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7978                        let new_text = next_snapshot
 7979                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7980                            .collect();
 7981                        lsp::TextDocumentContentChangeEvent {
 7982                            range: Some(lsp::Range::new(
 7983                                point_to_lsp(edit_start),
 7984                                point_to_lsp(edit_end),
 7985                            )),
 7986                            range_length: None,
 7987                            text: new_text,
 7988                        }
 7989                    })
 7990                    .collect()
 7991            };
 7992
 7993            let document_sync_kind = language_server
 7994                .capabilities()
 7995                .text_document_sync
 7996                .as_ref()
 7997                .and_then(|sync| match sync {
 7998                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7999                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 8000                });
 8001
 8002            let content_changes: Vec<_> = match document_sync_kind {
 8003                Some(lsp::TextDocumentSyncKind::FULL) => {
 8004                    vec![lsp::TextDocumentContentChangeEvent {
 8005                        range: None,
 8006                        range_length: None,
 8007                        text: next_snapshot.text(),
 8008                    }]
 8009                }
 8010                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8011                _ => {
 8012                    #[cfg(any(test, feature = "test-support"))]
 8013                    {
 8014                        build_incremental_change()
 8015                    }
 8016
 8017                    #[cfg(not(any(test, feature = "test-support")))]
 8018                    {
 8019                        continue;
 8020                    }
 8021                }
 8022            };
 8023
 8024            let next_version = previous_snapshot.version + 1;
 8025            buffer_snapshots.push(LspBufferSnapshot {
 8026                version: next_version,
 8027                snapshot: next_snapshot.clone(),
 8028            });
 8029
 8030            language_server
 8031                .notify::<lsp::notification::DidChangeTextDocument>(
 8032                    lsp::DidChangeTextDocumentParams {
 8033                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8034                            uri.clone(),
 8035                            next_version,
 8036                        ),
 8037                        content_changes,
 8038                    },
 8039                )
 8040                .ok();
 8041            self.pull_workspace_diagnostics(language_server.server_id());
 8042        }
 8043
 8044        None
 8045    }
 8046
 8047    pub fn on_buffer_saved(
 8048        &mut self,
 8049        buffer: Entity<Buffer>,
 8050        cx: &mut Context<Self>,
 8051    ) -> Option<()> {
 8052        let file = File::from_dyn(buffer.read(cx).file())?;
 8053        let worktree_id = file.worktree_id(cx);
 8054        let abs_path = file.as_local()?.abs_path(cx);
 8055        let text_document = lsp::TextDocumentIdentifier {
 8056            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8057        };
 8058        let local = self.as_local()?;
 8059
 8060        for server in local.language_servers_for_worktree(worktree_id) {
 8061            if let Some(include_text) = include_text(server.as_ref()) {
 8062                let text = if include_text {
 8063                    Some(buffer.read(cx).text())
 8064                } else {
 8065                    None
 8066                };
 8067                server
 8068                    .notify::<lsp::notification::DidSaveTextDocument>(
 8069                        lsp::DidSaveTextDocumentParams {
 8070                            text_document: text_document.clone(),
 8071                            text,
 8072                        },
 8073                    )
 8074                    .ok();
 8075            }
 8076        }
 8077
 8078        let language_servers = buffer.update(cx, |buffer, cx| {
 8079            local.language_server_ids_for_buffer(buffer, cx)
 8080        });
 8081        for language_server_id in language_servers {
 8082            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8083        }
 8084
 8085        None
 8086    }
 8087
 8088    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8089        maybe!(async move {
 8090            let mut refreshed_servers = HashSet::default();
 8091            let servers = lsp_store
 8092                .update(cx, |lsp_store, cx| {
 8093                    let local = lsp_store.as_local()?;
 8094
 8095                    let servers = local
 8096                        .language_server_ids
 8097                        .iter()
 8098                        .filter_map(|(seed, state)| {
 8099                            let worktree = lsp_store
 8100                                .worktree_store
 8101                                .read(cx)
 8102                                .worktree_for_id(seed.worktree_id, cx);
 8103                            let delegate: Arc<dyn LspAdapterDelegate> =
 8104                                worktree.map(|worktree| {
 8105                                    LocalLspAdapterDelegate::new(
 8106                                        local.languages.clone(),
 8107                                        &local.environment,
 8108                                        cx.weak_entity(),
 8109                                        &worktree,
 8110                                        local.http_client.clone(),
 8111                                        local.fs.clone(),
 8112                                        cx,
 8113                                    )
 8114                                })?;
 8115                            let server_id = state.id;
 8116
 8117                            let states = local.language_servers.get(&server_id)?;
 8118
 8119                            match states {
 8120                                LanguageServerState::Starting { .. } => None,
 8121                                LanguageServerState::Running {
 8122                                    adapter, server, ..
 8123                                } => {
 8124                                    let adapter = adapter.clone();
 8125                                    let server = server.clone();
 8126                                    refreshed_servers.insert(server.name());
 8127                                    let toolchain = seed.toolchain.clone();
 8128                                    Some(cx.spawn(async move |_, cx| {
 8129                                        let settings =
 8130                                            LocalLspStore::workspace_configuration_for_adapter(
 8131                                                adapter.adapter.clone(),
 8132                                                &delegate,
 8133                                                toolchain,
 8134                                                None,
 8135                                                cx,
 8136                                            )
 8137                                            .await
 8138                                            .ok()?;
 8139                                        server
 8140                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8141                                                lsp::DidChangeConfigurationParams { settings },
 8142                                            )
 8143                                            .ok()?;
 8144                                        Some(())
 8145                                    }))
 8146                                }
 8147                            }
 8148                        })
 8149                        .collect::<Vec<_>>();
 8150
 8151                    Some(servers)
 8152                })
 8153                .ok()
 8154                .flatten()?;
 8155
 8156            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8157            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8158            // to stop and unregister its language server wrapper.
 8159            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8160            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8161            let _: Vec<Option<()>> = join_all(servers).await;
 8162
 8163            Some(())
 8164        })
 8165        .await;
 8166    }
 8167
 8168    fn maintain_workspace_config(
 8169        external_refresh_requests: watch::Receiver<()>,
 8170        cx: &mut Context<Self>,
 8171    ) -> Task<Result<()>> {
 8172        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8173        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8174
 8175        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8176            *settings_changed_tx.borrow_mut() = ();
 8177        });
 8178
 8179        let mut joint_future =
 8180            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8181        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8182        // - 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).
 8183        // - 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.
 8184        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8185        // - 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,
 8186        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8187        cx.spawn(async move |this, cx| {
 8188            while let Some(()) = joint_future.next().await {
 8189                this.update(cx, |this, cx| {
 8190                    this.refresh_server_tree(cx);
 8191                })
 8192                .ok();
 8193
 8194                Self::refresh_workspace_configurations(&this, cx).await;
 8195            }
 8196
 8197            drop(settings_observation);
 8198            anyhow::Ok(())
 8199        })
 8200    }
 8201
 8202    pub fn running_language_servers_for_local_buffer<'a>(
 8203        &'a self,
 8204        buffer: &Buffer,
 8205        cx: &mut App,
 8206    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8207        let local = self.as_local();
 8208        let language_server_ids = local
 8209            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8210            .unwrap_or_default();
 8211
 8212        language_server_ids
 8213            .into_iter()
 8214            .filter_map(
 8215                move |server_id| match local?.language_servers.get(&server_id)? {
 8216                    LanguageServerState::Running {
 8217                        adapter, server, ..
 8218                    } => Some((adapter, server)),
 8219                    _ => None,
 8220                },
 8221            )
 8222    }
 8223
 8224    pub fn language_servers_for_local_buffer(
 8225        &self,
 8226        buffer: &Buffer,
 8227        cx: &mut App,
 8228    ) -> Vec<LanguageServerId> {
 8229        let local = self.as_local();
 8230        local
 8231            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8232            .unwrap_or_default()
 8233    }
 8234
 8235    pub fn language_server_for_local_buffer<'a>(
 8236        &'a self,
 8237        buffer: &'a Buffer,
 8238        server_id: LanguageServerId,
 8239        cx: &'a mut App,
 8240    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8241        self.as_local()?
 8242            .language_servers_for_buffer(buffer, cx)
 8243            .find(|(_, s)| s.server_id() == server_id)
 8244    }
 8245
 8246    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8247        self.diagnostic_summaries.remove(&id_to_remove);
 8248        if let Some(local) = self.as_local_mut() {
 8249            let to_remove = local.remove_worktree(id_to_remove, cx);
 8250            for server in to_remove {
 8251                self.language_server_statuses.remove(&server);
 8252            }
 8253        }
 8254    }
 8255
 8256    pub fn shared(
 8257        &mut self,
 8258        project_id: u64,
 8259        downstream_client: AnyProtoClient,
 8260        _: &mut Context<Self>,
 8261    ) {
 8262        self.downstream_client = Some((downstream_client.clone(), project_id));
 8263
 8264        for (server_id, status) in &self.language_server_statuses {
 8265            if let Some(server) = self.language_server_for_id(*server_id) {
 8266                downstream_client
 8267                    .send(proto::StartLanguageServer {
 8268                        project_id,
 8269                        server: Some(proto::LanguageServer {
 8270                            id: server_id.to_proto(),
 8271                            name: status.name.to_string(),
 8272                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8273                        }),
 8274                        capabilities: serde_json::to_string(&server.capabilities())
 8275                            .expect("serializing server LSP capabilities"),
 8276                    })
 8277                    .log_err();
 8278            }
 8279        }
 8280    }
 8281
 8282    pub fn disconnected_from_host(&mut self) {
 8283        self.downstream_client.take();
 8284    }
 8285
 8286    pub fn disconnected_from_ssh_remote(&mut self) {
 8287        if let LspStoreMode::Remote(RemoteLspStore {
 8288            upstream_client, ..
 8289        }) = &mut self.mode
 8290        {
 8291            upstream_client.take();
 8292        }
 8293    }
 8294
 8295    pub(crate) fn set_language_server_statuses_from_proto(
 8296        &mut self,
 8297        project: WeakEntity<Project>,
 8298        language_servers: Vec<proto::LanguageServer>,
 8299        server_capabilities: Vec<String>,
 8300        cx: &mut Context<Self>,
 8301    ) {
 8302        let lsp_logs = cx
 8303            .try_global::<GlobalLogStore>()
 8304            .map(|lsp_store| lsp_store.0.clone());
 8305
 8306        self.language_server_statuses = language_servers
 8307            .into_iter()
 8308            .zip(server_capabilities)
 8309            .map(|(server, server_capabilities)| {
 8310                let server_id = LanguageServerId(server.id as usize);
 8311                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8312                    self.lsp_server_capabilities
 8313                        .insert(server_id, server_capabilities);
 8314                }
 8315
 8316                let name = LanguageServerName::from_proto(server.name);
 8317                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8318
 8319                if let Some(lsp_logs) = &lsp_logs {
 8320                    lsp_logs.update(cx, |lsp_logs, cx| {
 8321                        lsp_logs.add_language_server(
 8322                            // Only remote clients get their language servers set from proto
 8323                            LanguageServerKind::Remote {
 8324                                project: project.clone(),
 8325                            },
 8326                            server_id,
 8327                            Some(name.clone()),
 8328                            worktree,
 8329                            None,
 8330                            cx,
 8331                        );
 8332                    });
 8333                }
 8334
 8335                (
 8336                    server_id,
 8337                    LanguageServerStatus {
 8338                        name,
 8339                        pending_work: Default::default(),
 8340                        has_pending_diagnostic_updates: false,
 8341                        progress_tokens: Default::default(),
 8342                        worktree,
 8343                        binary: None,
 8344                        configuration: None,
 8345                        workspace_folders: BTreeSet::new(),
 8346                    },
 8347                )
 8348            })
 8349            .collect();
 8350    }
 8351
 8352    #[cfg(test)]
 8353    pub fn update_diagnostic_entries(
 8354        &mut self,
 8355        server_id: LanguageServerId,
 8356        abs_path: PathBuf,
 8357        result_id: Option<SharedString>,
 8358        version: Option<i32>,
 8359        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8360        cx: &mut Context<Self>,
 8361    ) -> anyhow::Result<()> {
 8362        self.merge_diagnostic_entries(
 8363            vec![DocumentDiagnosticsUpdate {
 8364                diagnostics: DocumentDiagnostics {
 8365                    diagnostics,
 8366                    document_abs_path: abs_path,
 8367                    version,
 8368                },
 8369                result_id,
 8370                server_id,
 8371                disk_based_sources: Cow::Borrowed(&[]),
 8372                registration_id: None,
 8373            }],
 8374            |_, _, _| false,
 8375            cx,
 8376        )?;
 8377        Ok(())
 8378    }
 8379
 8380    pub fn merge_diagnostic_entries<'a>(
 8381        &mut self,
 8382        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8383        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8384        cx: &mut Context<Self>,
 8385    ) -> anyhow::Result<()> {
 8386        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8387        let mut updated_diagnostics_paths = HashMap::default();
 8388        for mut update in diagnostic_updates {
 8389            let abs_path = &update.diagnostics.document_abs_path;
 8390            let server_id = update.server_id;
 8391            let Some((worktree, relative_path)) =
 8392                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8393            else {
 8394                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8395                return Ok(());
 8396            };
 8397
 8398            let worktree_id = worktree.read(cx).id();
 8399            let project_path = ProjectPath {
 8400                worktree_id,
 8401                path: relative_path,
 8402            };
 8403
 8404            let document_uri = lsp::Uri::from_file_path(abs_path)
 8405                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8406            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8407                let snapshot = buffer_handle.read(cx).snapshot();
 8408                let buffer = buffer_handle.read(cx);
 8409                let reused_diagnostics = buffer
 8410                    .buffer_diagnostics(Some(server_id))
 8411                    .iter()
 8412                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8413                    .map(|v| {
 8414                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8415                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8416                        DiagnosticEntry {
 8417                            range: start..end,
 8418                            diagnostic: v.diagnostic.clone(),
 8419                        }
 8420                    })
 8421                    .collect::<Vec<_>>();
 8422
 8423                self.as_local_mut()
 8424                    .context("cannot merge diagnostics on a remote LspStore")?
 8425                    .update_buffer_diagnostics(
 8426                        &buffer_handle,
 8427                        server_id,
 8428                        Some(update.registration_id),
 8429                        update.result_id,
 8430                        update.diagnostics.version,
 8431                        update.diagnostics.diagnostics.clone(),
 8432                        reused_diagnostics.clone(),
 8433                        cx,
 8434                    )?;
 8435
 8436                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8437            } else if let Some(local) = self.as_local() {
 8438                let reused_diagnostics = local
 8439                    .diagnostics
 8440                    .get(&worktree_id)
 8441                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8442                    .and_then(|diagnostics_by_server_id| {
 8443                        diagnostics_by_server_id
 8444                            .binary_search_by_key(&server_id, |e| e.0)
 8445                            .ok()
 8446                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8447                    })
 8448                    .into_iter()
 8449                    .flatten()
 8450                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8451
 8452                update
 8453                    .diagnostics
 8454                    .diagnostics
 8455                    .extend(reused_diagnostics.cloned());
 8456            }
 8457
 8458            let updated = worktree.update(cx, |worktree, cx| {
 8459                self.update_worktree_diagnostics(
 8460                    worktree.id(),
 8461                    server_id,
 8462                    project_path.path.clone(),
 8463                    update.diagnostics.diagnostics,
 8464                    cx,
 8465                )
 8466            })?;
 8467            match updated {
 8468                ControlFlow::Continue(new_summary) => {
 8469                    if let Some((project_id, new_summary)) = new_summary {
 8470                        match &mut diagnostics_summary {
 8471                            Some(diagnostics_summary) => {
 8472                                diagnostics_summary
 8473                                    .more_summaries
 8474                                    .push(proto::DiagnosticSummary {
 8475                                        path: project_path.path.as_ref().to_proto(),
 8476                                        language_server_id: server_id.0 as u64,
 8477                                        error_count: new_summary.error_count,
 8478                                        warning_count: new_summary.warning_count,
 8479                                    })
 8480                            }
 8481                            None => {
 8482                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8483                                    project_id,
 8484                                    worktree_id: worktree_id.to_proto(),
 8485                                    summary: Some(proto::DiagnosticSummary {
 8486                                        path: project_path.path.as_ref().to_proto(),
 8487                                        language_server_id: server_id.0 as u64,
 8488                                        error_count: new_summary.error_count,
 8489                                        warning_count: new_summary.warning_count,
 8490                                    }),
 8491                                    more_summaries: Vec::new(),
 8492                                })
 8493                            }
 8494                        }
 8495                    }
 8496                    updated_diagnostics_paths
 8497                        .entry(server_id)
 8498                        .or_insert_with(Vec::new)
 8499                        .push(project_path);
 8500                }
 8501                ControlFlow::Break(()) => {}
 8502            }
 8503        }
 8504
 8505        if let Some((diagnostics_summary, (downstream_client, _))) =
 8506            diagnostics_summary.zip(self.downstream_client.as_ref())
 8507        {
 8508            downstream_client.send(diagnostics_summary).log_err();
 8509        }
 8510        for (server_id, paths) in updated_diagnostics_paths {
 8511            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8512        }
 8513        Ok(())
 8514    }
 8515
 8516    fn update_worktree_diagnostics(
 8517        &mut self,
 8518        worktree_id: WorktreeId,
 8519        server_id: LanguageServerId,
 8520        path_in_worktree: Arc<RelPath>,
 8521        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8522        _: &mut Context<Worktree>,
 8523    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8524        let local = match &mut self.mode {
 8525            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8526            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8527        };
 8528
 8529        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8530        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8531        let summaries_by_server_id = summaries_for_tree
 8532            .entry(path_in_worktree.clone())
 8533            .or_default();
 8534
 8535        let old_summary = summaries_by_server_id
 8536            .remove(&server_id)
 8537            .unwrap_or_default();
 8538
 8539        let new_summary = DiagnosticSummary::new(&diagnostics);
 8540        if diagnostics.is_empty() {
 8541            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8542            {
 8543                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8544                    diagnostics_by_server_id.remove(ix);
 8545                }
 8546                if diagnostics_by_server_id.is_empty() {
 8547                    diagnostics_for_tree.remove(&path_in_worktree);
 8548                }
 8549            }
 8550        } else {
 8551            summaries_by_server_id.insert(server_id, new_summary);
 8552            let diagnostics_by_server_id = diagnostics_for_tree
 8553                .entry(path_in_worktree.clone())
 8554                .or_default();
 8555            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8556                Ok(ix) => {
 8557                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8558                }
 8559                Err(ix) => {
 8560                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8561                }
 8562            }
 8563        }
 8564
 8565        if !old_summary.is_empty() || !new_summary.is_empty() {
 8566            if let Some((_, project_id)) = &self.downstream_client {
 8567                Ok(ControlFlow::Continue(Some((
 8568                    *project_id,
 8569                    proto::DiagnosticSummary {
 8570                        path: path_in_worktree.to_proto(),
 8571                        language_server_id: server_id.0 as u64,
 8572                        error_count: new_summary.error_count as u32,
 8573                        warning_count: new_summary.warning_count as u32,
 8574                    },
 8575                ))))
 8576            } else {
 8577                Ok(ControlFlow::Continue(None))
 8578            }
 8579        } else {
 8580            Ok(ControlFlow::Break(()))
 8581        }
 8582    }
 8583
 8584    pub fn open_buffer_for_symbol(
 8585        &mut self,
 8586        symbol: &Symbol,
 8587        cx: &mut Context<Self>,
 8588    ) -> Task<Result<Entity<Buffer>>> {
 8589        if let Some((client, project_id)) = self.upstream_client() {
 8590            let request = client.request(proto::OpenBufferForSymbol {
 8591                project_id,
 8592                symbol: Some(Self::serialize_symbol(symbol)),
 8593            });
 8594            cx.spawn(async move |this, cx| {
 8595                let response = request.await?;
 8596                let buffer_id = BufferId::new(response.buffer_id)?;
 8597                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8598                    .await
 8599            })
 8600        } else if let Some(local) = self.as_local() {
 8601            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8602                seed.worktree_id == symbol.source_worktree_id
 8603                    && state.id == symbol.source_language_server_id
 8604                    && symbol.language_server_name == seed.name
 8605            });
 8606            if !is_valid {
 8607                return Task::ready(Err(anyhow!(
 8608                    "language server for worktree and language not found"
 8609                )));
 8610            };
 8611
 8612            let symbol_abs_path = match &symbol.path {
 8613                SymbolLocation::InProject(project_path) => self
 8614                    .worktree_store
 8615                    .read(cx)
 8616                    .absolutize(&project_path, cx)
 8617                    .context("no such worktree"),
 8618                SymbolLocation::OutsideProject {
 8619                    abs_path,
 8620                    signature: _,
 8621                } => Ok(abs_path.to_path_buf()),
 8622            };
 8623            let symbol_abs_path = match symbol_abs_path {
 8624                Ok(abs_path) => abs_path,
 8625                Err(err) => return Task::ready(Err(err)),
 8626            };
 8627            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8628                uri
 8629            } else {
 8630                return Task::ready(Err(anyhow!("invalid symbol path")));
 8631            };
 8632
 8633            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8634        } else {
 8635            Task::ready(Err(anyhow!("no upstream client or local store")))
 8636        }
 8637    }
 8638
 8639    pub(crate) fn open_local_buffer_via_lsp(
 8640        &mut self,
 8641        abs_path: lsp::Uri,
 8642        language_server_id: LanguageServerId,
 8643        cx: &mut Context<Self>,
 8644    ) -> Task<Result<Entity<Buffer>>> {
 8645        cx.spawn(async move |lsp_store, cx| {
 8646            // Escape percent-encoded string.
 8647            let current_scheme = abs_path.scheme().to_owned();
 8648            // Uri is immutable, so we can't modify the scheme
 8649
 8650            let abs_path = abs_path
 8651                .to_file_path()
 8652                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8653            let p = abs_path.clone();
 8654            let yarn_worktree = lsp_store
 8655                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8656                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8657                        cx.spawn(async move |this, cx| {
 8658                            let t = this
 8659                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8660                                .ok()?;
 8661                            t.await
 8662                        })
 8663                    }),
 8664                    None => Task::ready(None),
 8665                })?
 8666                .await;
 8667            let (worktree_root_target, known_relative_path) =
 8668                if let Some((zip_root, relative_path)) = yarn_worktree {
 8669                    (zip_root, Some(relative_path))
 8670                } else {
 8671                    (Arc::<Path>::from(abs_path.as_path()), None)
 8672                };
 8673            let (worktree, relative_path) = if let Some(result) =
 8674                lsp_store.update(cx, |lsp_store, cx| {
 8675                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8676                        worktree_store.find_worktree(&worktree_root_target, cx)
 8677                    })
 8678                })? {
 8679                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8680                (result.0, relative_path)
 8681            } else {
 8682                let worktree = lsp_store
 8683                    .update(cx, |lsp_store, cx| {
 8684                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8685                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8686                        })
 8687                    })?
 8688                    .await?;
 8689                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8690                    lsp_store
 8691                        .update(cx, |lsp_store, cx| {
 8692                            if let Some(local) = lsp_store.as_local_mut() {
 8693                                local.register_language_server_for_invisible_worktree(
 8694                                    &worktree,
 8695                                    language_server_id,
 8696                                    cx,
 8697                                )
 8698                            }
 8699                        })
 8700                        .ok();
 8701                }
 8702                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8703                let relative_path = if let Some(known_path) = known_relative_path {
 8704                    known_path
 8705                } else {
 8706                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8707                        .into_arc()
 8708                };
 8709                (worktree, relative_path)
 8710            };
 8711            let project_path = ProjectPath {
 8712                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8713                path: relative_path,
 8714            };
 8715            lsp_store
 8716                .update(cx, |lsp_store, cx| {
 8717                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8718                        buffer_store.open_buffer(project_path, cx)
 8719                    })
 8720                })?
 8721                .await
 8722        })
 8723    }
 8724
 8725    fn request_multiple_lsp_locally<P, R>(
 8726        &mut self,
 8727        buffer: &Entity<Buffer>,
 8728        position: Option<P>,
 8729        request: R,
 8730        cx: &mut Context<Self>,
 8731    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8732    where
 8733        P: ToOffset,
 8734        R: LspCommand + Clone,
 8735        <R::LspRequest as lsp::request::Request>::Result: Send,
 8736        <R::LspRequest as lsp::request::Request>::Params: Send,
 8737    {
 8738        let Some(local) = self.as_local() else {
 8739            return Task::ready(Vec::new());
 8740        };
 8741
 8742        let snapshot = buffer.read(cx).snapshot();
 8743        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8744
 8745        let server_ids = buffer.update(cx, |buffer, cx| {
 8746            local
 8747                .language_servers_for_buffer(buffer, cx)
 8748                .filter(|(adapter, _)| {
 8749                    scope
 8750                        .as_ref()
 8751                        .map(|scope| scope.language_allowed(&adapter.name))
 8752                        .unwrap_or(true)
 8753                })
 8754                .map(|(_, server)| server.server_id())
 8755                .filter(|server_id| {
 8756                    self.as_local().is_none_or(|local| {
 8757                        local
 8758                            .buffers_opened_in_servers
 8759                            .get(&snapshot.remote_id())
 8760                            .is_some_and(|servers| servers.contains(server_id))
 8761                    })
 8762                })
 8763                .collect::<Vec<_>>()
 8764        });
 8765
 8766        let mut response_results = server_ids
 8767            .into_iter()
 8768            .map(|server_id| {
 8769                let task = self.request_lsp(
 8770                    buffer.clone(),
 8771                    LanguageServerToQuery::Other(server_id),
 8772                    request.clone(),
 8773                    cx,
 8774                );
 8775                async move { (server_id, task.await) }
 8776            })
 8777            .collect::<FuturesUnordered<_>>();
 8778
 8779        cx.background_spawn(async move {
 8780            let mut responses = Vec::with_capacity(response_results.len());
 8781            while let Some((server_id, response_result)) = response_results.next().await {
 8782                match response_result {
 8783                    Ok(response) => responses.push((server_id, response)),
 8784                    // rust-analyzer likes to error with this when its still loading up
 8785                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8786                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8787                }
 8788            }
 8789            responses
 8790        })
 8791    }
 8792
 8793    async fn handle_lsp_get_completions(
 8794        this: Entity<Self>,
 8795        envelope: TypedEnvelope<proto::GetCompletions>,
 8796        mut cx: AsyncApp,
 8797    ) -> Result<proto::GetCompletionsResponse> {
 8798        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8799
 8800        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8801        let buffer_handle = this.update(&mut cx, |this, cx| {
 8802            this.buffer_store.read(cx).get_existing(buffer_id)
 8803        })??;
 8804        let request = GetCompletions::from_proto(
 8805            envelope.payload,
 8806            this.clone(),
 8807            buffer_handle.clone(),
 8808            cx.clone(),
 8809        )
 8810        .await?;
 8811
 8812        let server_to_query = match request.server_id {
 8813            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8814            None => LanguageServerToQuery::FirstCapable,
 8815        };
 8816
 8817        let response = this
 8818            .update(&mut cx, |this, cx| {
 8819                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8820            })?
 8821            .await?;
 8822        this.update(&mut cx, |this, cx| {
 8823            Ok(GetCompletions::response_to_proto(
 8824                response,
 8825                this,
 8826                sender_id,
 8827                &buffer_handle.read(cx).version(),
 8828                cx,
 8829            ))
 8830        })?
 8831    }
 8832
 8833    async fn handle_lsp_command<T: LspCommand>(
 8834        this: Entity<Self>,
 8835        envelope: TypedEnvelope<T::ProtoRequest>,
 8836        mut cx: AsyncApp,
 8837    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8838    where
 8839        <T::LspRequest as lsp::request::Request>::Params: Send,
 8840        <T::LspRequest as lsp::request::Request>::Result: Send,
 8841    {
 8842        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8843        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8844        let buffer_handle = this.update(&mut cx, |this, cx| {
 8845            this.buffer_store.read(cx).get_existing(buffer_id)
 8846        })??;
 8847        let request = T::from_proto(
 8848            envelope.payload,
 8849            this.clone(),
 8850            buffer_handle.clone(),
 8851            cx.clone(),
 8852        )
 8853        .await?;
 8854        let response = this
 8855            .update(&mut cx, |this, cx| {
 8856                this.request_lsp(
 8857                    buffer_handle.clone(),
 8858                    LanguageServerToQuery::FirstCapable,
 8859                    request,
 8860                    cx,
 8861                )
 8862            })?
 8863            .await?;
 8864        this.update(&mut cx, |this, cx| {
 8865            Ok(T::response_to_proto(
 8866                response,
 8867                this,
 8868                sender_id,
 8869                &buffer_handle.read(cx).version(),
 8870                cx,
 8871            ))
 8872        })?
 8873    }
 8874
 8875    async fn handle_lsp_query(
 8876        lsp_store: Entity<Self>,
 8877        envelope: TypedEnvelope<proto::LspQuery>,
 8878        mut cx: AsyncApp,
 8879    ) -> Result<proto::Ack> {
 8880        use proto::lsp_query::Request;
 8881        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8882        let lsp_query = envelope.payload;
 8883        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8884        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8885        match lsp_query.request.context("invalid LSP query request")? {
 8886            Request::GetReferences(get_references) => {
 8887                let position = get_references.position.clone().and_then(deserialize_anchor);
 8888                Self::query_lsp_locally::<GetReferences>(
 8889                    lsp_store,
 8890                    server_id,
 8891                    sender_id,
 8892                    lsp_request_id,
 8893                    get_references,
 8894                    position,
 8895                    &mut cx,
 8896                )
 8897                .await?;
 8898            }
 8899            Request::GetDocumentColor(get_document_color) => {
 8900                Self::query_lsp_locally::<GetDocumentColor>(
 8901                    lsp_store,
 8902                    server_id,
 8903                    sender_id,
 8904                    lsp_request_id,
 8905                    get_document_color,
 8906                    None,
 8907                    &mut cx,
 8908                )
 8909                .await?;
 8910            }
 8911            Request::GetHover(get_hover) => {
 8912                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8913                Self::query_lsp_locally::<GetHover>(
 8914                    lsp_store,
 8915                    server_id,
 8916                    sender_id,
 8917                    lsp_request_id,
 8918                    get_hover,
 8919                    position,
 8920                    &mut cx,
 8921                )
 8922                .await?;
 8923            }
 8924            Request::GetCodeActions(get_code_actions) => {
 8925                Self::query_lsp_locally::<GetCodeActions>(
 8926                    lsp_store,
 8927                    server_id,
 8928                    sender_id,
 8929                    lsp_request_id,
 8930                    get_code_actions,
 8931                    None,
 8932                    &mut cx,
 8933                )
 8934                .await?;
 8935            }
 8936            Request::GetSignatureHelp(get_signature_help) => {
 8937                let position = get_signature_help
 8938                    .position
 8939                    .clone()
 8940                    .and_then(deserialize_anchor);
 8941                Self::query_lsp_locally::<GetSignatureHelp>(
 8942                    lsp_store,
 8943                    server_id,
 8944                    sender_id,
 8945                    lsp_request_id,
 8946                    get_signature_help,
 8947                    position,
 8948                    &mut cx,
 8949                )
 8950                .await?;
 8951            }
 8952            Request::GetCodeLens(get_code_lens) => {
 8953                Self::query_lsp_locally::<GetCodeLens>(
 8954                    lsp_store,
 8955                    server_id,
 8956                    sender_id,
 8957                    lsp_request_id,
 8958                    get_code_lens,
 8959                    None,
 8960                    &mut cx,
 8961                )
 8962                .await?;
 8963            }
 8964            Request::GetDefinition(get_definition) => {
 8965                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8966                Self::query_lsp_locally::<GetDefinitions>(
 8967                    lsp_store,
 8968                    server_id,
 8969                    sender_id,
 8970                    lsp_request_id,
 8971                    get_definition,
 8972                    position,
 8973                    &mut cx,
 8974                )
 8975                .await?;
 8976            }
 8977            Request::GetDeclaration(get_declaration) => {
 8978                let position = get_declaration
 8979                    .position
 8980                    .clone()
 8981                    .and_then(deserialize_anchor);
 8982                Self::query_lsp_locally::<GetDeclarations>(
 8983                    lsp_store,
 8984                    server_id,
 8985                    sender_id,
 8986                    lsp_request_id,
 8987                    get_declaration,
 8988                    position,
 8989                    &mut cx,
 8990                )
 8991                .await?;
 8992            }
 8993            Request::GetTypeDefinition(get_type_definition) => {
 8994                let position = get_type_definition
 8995                    .position
 8996                    .clone()
 8997                    .and_then(deserialize_anchor);
 8998                Self::query_lsp_locally::<GetTypeDefinitions>(
 8999                    lsp_store,
 9000                    server_id,
 9001                    sender_id,
 9002                    lsp_request_id,
 9003                    get_type_definition,
 9004                    position,
 9005                    &mut cx,
 9006                )
 9007                .await?;
 9008            }
 9009            Request::GetImplementation(get_implementation) => {
 9010                let position = get_implementation
 9011                    .position
 9012                    .clone()
 9013                    .and_then(deserialize_anchor);
 9014                Self::query_lsp_locally::<GetImplementations>(
 9015                    lsp_store,
 9016                    server_id,
 9017                    sender_id,
 9018                    lsp_request_id,
 9019                    get_implementation,
 9020                    position,
 9021                    &mut cx,
 9022                )
 9023                .await?;
 9024            }
 9025            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9026                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 9027                let version = deserialize_version(get_document_diagnostics.buffer_version());
 9028                let buffer = lsp_store.update(&mut cx, |this, cx| {
 9029                    this.buffer_store.read(cx).get_existing(buffer_id)
 9030                })??;
 9031                buffer
 9032                    .update(&mut cx, |buffer, _| {
 9033                        buffer.wait_for_version(version.clone())
 9034                    })?
 9035                    .await?;
 9036                lsp_store.update(&mut cx, |lsp_store, cx| {
 9037                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9038                    let key = LspKey {
 9039                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9040                        server_queried: server_id,
 9041                    };
 9042                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9043                    ) {
 9044                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9045                            lsp_requests.clear();
 9046                        };
 9047                    }
 9048
 9049                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 9050                    existing_queries.insert(
 9051                        lsp_request_id,
 9052                        cx.spawn(async move |lsp_store, cx| {
 9053                            let diagnostics_pull = lsp_store
 9054                                .update(cx, |lsp_store, cx| {
 9055                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9056                                })
 9057                                .ok();
 9058                            if let Some(diagnostics_pull) = diagnostics_pull {
 9059                                match diagnostics_pull.await {
 9060                                    Ok(()) => {}
 9061                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9062                                };
 9063                            }
 9064                        }),
 9065                    );
 9066                })?;
 9067            }
 9068            Request::InlayHints(inlay_hints) => {
 9069                let query_start = inlay_hints
 9070                    .start
 9071                    .clone()
 9072                    .and_then(deserialize_anchor)
 9073                    .context("invalid inlay hints range start")?;
 9074                let query_end = inlay_hints
 9075                    .end
 9076                    .clone()
 9077                    .and_then(deserialize_anchor)
 9078                    .context("invalid inlay hints range end")?;
 9079                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9080                    &lsp_store,
 9081                    server_id,
 9082                    lsp_request_id,
 9083                    &inlay_hints,
 9084                    query_start..query_end,
 9085                    &mut cx,
 9086                )
 9087                .await
 9088                .context("preparing inlay hints request")?;
 9089                Self::query_lsp_locally::<InlayHints>(
 9090                    lsp_store,
 9091                    server_id,
 9092                    sender_id,
 9093                    lsp_request_id,
 9094                    inlay_hints,
 9095                    None,
 9096                    &mut cx,
 9097                )
 9098                .await
 9099                .context("querying for inlay hints")?
 9100            }
 9101        }
 9102        Ok(proto::Ack {})
 9103    }
 9104
 9105    async fn handle_lsp_query_response(
 9106        lsp_store: Entity<Self>,
 9107        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9108        cx: AsyncApp,
 9109    ) -> Result<()> {
 9110        lsp_store.read_with(&cx, |lsp_store, _| {
 9111            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9112                upstream_client.handle_lsp_response(envelope.clone());
 9113            }
 9114        })?;
 9115        Ok(())
 9116    }
 9117
 9118    async fn handle_apply_code_action(
 9119        this: Entity<Self>,
 9120        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9121        mut cx: AsyncApp,
 9122    ) -> Result<proto::ApplyCodeActionResponse> {
 9123        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9124        let action =
 9125            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9126        let apply_code_action = this.update(&mut cx, |this, cx| {
 9127            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9128            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9129            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9130        })??;
 9131
 9132        let project_transaction = apply_code_action.await?;
 9133        let project_transaction = this.update(&mut cx, |this, cx| {
 9134            this.buffer_store.update(cx, |buffer_store, cx| {
 9135                buffer_store.serialize_project_transaction_for_peer(
 9136                    project_transaction,
 9137                    sender_id,
 9138                    cx,
 9139                )
 9140            })
 9141        })?;
 9142        Ok(proto::ApplyCodeActionResponse {
 9143            transaction: Some(project_transaction),
 9144        })
 9145    }
 9146
 9147    async fn handle_register_buffer_with_language_servers(
 9148        this: Entity<Self>,
 9149        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9150        mut cx: AsyncApp,
 9151    ) -> Result<proto::Ack> {
 9152        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9153        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9154        this.update(&mut cx, |this, cx| {
 9155            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9156                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9157                    project_id: upstream_project_id,
 9158                    buffer_id: buffer_id.to_proto(),
 9159                    only_servers: envelope.payload.only_servers,
 9160                });
 9161            }
 9162
 9163            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9164                anyhow::bail!("buffer is not open");
 9165            };
 9166
 9167            let handle = this.register_buffer_with_language_servers(
 9168                &buffer,
 9169                envelope
 9170                    .payload
 9171                    .only_servers
 9172                    .into_iter()
 9173                    .filter_map(|selector| {
 9174                        Some(match selector.selector? {
 9175                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9176                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9177                            }
 9178                            proto::language_server_selector::Selector::Name(name) => {
 9179                                LanguageServerSelector::Name(LanguageServerName(
 9180                                    SharedString::from(name),
 9181                                ))
 9182                            }
 9183                        })
 9184                    })
 9185                    .collect(),
 9186                false,
 9187                cx,
 9188            );
 9189            this.buffer_store().update(cx, |buffer_store, _| {
 9190                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9191            });
 9192
 9193            Ok(())
 9194        })??;
 9195        Ok(proto::Ack {})
 9196    }
 9197
 9198    async fn handle_rename_project_entry(
 9199        this: Entity<Self>,
 9200        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9201        mut cx: AsyncApp,
 9202    ) -> Result<proto::ProjectEntryResponse> {
 9203        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9204        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9205        let new_path =
 9206            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9207
 9208        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9209            .update(&mut cx, |this, cx| {
 9210                let (worktree, entry) = this
 9211                    .worktree_store
 9212                    .read(cx)
 9213                    .worktree_and_entry_for_id(entry_id, cx)?;
 9214                let new_worktree = this
 9215                    .worktree_store
 9216                    .read(cx)
 9217                    .worktree_for_id(new_worktree_id, cx)?;
 9218                Some((
 9219                    this.worktree_store.clone(),
 9220                    worktree,
 9221                    new_worktree,
 9222                    entry.clone(),
 9223                ))
 9224            })?
 9225            .context("worktree not found")?;
 9226        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9227            (worktree.absolutize(&old_entry.path), worktree.id())
 9228        })?;
 9229        let new_abs_path =
 9230            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 9231
 9232        let _transaction = Self::will_rename_entry(
 9233            this.downgrade(),
 9234            old_worktree_id,
 9235            &old_abs_path,
 9236            &new_abs_path,
 9237            old_entry.is_dir(),
 9238            cx.clone(),
 9239        )
 9240        .await;
 9241        let response = WorktreeStore::handle_rename_project_entry(
 9242            worktree_store,
 9243            envelope.payload,
 9244            cx.clone(),
 9245        )
 9246        .await;
 9247        this.read_with(&cx, |this, _| {
 9248            this.did_rename_entry(
 9249                old_worktree_id,
 9250                &old_abs_path,
 9251                &new_abs_path,
 9252                old_entry.is_dir(),
 9253            );
 9254        })
 9255        .ok();
 9256        response
 9257    }
 9258
 9259    async fn handle_update_diagnostic_summary(
 9260        this: Entity<Self>,
 9261        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9262        mut cx: AsyncApp,
 9263    ) -> Result<()> {
 9264        this.update(&mut cx, |lsp_store, cx| {
 9265            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9266            let mut updated_diagnostics_paths = HashMap::default();
 9267            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9268            for message_summary in envelope
 9269                .payload
 9270                .summary
 9271                .into_iter()
 9272                .chain(envelope.payload.more_summaries)
 9273            {
 9274                let project_path = ProjectPath {
 9275                    worktree_id,
 9276                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9277                };
 9278                let path = project_path.path.clone();
 9279                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9280                let summary = DiagnosticSummary {
 9281                    error_count: message_summary.error_count as usize,
 9282                    warning_count: message_summary.warning_count as usize,
 9283                };
 9284
 9285                if summary.is_empty() {
 9286                    if let Some(worktree_summaries) =
 9287                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9288                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9289                    {
 9290                        summaries.remove(&server_id);
 9291                        if summaries.is_empty() {
 9292                            worktree_summaries.remove(&path);
 9293                        }
 9294                    }
 9295                } else {
 9296                    lsp_store
 9297                        .diagnostic_summaries
 9298                        .entry(worktree_id)
 9299                        .or_default()
 9300                        .entry(path)
 9301                        .or_default()
 9302                        .insert(server_id, summary);
 9303                }
 9304
 9305                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9306                    match &mut diagnostics_summary {
 9307                        Some(diagnostics_summary) => {
 9308                            diagnostics_summary
 9309                                .more_summaries
 9310                                .push(proto::DiagnosticSummary {
 9311                                    path: project_path.path.as_ref().to_proto(),
 9312                                    language_server_id: server_id.0 as u64,
 9313                                    error_count: summary.error_count as u32,
 9314                                    warning_count: summary.warning_count as u32,
 9315                                })
 9316                        }
 9317                        None => {
 9318                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9319                                project_id: *project_id,
 9320                                worktree_id: worktree_id.to_proto(),
 9321                                summary: Some(proto::DiagnosticSummary {
 9322                                    path: project_path.path.as_ref().to_proto(),
 9323                                    language_server_id: server_id.0 as u64,
 9324                                    error_count: summary.error_count as u32,
 9325                                    warning_count: summary.warning_count as u32,
 9326                                }),
 9327                                more_summaries: Vec::new(),
 9328                            })
 9329                        }
 9330                    }
 9331                }
 9332                updated_diagnostics_paths
 9333                    .entry(server_id)
 9334                    .or_insert_with(Vec::new)
 9335                    .push(project_path);
 9336            }
 9337
 9338            if let Some((diagnostics_summary, (downstream_client, _))) =
 9339                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9340            {
 9341                downstream_client.send(diagnostics_summary).log_err();
 9342            }
 9343            for (server_id, paths) in updated_diagnostics_paths {
 9344                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9345            }
 9346            Ok(())
 9347        })?
 9348    }
 9349
 9350    async fn handle_start_language_server(
 9351        lsp_store: Entity<Self>,
 9352        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9353        mut cx: AsyncApp,
 9354    ) -> Result<()> {
 9355        let server = envelope.payload.server.context("invalid server")?;
 9356        let server_capabilities =
 9357            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9358                .with_context(|| {
 9359                    format!(
 9360                        "incorrect server capabilities {}",
 9361                        envelope.payload.capabilities
 9362                    )
 9363                })?;
 9364        lsp_store.update(&mut cx, |lsp_store, cx| {
 9365            let server_id = LanguageServerId(server.id as usize);
 9366            let server_name = LanguageServerName::from_proto(server.name.clone());
 9367            lsp_store
 9368                .lsp_server_capabilities
 9369                .insert(server_id, server_capabilities);
 9370            lsp_store.language_server_statuses.insert(
 9371                server_id,
 9372                LanguageServerStatus {
 9373                    name: server_name.clone(),
 9374                    pending_work: Default::default(),
 9375                    has_pending_diagnostic_updates: false,
 9376                    progress_tokens: Default::default(),
 9377                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9378                    binary: None,
 9379                    configuration: None,
 9380                    workspace_folders: BTreeSet::new(),
 9381                },
 9382            );
 9383            cx.emit(LspStoreEvent::LanguageServerAdded(
 9384                server_id,
 9385                server_name,
 9386                server.worktree_id.map(WorktreeId::from_proto),
 9387            ));
 9388            cx.notify();
 9389        })?;
 9390        Ok(())
 9391    }
 9392
 9393    async fn handle_update_language_server(
 9394        lsp_store: Entity<Self>,
 9395        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9396        mut cx: AsyncApp,
 9397    ) -> Result<()> {
 9398        lsp_store.update(&mut cx, |lsp_store, cx| {
 9399            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9400
 9401            match envelope.payload.variant.context("invalid variant")? {
 9402                proto::update_language_server::Variant::WorkStart(payload) => {
 9403                    lsp_store.on_lsp_work_start(
 9404                        language_server_id,
 9405                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9406                            .context("invalid progress token value")?,
 9407                        LanguageServerProgress {
 9408                            title: payload.title,
 9409                            is_disk_based_diagnostics_progress: false,
 9410                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9411                            message: payload.message,
 9412                            percentage: payload.percentage.map(|p| p as usize),
 9413                            last_update_at: cx.background_executor().now(),
 9414                        },
 9415                        cx,
 9416                    );
 9417                }
 9418                proto::update_language_server::Variant::WorkProgress(payload) => {
 9419                    lsp_store.on_lsp_work_progress(
 9420                        language_server_id,
 9421                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9422                            .context("invalid progress token value")?,
 9423                        LanguageServerProgress {
 9424                            title: None,
 9425                            is_disk_based_diagnostics_progress: false,
 9426                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9427                            message: payload.message,
 9428                            percentage: payload.percentage.map(|p| p as usize),
 9429                            last_update_at: cx.background_executor().now(),
 9430                        },
 9431                        cx,
 9432                    );
 9433                }
 9434
 9435                proto::update_language_server::Variant::WorkEnd(payload) => {
 9436                    lsp_store.on_lsp_work_end(
 9437                        language_server_id,
 9438                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9439                            .context("invalid progress token value")?,
 9440                        cx,
 9441                    );
 9442                }
 9443
 9444                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9445                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9446                }
 9447
 9448                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9449                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9450                }
 9451
 9452                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9453                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9454                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9455                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9456                        language_server_id,
 9457                        name: envelope
 9458                            .payload
 9459                            .server_name
 9460                            .map(SharedString::new)
 9461                            .map(LanguageServerName),
 9462                        message: non_lsp,
 9463                    });
 9464                }
 9465            }
 9466
 9467            Ok(())
 9468        })?
 9469    }
 9470
 9471    async fn handle_language_server_log(
 9472        this: Entity<Self>,
 9473        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9474        mut cx: AsyncApp,
 9475    ) -> Result<()> {
 9476        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9477        let log_type = envelope
 9478            .payload
 9479            .log_type
 9480            .map(LanguageServerLogType::from_proto)
 9481            .context("invalid language server log type")?;
 9482
 9483        let message = envelope.payload.message;
 9484
 9485        this.update(&mut cx, |_, cx| {
 9486            cx.emit(LspStoreEvent::LanguageServerLog(
 9487                language_server_id,
 9488                log_type,
 9489                message,
 9490            ));
 9491        })
 9492    }
 9493
 9494    async fn handle_lsp_ext_cancel_flycheck(
 9495        lsp_store: Entity<Self>,
 9496        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9497        cx: AsyncApp,
 9498    ) -> Result<proto::Ack> {
 9499        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9500        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9501            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9502                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9503            } else {
 9504                None
 9505            }
 9506        })?;
 9507        if let Some(task) = task {
 9508            task.context("handling lsp ext cancel flycheck")?;
 9509        }
 9510
 9511        Ok(proto::Ack {})
 9512    }
 9513
 9514    async fn handle_lsp_ext_run_flycheck(
 9515        lsp_store: Entity<Self>,
 9516        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9517        mut cx: AsyncApp,
 9518    ) -> Result<proto::Ack> {
 9519        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9520        lsp_store.update(&mut cx, |lsp_store, cx| {
 9521            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9522                let text_document = if envelope.payload.current_file_only {
 9523                    let buffer_id = envelope
 9524                        .payload
 9525                        .buffer_id
 9526                        .map(|id| BufferId::new(id))
 9527                        .transpose()?;
 9528                    buffer_id
 9529                        .and_then(|buffer_id| {
 9530                            lsp_store
 9531                                .buffer_store()
 9532                                .read(cx)
 9533                                .get(buffer_id)
 9534                                .and_then(|buffer| {
 9535                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9536                                })
 9537                                .map(|path| make_text_document_identifier(&path))
 9538                        })
 9539                        .transpose()?
 9540                } else {
 9541                    None
 9542                };
 9543                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9544                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9545                )?;
 9546            }
 9547            anyhow::Ok(())
 9548        })??;
 9549
 9550        Ok(proto::Ack {})
 9551    }
 9552
 9553    async fn handle_lsp_ext_clear_flycheck(
 9554        lsp_store: Entity<Self>,
 9555        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9556        cx: AsyncApp,
 9557    ) -> Result<proto::Ack> {
 9558        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9559        lsp_store
 9560            .read_with(&cx, |lsp_store, _| {
 9561                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9562                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9563                } else {
 9564                    None
 9565                }
 9566            })
 9567            .context("handling lsp ext clear flycheck")?;
 9568
 9569        Ok(proto::Ack {})
 9570    }
 9571
 9572    pub fn disk_based_diagnostics_started(
 9573        &mut self,
 9574        language_server_id: LanguageServerId,
 9575        cx: &mut Context<Self>,
 9576    ) {
 9577        if let Some(language_server_status) =
 9578            self.language_server_statuses.get_mut(&language_server_id)
 9579        {
 9580            language_server_status.has_pending_diagnostic_updates = true;
 9581        }
 9582
 9583        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9584        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9585            language_server_id,
 9586            name: self
 9587                .language_server_adapter_for_id(language_server_id)
 9588                .map(|adapter| adapter.name()),
 9589            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9590                Default::default(),
 9591            ),
 9592        })
 9593    }
 9594
 9595    pub fn disk_based_diagnostics_finished(
 9596        &mut self,
 9597        language_server_id: LanguageServerId,
 9598        cx: &mut Context<Self>,
 9599    ) {
 9600        if let Some(language_server_status) =
 9601            self.language_server_statuses.get_mut(&language_server_id)
 9602        {
 9603            language_server_status.has_pending_diagnostic_updates = false;
 9604        }
 9605
 9606        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9607        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9608            language_server_id,
 9609            name: self
 9610                .language_server_adapter_for_id(language_server_id)
 9611                .map(|adapter| adapter.name()),
 9612            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9613                Default::default(),
 9614            ),
 9615        })
 9616    }
 9617
 9618    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9619    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9620    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9621    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9622    // the language server might take some time to publish diagnostics.
 9623    fn simulate_disk_based_diagnostics_events_if_needed(
 9624        &mut self,
 9625        language_server_id: LanguageServerId,
 9626        cx: &mut Context<Self>,
 9627    ) {
 9628        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9629
 9630        let Some(LanguageServerState::Running {
 9631            simulate_disk_based_diagnostics_completion,
 9632            adapter,
 9633            ..
 9634        }) = self
 9635            .as_local_mut()
 9636            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9637        else {
 9638            return;
 9639        };
 9640
 9641        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9642            return;
 9643        }
 9644
 9645        let prev_task =
 9646            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9647                cx.background_executor()
 9648                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9649                    .await;
 9650
 9651                this.update(cx, |this, cx| {
 9652                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9653
 9654                    if let Some(LanguageServerState::Running {
 9655                        simulate_disk_based_diagnostics_completion,
 9656                        ..
 9657                    }) = this.as_local_mut().and_then(|local_store| {
 9658                        local_store.language_servers.get_mut(&language_server_id)
 9659                    }) {
 9660                        *simulate_disk_based_diagnostics_completion = None;
 9661                    }
 9662                })
 9663                .ok();
 9664            }));
 9665
 9666        if prev_task.is_none() {
 9667            self.disk_based_diagnostics_started(language_server_id, cx);
 9668        }
 9669    }
 9670
 9671    pub fn language_server_statuses(
 9672        &self,
 9673    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9674        self.language_server_statuses
 9675            .iter()
 9676            .map(|(key, value)| (*key, value))
 9677    }
 9678
 9679    pub(super) fn did_rename_entry(
 9680        &self,
 9681        worktree_id: WorktreeId,
 9682        old_path: &Path,
 9683        new_path: &Path,
 9684        is_dir: bool,
 9685    ) {
 9686        maybe!({
 9687            let local_store = self.as_local()?;
 9688
 9689            let old_uri = lsp::Uri::from_file_path(old_path)
 9690                .ok()
 9691                .map(|uri| uri.to_string())?;
 9692            let new_uri = lsp::Uri::from_file_path(new_path)
 9693                .ok()
 9694                .map(|uri| uri.to_string())?;
 9695
 9696            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9697                let Some(filter) = local_store
 9698                    .language_server_paths_watched_for_rename
 9699                    .get(&language_server.server_id())
 9700                else {
 9701                    continue;
 9702                };
 9703
 9704                if filter.should_send_did_rename(&old_uri, is_dir) {
 9705                    language_server
 9706                        .notify::<DidRenameFiles>(RenameFilesParams {
 9707                            files: vec![FileRename {
 9708                                old_uri: old_uri.clone(),
 9709                                new_uri: new_uri.clone(),
 9710                            }],
 9711                        })
 9712                        .ok();
 9713                }
 9714            }
 9715            Some(())
 9716        });
 9717    }
 9718
 9719    pub(super) fn will_rename_entry(
 9720        this: WeakEntity<Self>,
 9721        worktree_id: WorktreeId,
 9722        old_path: &Path,
 9723        new_path: &Path,
 9724        is_dir: bool,
 9725        cx: AsyncApp,
 9726    ) -> Task<ProjectTransaction> {
 9727        let old_uri = lsp::Uri::from_file_path(old_path)
 9728            .ok()
 9729            .map(|uri| uri.to_string());
 9730        let new_uri = lsp::Uri::from_file_path(new_path)
 9731            .ok()
 9732            .map(|uri| uri.to_string());
 9733        cx.spawn(async move |cx| {
 9734            let mut tasks = vec![];
 9735            this.update(cx, |this, cx| {
 9736                let local_store = this.as_local()?;
 9737                let old_uri = old_uri?;
 9738                let new_uri = new_uri?;
 9739                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9740                    let Some(filter) = local_store
 9741                        .language_server_paths_watched_for_rename
 9742                        .get(&language_server.server_id())
 9743                    else {
 9744                        continue;
 9745                    };
 9746
 9747                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9748                        let apply_edit = cx.spawn({
 9749                            let old_uri = old_uri.clone();
 9750                            let new_uri = new_uri.clone();
 9751                            let language_server = language_server.clone();
 9752                            async move |this, cx| {
 9753                                let edit = language_server
 9754                                    .request::<WillRenameFiles>(RenameFilesParams {
 9755                                        files: vec![FileRename { old_uri, new_uri }],
 9756                                    })
 9757                                    .await
 9758                                    .into_response()
 9759                                    .context("will rename files")
 9760                                    .log_err()
 9761                                    .flatten()?;
 9762
 9763                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9764                                    this.upgrade()?,
 9765                                    edit,
 9766                                    false,
 9767                                    language_server.clone(),
 9768                                    cx,
 9769                                )
 9770                                .await
 9771                                .ok()?;
 9772                                Some(transaction)
 9773                            }
 9774                        });
 9775                        tasks.push(apply_edit);
 9776                    }
 9777                }
 9778                Some(())
 9779            })
 9780            .ok()
 9781            .flatten();
 9782            let mut merged_transaction = ProjectTransaction::default();
 9783            for task in tasks {
 9784                // Await on tasks sequentially so that the order of application of edits is deterministic
 9785                // (at least with regards to the order of registration of language servers)
 9786                if let Some(transaction) = task.await {
 9787                    for (buffer, buffer_transaction) in transaction.0 {
 9788                        merged_transaction.0.insert(buffer, buffer_transaction);
 9789                    }
 9790                }
 9791            }
 9792            merged_transaction
 9793        })
 9794    }
 9795
 9796    fn lsp_notify_abs_paths_changed(
 9797        &mut self,
 9798        server_id: LanguageServerId,
 9799        changes: Vec<PathEvent>,
 9800    ) {
 9801        maybe!({
 9802            let server = self.language_server_for_id(server_id)?;
 9803            let changes = changes
 9804                .into_iter()
 9805                .filter_map(|event| {
 9806                    let typ = match event.kind? {
 9807                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9808                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9809                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9810                    };
 9811                    Some(lsp::FileEvent {
 9812                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9813                        typ,
 9814                    })
 9815                })
 9816                .collect::<Vec<_>>();
 9817            if !changes.is_empty() {
 9818                server
 9819                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9820                        lsp::DidChangeWatchedFilesParams { changes },
 9821                    )
 9822                    .ok();
 9823            }
 9824            Some(())
 9825        });
 9826    }
 9827
 9828    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9829        self.as_local()?.language_server_for_id(id)
 9830    }
 9831
 9832    fn on_lsp_progress(
 9833        &mut self,
 9834        progress_params: lsp::ProgressParams,
 9835        language_server_id: LanguageServerId,
 9836        disk_based_diagnostics_progress_token: Option<String>,
 9837        cx: &mut Context<Self>,
 9838    ) {
 9839        match progress_params.value {
 9840            lsp::ProgressParamsValue::WorkDone(progress) => {
 9841                self.handle_work_done_progress(
 9842                    progress,
 9843                    language_server_id,
 9844                    disk_based_diagnostics_progress_token,
 9845                    ProgressToken::from_lsp(progress_params.token),
 9846                    cx,
 9847                );
 9848            }
 9849            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9850                let registration_id = match progress_params.token {
 9851                    lsp::NumberOrString::Number(_) => None,
 9852                    lsp::NumberOrString::String(token) => token
 9853                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9854                        .map(|(_, id)| id.to_owned()),
 9855                };
 9856                if let Some(LanguageServerState::Running {
 9857                    workspace_diagnostics_refresh_tasks,
 9858                    ..
 9859                }) = self
 9860                    .as_local_mut()
 9861                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9862                    && let Some(workspace_diagnostics) =
 9863                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9864                {
 9865                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9866                    self.apply_workspace_diagnostic_report(
 9867                        language_server_id,
 9868                        report,
 9869                        registration_id.map(SharedString::from),
 9870                        cx,
 9871                    )
 9872                }
 9873            }
 9874        }
 9875    }
 9876
 9877    fn handle_work_done_progress(
 9878        &mut self,
 9879        progress: lsp::WorkDoneProgress,
 9880        language_server_id: LanguageServerId,
 9881        disk_based_diagnostics_progress_token: Option<String>,
 9882        token: ProgressToken,
 9883        cx: &mut Context<Self>,
 9884    ) {
 9885        let language_server_status =
 9886            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9887                status
 9888            } else {
 9889                return;
 9890            };
 9891
 9892        if !language_server_status.progress_tokens.contains(&token) {
 9893            return;
 9894        }
 9895
 9896        let is_disk_based_diagnostics_progress =
 9897            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9898                (&disk_based_diagnostics_progress_token, &token)
 9899            {
 9900                token.starts_with(disk_based_token)
 9901            } else {
 9902                false
 9903            };
 9904
 9905        match progress {
 9906            lsp::WorkDoneProgress::Begin(report) => {
 9907                if is_disk_based_diagnostics_progress {
 9908                    self.disk_based_diagnostics_started(language_server_id, cx);
 9909                }
 9910                self.on_lsp_work_start(
 9911                    language_server_id,
 9912                    token.clone(),
 9913                    LanguageServerProgress {
 9914                        title: Some(report.title),
 9915                        is_disk_based_diagnostics_progress,
 9916                        is_cancellable: report.cancellable.unwrap_or(false),
 9917                        message: report.message.clone(),
 9918                        percentage: report.percentage.map(|p| p as usize),
 9919                        last_update_at: cx.background_executor().now(),
 9920                    },
 9921                    cx,
 9922                );
 9923            }
 9924            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9925                language_server_id,
 9926                token,
 9927                LanguageServerProgress {
 9928                    title: None,
 9929                    is_disk_based_diagnostics_progress,
 9930                    is_cancellable: report.cancellable.unwrap_or(false),
 9931                    message: report.message,
 9932                    percentage: report.percentage.map(|p| p as usize),
 9933                    last_update_at: cx.background_executor().now(),
 9934                },
 9935                cx,
 9936            ),
 9937            lsp::WorkDoneProgress::End(_) => {
 9938                language_server_status.progress_tokens.remove(&token);
 9939                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9940                if is_disk_based_diagnostics_progress {
 9941                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9942                }
 9943            }
 9944        }
 9945    }
 9946
 9947    fn on_lsp_work_start(
 9948        &mut self,
 9949        language_server_id: LanguageServerId,
 9950        token: ProgressToken,
 9951        progress: LanguageServerProgress,
 9952        cx: &mut Context<Self>,
 9953    ) {
 9954        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9955            status.pending_work.insert(token.clone(), progress.clone());
 9956            cx.notify();
 9957        }
 9958        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9959            language_server_id,
 9960            name: self
 9961                .language_server_adapter_for_id(language_server_id)
 9962                .map(|adapter| adapter.name()),
 9963            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9964                token: Some(token.to_proto()),
 9965                title: progress.title,
 9966                message: progress.message,
 9967                percentage: progress.percentage.map(|p| p as u32),
 9968                is_cancellable: Some(progress.is_cancellable),
 9969            }),
 9970        })
 9971    }
 9972
 9973    fn on_lsp_work_progress(
 9974        &mut self,
 9975        language_server_id: LanguageServerId,
 9976        token: ProgressToken,
 9977        progress: LanguageServerProgress,
 9978        cx: &mut Context<Self>,
 9979    ) {
 9980        let mut did_update = false;
 9981        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9982            match status.pending_work.entry(token.clone()) {
 9983                btree_map::Entry::Vacant(entry) => {
 9984                    entry.insert(progress.clone());
 9985                    did_update = true;
 9986                }
 9987                btree_map::Entry::Occupied(mut entry) => {
 9988                    let entry = entry.get_mut();
 9989                    if (progress.last_update_at - entry.last_update_at)
 9990                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9991                    {
 9992                        entry.last_update_at = progress.last_update_at;
 9993                        if progress.message.is_some() {
 9994                            entry.message = progress.message.clone();
 9995                        }
 9996                        if progress.percentage.is_some() {
 9997                            entry.percentage = progress.percentage;
 9998                        }
 9999                        if progress.is_cancellable != entry.is_cancellable {
10000                            entry.is_cancellable = progress.is_cancellable;
10001                        }
10002                        did_update = true;
10003                    }
10004                }
10005            }
10006        }
10007
10008        if did_update {
10009            cx.emit(LspStoreEvent::LanguageServerUpdate {
10010                language_server_id,
10011                name: self
10012                    .language_server_adapter_for_id(language_server_id)
10013                    .map(|adapter| adapter.name()),
10014                message: proto::update_language_server::Variant::WorkProgress(
10015                    proto::LspWorkProgress {
10016                        token: Some(token.to_proto()),
10017                        message: progress.message,
10018                        percentage: progress.percentage.map(|p| p as u32),
10019                        is_cancellable: Some(progress.is_cancellable),
10020                    },
10021                ),
10022            })
10023        }
10024    }
10025
10026    fn on_lsp_work_end(
10027        &mut self,
10028        language_server_id: LanguageServerId,
10029        token: ProgressToken,
10030        cx: &mut Context<Self>,
10031    ) {
10032        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10033            if let Some(work) = status.pending_work.remove(&token)
10034                && !work.is_disk_based_diagnostics_progress
10035            {
10036                cx.emit(LspStoreEvent::RefreshInlayHints {
10037                    server_id: language_server_id,
10038                    request_id: None,
10039                });
10040            }
10041            cx.notify();
10042        }
10043
10044        cx.emit(LspStoreEvent::LanguageServerUpdate {
10045            language_server_id,
10046            name: self
10047                .language_server_adapter_for_id(language_server_id)
10048                .map(|adapter| adapter.name()),
10049            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10050                token: Some(token.to_proto()),
10051            }),
10052        })
10053    }
10054
10055    pub async fn handle_resolve_completion_documentation(
10056        this: Entity<Self>,
10057        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10058        mut cx: AsyncApp,
10059    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10060        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10061
10062        let completion = this
10063            .read_with(&cx, |this, cx| {
10064                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10065                let server = this
10066                    .language_server_for_id(id)
10067                    .with_context(|| format!("No language server {id}"))?;
10068
10069                anyhow::Ok(cx.background_spawn(async move {
10070                    let can_resolve = server
10071                        .capabilities()
10072                        .completion_provider
10073                        .as_ref()
10074                        .and_then(|options| options.resolve_provider)
10075                        .unwrap_or(false);
10076                    if can_resolve {
10077                        server
10078                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
10079                            .await
10080                            .into_response()
10081                            .context("resolve completion item")
10082                    } else {
10083                        anyhow::Ok(lsp_completion)
10084                    }
10085                }))
10086            })??
10087            .await?;
10088
10089        let mut documentation_is_markdown = false;
10090        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10091        let documentation = match completion.documentation {
10092            Some(lsp::Documentation::String(text)) => text,
10093
10094            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10095                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10096                value
10097            }
10098
10099            _ => String::new(),
10100        };
10101
10102        // If we have a new buffer_id, that means we're talking to a new client
10103        // and want to check for new text_edits in the completion too.
10104        let mut old_replace_start = None;
10105        let mut old_replace_end = None;
10106        let mut old_insert_start = None;
10107        let mut old_insert_end = None;
10108        let mut new_text = String::default();
10109        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10110            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10111                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10112                anyhow::Ok(buffer.read(cx).snapshot())
10113            })??;
10114
10115            if let Some(text_edit) = completion.text_edit.as_ref() {
10116                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10117
10118                if let Some(mut edit) = edit {
10119                    LineEnding::normalize(&mut edit.new_text);
10120
10121                    new_text = edit.new_text;
10122                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10123                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10124                    if let Some(insert_range) = edit.insert_range {
10125                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10126                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10127                    }
10128                }
10129            }
10130        }
10131
10132        Ok(proto::ResolveCompletionDocumentationResponse {
10133            documentation,
10134            documentation_is_markdown,
10135            old_replace_start,
10136            old_replace_end,
10137            new_text,
10138            lsp_completion,
10139            old_insert_start,
10140            old_insert_end,
10141        })
10142    }
10143
10144    async fn handle_on_type_formatting(
10145        this: Entity<Self>,
10146        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10147        mut cx: AsyncApp,
10148    ) -> Result<proto::OnTypeFormattingResponse> {
10149        let on_type_formatting = this.update(&mut cx, |this, cx| {
10150            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10151            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10152            let position = envelope
10153                .payload
10154                .position
10155                .and_then(deserialize_anchor)
10156                .context("invalid position")?;
10157            anyhow::Ok(this.apply_on_type_formatting(
10158                buffer,
10159                position,
10160                envelope.payload.trigger.clone(),
10161                cx,
10162            ))
10163        })??;
10164
10165        let transaction = on_type_formatting
10166            .await?
10167            .as_ref()
10168            .map(language::proto::serialize_transaction);
10169        Ok(proto::OnTypeFormattingResponse { transaction })
10170    }
10171
10172    async fn handle_refresh_inlay_hints(
10173        lsp_store: Entity<Self>,
10174        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10175        mut cx: AsyncApp,
10176    ) -> Result<proto::Ack> {
10177        lsp_store.update(&mut cx, |_, cx| {
10178            cx.emit(LspStoreEvent::RefreshInlayHints {
10179                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10180                request_id: envelope.payload.request_id.map(|id| id as usize),
10181            });
10182        })?;
10183        Ok(proto::Ack {})
10184    }
10185
10186    async fn handle_pull_workspace_diagnostics(
10187        lsp_store: Entity<Self>,
10188        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10189        mut cx: AsyncApp,
10190    ) -> Result<proto::Ack> {
10191        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10192        lsp_store.update(&mut cx, |lsp_store, _| {
10193            lsp_store.pull_workspace_diagnostics(server_id);
10194        })?;
10195        Ok(proto::Ack {})
10196    }
10197
10198    async fn handle_get_color_presentation(
10199        lsp_store: Entity<Self>,
10200        envelope: TypedEnvelope<proto::GetColorPresentation>,
10201        mut cx: AsyncApp,
10202    ) -> Result<proto::GetColorPresentationResponse> {
10203        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10204        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10205            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10206        })??;
10207
10208        let color = envelope
10209            .payload
10210            .color
10211            .context("invalid color resolve request")?;
10212        let start = color
10213            .lsp_range_start
10214            .context("invalid color resolve request")?;
10215        let end = color
10216            .lsp_range_end
10217            .context("invalid color resolve request")?;
10218
10219        let color = DocumentColor {
10220            lsp_range: lsp::Range {
10221                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10222                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10223            },
10224            color: lsp::Color {
10225                red: color.red,
10226                green: color.green,
10227                blue: color.blue,
10228                alpha: color.alpha,
10229            },
10230            resolved: false,
10231            color_presentations: Vec::new(),
10232        };
10233        let resolved_color = lsp_store
10234            .update(&mut cx, |lsp_store, cx| {
10235                lsp_store.resolve_color_presentation(
10236                    color,
10237                    buffer.clone(),
10238                    LanguageServerId(envelope.payload.server_id as usize),
10239                    cx,
10240                )
10241            })?
10242            .await
10243            .context("resolving color presentation")?;
10244
10245        Ok(proto::GetColorPresentationResponse {
10246            presentations: resolved_color
10247                .color_presentations
10248                .into_iter()
10249                .map(|presentation| proto::ColorPresentation {
10250                    label: presentation.label.to_string(),
10251                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10252                    additional_text_edits: presentation
10253                        .additional_text_edits
10254                        .into_iter()
10255                        .map(serialize_lsp_edit)
10256                        .collect(),
10257                })
10258                .collect(),
10259        })
10260    }
10261
10262    async fn handle_resolve_inlay_hint(
10263        lsp_store: Entity<Self>,
10264        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10265        mut cx: AsyncApp,
10266    ) -> Result<proto::ResolveInlayHintResponse> {
10267        let proto_hint = envelope
10268            .payload
10269            .hint
10270            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10271        let hint = InlayHints::proto_to_project_hint(proto_hint)
10272            .context("resolved proto inlay hint conversion")?;
10273        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10274            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10275            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10276        })??;
10277        let response_hint = lsp_store
10278            .update(&mut cx, |lsp_store, cx| {
10279                lsp_store.resolve_inlay_hint(
10280                    hint,
10281                    buffer,
10282                    LanguageServerId(envelope.payload.language_server_id as usize),
10283                    cx,
10284                )
10285            })?
10286            .await
10287            .context("inlay hints fetch")?;
10288        Ok(proto::ResolveInlayHintResponse {
10289            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10290        })
10291    }
10292
10293    async fn handle_refresh_code_lens(
10294        this: Entity<Self>,
10295        _: TypedEnvelope<proto::RefreshCodeLens>,
10296        mut cx: AsyncApp,
10297    ) -> Result<proto::Ack> {
10298        this.update(&mut cx, |_, cx| {
10299            cx.emit(LspStoreEvent::RefreshCodeLens);
10300        })?;
10301        Ok(proto::Ack {})
10302    }
10303
10304    async fn handle_open_buffer_for_symbol(
10305        this: Entity<Self>,
10306        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10307        mut cx: AsyncApp,
10308    ) -> Result<proto::OpenBufferForSymbolResponse> {
10309        let peer_id = envelope.original_sender_id().unwrap_or_default();
10310        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10311        let symbol = Self::deserialize_symbol(symbol)?;
10312        this.read_with(&cx, |this, _| {
10313            if let SymbolLocation::OutsideProject {
10314                abs_path,
10315                signature,
10316            } = &symbol.path
10317            {
10318                let new_signature = this.symbol_signature(&abs_path);
10319                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10320            }
10321            Ok(())
10322        })??;
10323        let buffer = this
10324            .update(&mut cx, |this, cx| {
10325                this.open_buffer_for_symbol(
10326                    &Symbol {
10327                        language_server_name: symbol.language_server_name,
10328                        source_worktree_id: symbol.source_worktree_id,
10329                        source_language_server_id: symbol.source_language_server_id,
10330                        path: symbol.path,
10331                        name: symbol.name,
10332                        kind: symbol.kind,
10333                        range: symbol.range,
10334                        label: CodeLabel::default(),
10335                    },
10336                    cx,
10337                )
10338            })?
10339            .await?;
10340
10341        this.update(&mut cx, |this, cx| {
10342            let is_private = buffer
10343                .read(cx)
10344                .file()
10345                .map(|f| f.is_private())
10346                .unwrap_or_default();
10347            if is_private {
10348                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10349            } else {
10350                this.buffer_store
10351                    .update(cx, |buffer_store, cx| {
10352                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10353                    })
10354                    .detach_and_log_err(cx);
10355                let buffer_id = buffer.read(cx).remote_id().to_proto();
10356                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10357            }
10358        })?
10359    }
10360
10361    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10362        let mut hasher = Sha256::new();
10363        hasher.update(abs_path.to_string_lossy().as_bytes());
10364        hasher.update(self.nonce.to_be_bytes());
10365        hasher.finalize().as_slice().try_into().unwrap()
10366    }
10367
10368    pub async fn handle_get_project_symbols(
10369        this: Entity<Self>,
10370        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10371        mut cx: AsyncApp,
10372    ) -> Result<proto::GetProjectSymbolsResponse> {
10373        let symbols = this
10374            .update(&mut cx, |this, cx| {
10375                this.symbols(&envelope.payload.query, cx)
10376            })?
10377            .await?;
10378
10379        Ok(proto::GetProjectSymbolsResponse {
10380            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10381        })
10382    }
10383
10384    pub async fn handle_restart_language_servers(
10385        this: Entity<Self>,
10386        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10387        mut cx: AsyncApp,
10388    ) -> Result<proto::Ack> {
10389        this.update(&mut cx, |lsp_store, cx| {
10390            let buffers =
10391                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10392            lsp_store.restart_language_servers_for_buffers(
10393                buffers,
10394                envelope
10395                    .payload
10396                    .only_servers
10397                    .into_iter()
10398                    .filter_map(|selector| {
10399                        Some(match selector.selector? {
10400                            proto::language_server_selector::Selector::ServerId(server_id) => {
10401                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10402                            }
10403                            proto::language_server_selector::Selector::Name(name) => {
10404                                LanguageServerSelector::Name(LanguageServerName(
10405                                    SharedString::from(name),
10406                                ))
10407                            }
10408                        })
10409                    })
10410                    .collect(),
10411                cx,
10412            );
10413        })?;
10414
10415        Ok(proto::Ack {})
10416    }
10417
10418    pub async fn handle_stop_language_servers(
10419        lsp_store: Entity<Self>,
10420        envelope: TypedEnvelope<proto::StopLanguageServers>,
10421        mut cx: AsyncApp,
10422    ) -> Result<proto::Ack> {
10423        lsp_store.update(&mut cx, |lsp_store, cx| {
10424            if envelope.payload.all
10425                && envelope.payload.also_servers.is_empty()
10426                && envelope.payload.buffer_ids.is_empty()
10427            {
10428                lsp_store.stop_all_language_servers(cx);
10429            } else {
10430                let buffers =
10431                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10432                lsp_store
10433                    .stop_language_servers_for_buffers(
10434                        buffers,
10435                        envelope
10436                            .payload
10437                            .also_servers
10438                            .into_iter()
10439                            .filter_map(|selector| {
10440                                Some(match selector.selector? {
10441                                    proto::language_server_selector::Selector::ServerId(
10442                                        server_id,
10443                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10444                                        server_id,
10445                                    )),
10446                                    proto::language_server_selector::Selector::Name(name) => {
10447                                        LanguageServerSelector::Name(LanguageServerName(
10448                                            SharedString::from(name),
10449                                        ))
10450                                    }
10451                                })
10452                            })
10453                            .collect(),
10454                        cx,
10455                    )
10456                    .detach_and_log_err(cx);
10457            }
10458        })?;
10459
10460        Ok(proto::Ack {})
10461    }
10462
10463    pub async fn handle_cancel_language_server_work(
10464        lsp_store: Entity<Self>,
10465        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10466        mut cx: AsyncApp,
10467    ) -> Result<proto::Ack> {
10468        lsp_store.update(&mut cx, |lsp_store, cx| {
10469            if let Some(work) = envelope.payload.work {
10470                match work {
10471                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10472                        let buffers =
10473                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10474                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10475                    }
10476                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10477                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10478                        let token = work
10479                            .token
10480                            .map(|token| {
10481                                ProgressToken::from_proto(token)
10482                                    .context("invalid work progress token")
10483                            })
10484                            .transpose()?;
10485                        lsp_store.cancel_language_server_work(server_id, token, cx);
10486                    }
10487                }
10488            }
10489            anyhow::Ok(())
10490        })??;
10491
10492        Ok(proto::Ack {})
10493    }
10494
10495    fn buffer_ids_to_buffers(
10496        &mut self,
10497        buffer_ids: impl Iterator<Item = u64>,
10498        cx: &mut Context<Self>,
10499    ) -> Vec<Entity<Buffer>> {
10500        buffer_ids
10501            .into_iter()
10502            .flat_map(|buffer_id| {
10503                self.buffer_store
10504                    .read(cx)
10505                    .get(BufferId::new(buffer_id).log_err()?)
10506            })
10507            .collect::<Vec<_>>()
10508    }
10509
10510    async fn handle_apply_additional_edits_for_completion(
10511        this: Entity<Self>,
10512        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10513        mut cx: AsyncApp,
10514    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10515        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10516            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10517            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10518            let completion = Self::deserialize_completion(
10519                envelope.payload.completion.context("invalid completion")?,
10520            )?;
10521            anyhow::Ok((buffer, completion))
10522        })??;
10523
10524        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10525            this.apply_additional_edits_for_completion(
10526                buffer,
10527                Rc::new(RefCell::new(Box::new([Completion {
10528                    replace_range: completion.replace_range,
10529                    new_text: completion.new_text,
10530                    source: completion.source,
10531                    documentation: None,
10532                    label: CodeLabel::default(),
10533                    match_start: None,
10534                    snippet_deduplication_key: None,
10535                    insert_text_mode: None,
10536                    icon_path: None,
10537                    confirm: None,
10538                }]))),
10539                0,
10540                false,
10541                cx,
10542            )
10543        })?;
10544
10545        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10546            transaction: apply_additional_edits
10547                .await?
10548                .as_ref()
10549                .map(language::proto::serialize_transaction),
10550        })
10551    }
10552
10553    pub fn last_formatting_failure(&self) -> Option<&str> {
10554        self.last_formatting_failure.as_deref()
10555    }
10556
10557    pub fn reset_last_formatting_failure(&mut self) {
10558        self.last_formatting_failure = None;
10559    }
10560
10561    pub fn environment_for_buffer(
10562        &self,
10563        buffer: &Entity<Buffer>,
10564        cx: &mut Context<Self>,
10565    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10566        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10567            environment.update(cx, |env, cx| {
10568                env.buffer_environment(buffer, &self.worktree_store, cx)
10569            })
10570        } else {
10571            Task::ready(None).shared()
10572        }
10573    }
10574
10575    pub fn format(
10576        &mut self,
10577        buffers: HashSet<Entity<Buffer>>,
10578        target: LspFormatTarget,
10579        push_to_history: bool,
10580        trigger: FormatTrigger,
10581        cx: &mut Context<Self>,
10582    ) -> Task<anyhow::Result<ProjectTransaction>> {
10583        let logger = zlog::scoped!("format");
10584        if self.as_local().is_some() {
10585            zlog::trace!(logger => "Formatting locally");
10586            let logger = zlog::scoped!(logger => "local");
10587            let buffers = buffers
10588                .into_iter()
10589                .map(|buffer_handle| {
10590                    let buffer = buffer_handle.read(cx);
10591                    let buffer_abs_path = File::from_dyn(buffer.file())
10592                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10593
10594                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10595                })
10596                .collect::<Vec<_>>();
10597
10598            cx.spawn(async move |lsp_store, cx| {
10599                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10600
10601                for (handle, abs_path, id) in buffers {
10602                    let env = lsp_store
10603                        .update(cx, |lsp_store, cx| {
10604                            lsp_store.environment_for_buffer(&handle, cx)
10605                        })?
10606                        .await;
10607
10608                    let ranges = match &target {
10609                        LspFormatTarget::Buffers => None,
10610                        LspFormatTarget::Ranges(ranges) => {
10611                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10612                        }
10613                    };
10614
10615                    formattable_buffers.push(FormattableBuffer {
10616                        handle,
10617                        abs_path,
10618                        env,
10619                        ranges,
10620                    });
10621                }
10622                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10623
10624                let format_timer = zlog::time!(logger => "Formatting buffers");
10625                let result = LocalLspStore::format_locally(
10626                    lsp_store.clone(),
10627                    formattable_buffers,
10628                    push_to_history,
10629                    trigger,
10630                    logger,
10631                    cx,
10632                )
10633                .await;
10634                format_timer.end();
10635
10636                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10637
10638                lsp_store.update(cx, |lsp_store, _| {
10639                    lsp_store.update_last_formatting_failure(&result);
10640                })?;
10641
10642                result
10643            })
10644        } else if let Some((client, project_id)) = self.upstream_client() {
10645            zlog::trace!(logger => "Formatting remotely");
10646            let logger = zlog::scoped!(logger => "remote");
10647            // Don't support formatting ranges via remote
10648            match target {
10649                LspFormatTarget::Buffers => {}
10650                LspFormatTarget::Ranges(_) => {
10651                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10652                    return Task::ready(Ok(ProjectTransaction::default()));
10653                }
10654            }
10655
10656            let buffer_store = self.buffer_store();
10657            cx.spawn(async move |lsp_store, cx| {
10658                zlog::trace!(logger => "Sending remote format request");
10659                let request_timer = zlog::time!(logger => "remote format request");
10660                let result = client
10661                    .request(proto::FormatBuffers {
10662                        project_id,
10663                        trigger: trigger as i32,
10664                        buffer_ids: buffers
10665                            .iter()
10666                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10667                            .collect::<Result<_>>()?,
10668                    })
10669                    .await
10670                    .and_then(|result| result.transaction.context("missing transaction"));
10671                request_timer.end();
10672
10673                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10674
10675                lsp_store.update(cx, |lsp_store, _| {
10676                    lsp_store.update_last_formatting_failure(&result);
10677                })?;
10678
10679                let transaction_response = result?;
10680                let _timer = zlog::time!(logger => "deserializing project transaction");
10681                buffer_store
10682                    .update(cx, |buffer_store, cx| {
10683                        buffer_store.deserialize_project_transaction(
10684                            transaction_response,
10685                            push_to_history,
10686                            cx,
10687                        )
10688                    })?
10689                    .await
10690            })
10691        } else {
10692            zlog::trace!(logger => "Not formatting");
10693            Task::ready(Ok(ProjectTransaction::default()))
10694        }
10695    }
10696
10697    async fn handle_format_buffers(
10698        this: Entity<Self>,
10699        envelope: TypedEnvelope<proto::FormatBuffers>,
10700        mut cx: AsyncApp,
10701    ) -> Result<proto::FormatBuffersResponse> {
10702        let sender_id = envelope.original_sender_id().unwrap_or_default();
10703        let format = this.update(&mut cx, |this, cx| {
10704            let mut buffers = HashSet::default();
10705            for buffer_id in &envelope.payload.buffer_ids {
10706                let buffer_id = BufferId::new(*buffer_id)?;
10707                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10708            }
10709            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10710            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10711        })??;
10712
10713        let project_transaction = format.await?;
10714        let project_transaction = this.update(&mut cx, |this, cx| {
10715            this.buffer_store.update(cx, |buffer_store, cx| {
10716                buffer_store.serialize_project_transaction_for_peer(
10717                    project_transaction,
10718                    sender_id,
10719                    cx,
10720                )
10721            })
10722        })?;
10723        Ok(proto::FormatBuffersResponse {
10724            transaction: Some(project_transaction),
10725        })
10726    }
10727
10728    async fn handle_apply_code_action_kind(
10729        this: Entity<Self>,
10730        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10731        mut cx: AsyncApp,
10732    ) -> Result<proto::ApplyCodeActionKindResponse> {
10733        let sender_id = envelope.original_sender_id().unwrap_or_default();
10734        let format = this.update(&mut cx, |this, cx| {
10735            let mut buffers = HashSet::default();
10736            for buffer_id in &envelope.payload.buffer_ids {
10737                let buffer_id = BufferId::new(*buffer_id)?;
10738                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10739            }
10740            let kind = match envelope.payload.kind.as_str() {
10741                "" => CodeActionKind::EMPTY,
10742                "quickfix" => CodeActionKind::QUICKFIX,
10743                "refactor" => CodeActionKind::REFACTOR,
10744                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10745                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10746                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10747                "source" => CodeActionKind::SOURCE,
10748                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10749                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10750                _ => anyhow::bail!(
10751                    "Invalid code action kind {}",
10752                    envelope.payload.kind.as_str()
10753                ),
10754            };
10755            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10756        })??;
10757
10758        let project_transaction = format.await?;
10759        let project_transaction = this.update(&mut cx, |this, cx| {
10760            this.buffer_store.update(cx, |buffer_store, cx| {
10761                buffer_store.serialize_project_transaction_for_peer(
10762                    project_transaction,
10763                    sender_id,
10764                    cx,
10765                )
10766            })
10767        })?;
10768        Ok(proto::ApplyCodeActionKindResponse {
10769            transaction: Some(project_transaction),
10770        })
10771    }
10772
10773    async fn shutdown_language_server(
10774        server_state: Option<LanguageServerState>,
10775        name: LanguageServerName,
10776        cx: &mut AsyncApp,
10777    ) {
10778        let server = match server_state {
10779            Some(LanguageServerState::Starting { startup, .. }) => {
10780                let mut timer = cx
10781                    .background_executor()
10782                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10783                    .fuse();
10784
10785                select! {
10786                    server = startup.fuse() => server,
10787                    () = timer => {
10788                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10789                        None
10790                    },
10791                }
10792            }
10793
10794            Some(LanguageServerState::Running { server, .. }) => Some(server),
10795
10796            None => None,
10797        };
10798
10799        if let Some(server) = server
10800            && let Some(shutdown) = server.shutdown()
10801        {
10802            shutdown.await;
10803        }
10804    }
10805
10806    // Returns a list of all of the worktrees which no longer have a language server and the root path
10807    // for the stopped server
10808    fn stop_local_language_server(
10809        &mut self,
10810        server_id: LanguageServerId,
10811        cx: &mut Context<Self>,
10812    ) -> Task<()> {
10813        let local = match &mut self.mode {
10814            LspStoreMode::Local(local) => local,
10815            _ => {
10816                return Task::ready(());
10817            }
10818        };
10819
10820        // Remove this server ID from all entries in the given worktree.
10821        local
10822            .language_server_ids
10823            .retain(|_, state| state.id != server_id);
10824        self.buffer_store.update(cx, |buffer_store, cx| {
10825            for buffer in buffer_store.buffers() {
10826                buffer.update(cx, |buffer, cx| {
10827                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10828                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10829                });
10830            }
10831        });
10832
10833        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10834            summaries.retain(|path, summaries_by_server_id| {
10835                if summaries_by_server_id.remove(&server_id).is_some() {
10836                    if let Some((client, project_id)) = self.downstream_client.clone() {
10837                        client
10838                            .send(proto::UpdateDiagnosticSummary {
10839                                project_id,
10840                                worktree_id: worktree_id.to_proto(),
10841                                summary: Some(proto::DiagnosticSummary {
10842                                    path: path.as_ref().to_proto(),
10843                                    language_server_id: server_id.0 as u64,
10844                                    error_count: 0,
10845                                    warning_count: 0,
10846                                }),
10847                                more_summaries: Vec::new(),
10848                            })
10849                            .log_err();
10850                    }
10851                    !summaries_by_server_id.is_empty()
10852                } else {
10853                    true
10854                }
10855            });
10856        }
10857
10858        let local = self.as_local_mut().unwrap();
10859        for diagnostics in local.diagnostics.values_mut() {
10860            diagnostics.retain(|_, diagnostics_by_server_id| {
10861                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10862                    diagnostics_by_server_id.remove(ix);
10863                    !diagnostics_by_server_id.is_empty()
10864                } else {
10865                    true
10866                }
10867            });
10868        }
10869        local.language_server_watched_paths.remove(&server_id);
10870
10871        let server_state = local.language_servers.remove(&server_id);
10872        self.cleanup_lsp_data(server_id);
10873        let name = self
10874            .language_server_statuses
10875            .remove(&server_id)
10876            .map(|status| status.name)
10877            .or_else(|| {
10878                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10879                    Some(adapter.name())
10880                } else {
10881                    None
10882                }
10883            });
10884
10885        if let Some(name) = name {
10886            log::info!("stopping language server {name}");
10887            self.languages
10888                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10889            cx.notify();
10890
10891            return cx.spawn(async move |lsp_store, cx| {
10892                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10893                lsp_store
10894                    .update(cx, |lsp_store, cx| {
10895                        lsp_store
10896                            .languages
10897                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10898                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10899                        cx.notify();
10900                    })
10901                    .ok();
10902            });
10903        }
10904
10905        if server_state.is_some() {
10906            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10907        }
10908        Task::ready(())
10909    }
10910
10911    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10912        if let Some((client, project_id)) = self.upstream_client() {
10913            let request = client.request(proto::StopLanguageServers {
10914                project_id,
10915                buffer_ids: Vec::new(),
10916                also_servers: Vec::new(),
10917                all: true,
10918            });
10919            cx.background_spawn(request).detach_and_log_err(cx);
10920        } else {
10921            let Some(local) = self.as_local_mut() else {
10922                return;
10923            };
10924            let language_servers_to_stop = local
10925                .language_server_ids
10926                .values()
10927                .map(|state| state.id)
10928                .collect();
10929            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10930            let tasks = language_servers_to_stop
10931                .into_iter()
10932                .map(|server| self.stop_local_language_server(server, cx))
10933                .collect::<Vec<_>>();
10934            cx.background_spawn(async move {
10935                futures::future::join_all(tasks).await;
10936            })
10937            .detach();
10938        }
10939    }
10940
10941    pub fn restart_language_servers_for_buffers(
10942        &mut self,
10943        buffers: Vec<Entity<Buffer>>,
10944        only_restart_servers: HashSet<LanguageServerSelector>,
10945        cx: &mut Context<Self>,
10946    ) {
10947        if let Some((client, project_id)) = self.upstream_client() {
10948            let request = client.request(proto::RestartLanguageServers {
10949                project_id,
10950                buffer_ids: buffers
10951                    .into_iter()
10952                    .map(|b| b.read(cx).remote_id().to_proto())
10953                    .collect(),
10954                only_servers: only_restart_servers
10955                    .into_iter()
10956                    .map(|selector| {
10957                        let selector = match selector {
10958                            LanguageServerSelector::Id(language_server_id) => {
10959                                proto::language_server_selector::Selector::ServerId(
10960                                    language_server_id.to_proto(),
10961                                )
10962                            }
10963                            LanguageServerSelector::Name(language_server_name) => {
10964                                proto::language_server_selector::Selector::Name(
10965                                    language_server_name.to_string(),
10966                                )
10967                            }
10968                        };
10969                        proto::LanguageServerSelector {
10970                            selector: Some(selector),
10971                        }
10972                    })
10973                    .collect(),
10974                all: false,
10975            });
10976            cx.background_spawn(request).detach_and_log_err(cx);
10977        } else {
10978            let stop_task = if only_restart_servers.is_empty() {
10979                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10980            } else {
10981                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10982            };
10983            cx.spawn(async move |lsp_store, cx| {
10984                stop_task.await;
10985                lsp_store
10986                    .update(cx, |lsp_store, cx| {
10987                        for buffer in buffers {
10988                            lsp_store.register_buffer_with_language_servers(
10989                                &buffer,
10990                                only_restart_servers.clone(),
10991                                true,
10992                                cx,
10993                            );
10994                        }
10995                    })
10996                    .ok()
10997            })
10998            .detach();
10999        }
11000    }
11001
11002    pub fn stop_language_servers_for_buffers(
11003        &mut self,
11004        buffers: Vec<Entity<Buffer>>,
11005        also_stop_servers: HashSet<LanguageServerSelector>,
11006        cx: &mut Context<Self>,
11007    ) -> Task<Result<()>> {
11008        if let Some((client, project_id)) = self.upstream_client() {
11009            let request = client.request(proto::StopLanguageServers {
11010                project_id,
11011                buffer_ids: buffers
11012                    .into_iter()
11013                    .map(|b| b.read(cx).remote_id().to_proto())
11014                    .collect(),
11015                also_servers: also_stop_servers
11016                    .into_iter()
11017                    .map(|selector| {
11018                        let selector = match selector {
11019                            LanguageServerSelector::Id(language_server_id) => {
11020                                proto::language_server_selector::Selector::ServerId(
11021                                    language_server_id.to_proto(),
11022                                )
11023                            }
11024                            LanguageServerSelector::Name(language_server_name) => {
11025                                proto::language_server_selector::Selector::Name(
11026                                    language_server_name.to_string(),
11027                                )
11028                            }
11029                        };
11030                        proto::LanguageServerSelector {
11031                            selector: Some(selector),
11032                        }
11033                    })
11034                    .collect(),
11035                all: false,
11036            });
11037            cx.background_spawn(async move {
11038                let _ = request.await?;
11039                Ok(())
11040            })
11041        } else {
11042            let task =
11043                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11044            cx.background_spawn(async move {
11045                task.await;
11046                Ok(())
11047            })
11048        }
11049    }
11050
11051    fn stop_local_language_servers_for_buffers(
11052        &mut self,
11053        buffers: &[Entity<Buffer>],
11054        also_stop_servers: HashSet<LanguageServerSelector>,
11055        cx: &mut Context<Self>,
11056    ) -> Task<()> {
11057        let Some(local) = self.as_local_mut() else {
11058            return Task::ready(());
11059        };
11060        let mut language_server_names_to_stop = BTreeSet::default();
11061        let mut language_servers_to_stop = also_stop_servers
11062            .into_iter()
11063            .flat_map(|selector| match selector {
11064                LanguageServerSelector::Id(id) => Some(id),
11065                LanguageServerSelector::Name(name) => {
11066                    language_server_names_to_stop.insert(name);
11067                    None
11068                }
11069            })
11070            .collect::<BTreeSet<_>>();
11071
11072        let mut covered_worktrees = HashSet::default();
11073        for buffer in buffers {
11074            buffer.update(cx, |buffer, cx| {
11075                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11076                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11077                    && covered_worktrees.insert(worktree_id)
11078                {
11079                    language_server_names_to_stop.retain(|name| {
11080                        let old_ids_count = language_servers_to_stop.len();
11081                        let all_language_servers_with_this_name = local
11082                            .language_server_ids
11083                            .iter()
11084                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11085                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11086                        old_ids_count == language_servers_to_stop.len()
11087                    });
11088                }
11089            });
11090        }
11091        for name in language_server_names_to_stop {
11092            language_servers_to_stop.extend(
11093                local
11094                    .language_server_ids
11095                    .iter()
11096                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11097            );
11098        }
11099
11100        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11101        let tasks = language_servers_to_stop
11102            .into_iter()
11103            .map(|server| self.stop_local_language_server(server, cx))
11104            .collect::<Vec<_>>();
11105
11106        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11107    }
11108
11109    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11110        let (worktree, relative_path) =
11111            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11112
11113        let project_path = ProjectPath {
11114            worktree_id: worktree.read(cx).id(),
11115            path: relative_path,
11116        };
11117
11118        Some(
11119            self.buffer_store()
11120                .read(cx)
11121                .get_by_path(&project_path)?
11122                .read(cx),
11123        )
11124    }
11125
11126    #[cfg(any(test, feature = "test-support"))]
11127    pub fn update_diagnostics(
11128        &mut self,
11129        server_id: LanguageServerId,
11130        diagnostics: lsp::PublishDiagnosticsParams,
11131        result_id: Option<SharedString>,
11132        source_kind: DiagnosticSourceKind,
11133        disk_based_sources: &[String],
11134        cx: &mut Context<Self>,
11135    ) -> Result<()> {
11136        self.merge_lsp_diagnostics(
11137            source_kind,
11138            vec![DocumentDiagnosticsUpdate {
11139                diagnostics,
11140                result_id,
11141                server_id,
11142                disk_based_sources: Cow::Borrowed(disk_based_sources),
11143                registration_id: None,
11144            }],
11145            |_, _, _| false,
11146            cx,
11147        )
11148    }
11149
11150    pub fn merge_lsp_diagnostics(
11151        &mut self,
11152        source_kind: DiagnosticSourceKind,
11153        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11154        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11155        cx: &mut Context<Self>,
11156    ) -> Result<()> {
11157        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11158        let updates = lsp_diagnostics
11159            .into_iter()
11160            .filter_map(|update| {
11161                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11162                Some(DocumentDiagnosticsUpdate {
11163                    diagnostics: self.lsp_to_document_diagnostics(
11164                        abs_path,
11165                        source_kind,
11166                        update.server_id,
11167                        update.diagnostics,
11168                        &update.disk_based_sources,
11169                        update.registration_id.clone(),
11170                    ),
11171                    result_id: update.result_id,
11172                    server_id: update.server_id,
11173                    disk_based_sources: update.disk_based_sources,
11174                    registration_id: update.registration_id,
11175                })
11176            })
11177            .collect();
11178        self.merge_diagnostic_entries(updates, merge, cx)?;
11179        Ok(())
11180    }
11181
11182    fn lsp_to_document_diagnostics(
11183        &mut self,
11184        document_abs_path: PathBuf,
11185        source_kind: DiagnosticSourceKind,
11186        server_id: LanguageServerId,
11187        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11188        disk_based_sources: &[String],
11189        registration_id: Option<SharedString>,
11190    ) -> DocumentDiagnostics {
11191        let mut diagnostics = Vec::default();
11192        let mut primary_diagnostic_group_ids = HashMap::default();
11193        let mut sources_by_group_id = HashMap::default();
11194        let mut supporting_diagnostics = HashMap::default();
11195
11196        let adapter = self.language_server_adapter_for_id(server_id);
11197
11198        // Ensure that primary diagnostics are always the most severe
11199        lsp_diagnostics
11200            .diagnostics
11201            .sort_by_key(|item| item.severity);
11202
11203        for diagnostic in &lsp_diagnostics.diagnostics {
11204            let source = diagnostic.source.as_ref();
11205            let range = range_from_lsp(diagnostic.range);
11206            let is_supporting = diagnostic
11207                .related_information
11208                .as_ref()
11209                .is_some_and(|infos| {
11210                    infos.iter().any(|info| {
11211                        primary_diagnostic_group_ids.contains_key(&(
11212                            source,
11213                            diagnostic.code.clone(),
11214                            range_from_lsp(info.location.range),
11215                        ))
11216                    })
11217                });
11218
11219            let is_unnecessary = diagnostic
11220                .tags
11221                .as_ref()
11222                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11223
11224            let underline = self
11225                .language_server_adapter_for_id(server_id)
11226                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11227
11228            if is_supporting {
11229                supporting_diagnostics.insert(
11230                    (source, diagnostic.code.clone(), range),
11231                    (diagnostic.severity, is_unnecessary),
11232                );
11233            } else {
11234                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11235                let is_disk_based =
11236                    source.is_some_and(|source| disk_based_sources.contains(source));
11237
11238                sources_by_group_id.insert(group_id, source);
11239                primary_diagnostic_group_ids
11240                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11241
11242                diagnostics.push(DiagnosticEntry {
11243                    range,
11244                    diagnostic: Diagnostic {
11245                        source: diagnostic.source.clone(),
11246                        source_kind,
11247                        code: diagnostic.code.clone(),
11248                        code_description: diagnostic
11249                            .code_description
11250                            .as_ref()
11251                            .and_then(|d| d.href.clone()),
11252                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11253                        markdown: adapter.as_ref().and_then(|adapter| {
11254                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11255                        }),
11256                        message: diagnostic.message.trim().to_string(),
11257                        group_id,
11258                        is_primary: true,
11259                        is_disk_based,
11260                        is_unnecessary,
11261                        underline,
11262                        data: diagnostic.data.clone(),
11263                        registration_id: registration_id.clone(),
11264                    },
11265                });
11266                if let Some(infos) = &diagnostic.related_information {
11267                    for info in infos {
11268                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11269                            let range = range_from_lsp(info.location.range);
11270                            diagnostics.push(DiagnosticEntry {
11271                                range,
11272                                diagnostic: Diagnostic {
11273                                    source: diagnostic.source.clone(),
11274                                    source_kind,
11275                                    code: diagnostic.code.clone(),
11276                                    code_description: diagnostic
11277                                        .code_description
11278                                        .as_ref()
11279                                        .and_then(|d| d.href.clone()),
11280                                    severity: DiagnosticSeverity::INFORMATION,
11281                                    markdown: adapter.as_ref().and_then(|adapter| {
11282                                        adapter.diagnostic_message_to_markdown(&info.message)
11283                                    }),
11284                                    message: info.message.trim().to_string(),
11285                                    group_id,
11286                                    is_primary: false,
11287                                    is_disk_based,
11288                                    is_unnecessary: false,
11289                                    underline,
11290                                    data: diagnostic.data.clone(),
11291                                    registration_id: registration_id.clone(),
11292                                },
11293                            });
11294                        }
11295                    }
11296                }
11297            }
11298        }
11299
11300        for entry in &mut diagnostics {
11301            let diagnostic = &mut entry.diagnostic;
11302            if !diagnostic.is_primary {
11303                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11304                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11305                    source,
11306                    diagnostic.code.clone(),
11307                    entry.range.clone(),
11308                )) {
11309                    if let Some(severity) = severity {
11310                        diagnostic.severity = severity;
11311                    }
11312                    diagnostic.is_unnecessary = is_unnecessary;
11313                }
11314            }
11315        }
11316
11317        DocumentDiagnostics {
11318            diagnostics,
11319            document_abs_path,
11320            version: lsp_diagnostics.version,
11321        }
11322    }
11323
11324    fn insert_newly_running_language_server(
11325        &mut self,
11326        adapter: Arc<CachedLspAdapter>,
11327        language_server: Arc<LanguageServer>,
11328        server_id: LanguageServerId,
11329        key: LanguageServerSeed,
11330        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11331        cx: &mut Context<Self>,
11332    ) {
11333        let Some(local) = self.as_local_mut() else {
11334            return;
11335        };
11336        // If the language server for this key doesn't match the server id, don't store the
11337        // server. Which will cause it to be dropped, killing the process
11338        if local
11339            .language_server_ids
11340            .get(&key)
11341            .map(|state| state.id != server_id)
11342            .unwrap_or(false)
11343        {
11344            return;
11345        }
11346
11347        // Update language_servers collection with Running variant of LanguageServerState
11348        // indicating that the server is up and running and ready
11349        let workspace_folders = workspace_folders.lock().clone();
11350        language_server.set_workspace_folders(workspace_folders);
11351
11352        let workspace_diagnostics_refresh_tasks = language_server
11353            .capabilities()
11354            .diagnostic_provider
11355            .and_then(|provider| {
11356                local
11357                    .language_server_dynamic_registrations
11358                    .entry(server_id)
11359                    .or_default()
11360                    .diagnostics
11361                    .entry(None)
11362                    .or_insert(provider.clone());
11363                let workspace_refresher =
11364                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11365
11366                Some((None, workspace_refresher))
11367            })
11368            .into_iter()
11369            .collect();
11370        local.language_servers.insert(
11371            server_id,
11372            LanguageServerState::Running {
11373                workspace_diagnostics_refresh_tasks,
11374                adapter: adapter.clone(),
11375                server: language_server.clone(),
11376                simulate_disk_based_diagnostics_completion: None,
11377            },
11378        );
11379        local
11380            .languages
11381            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11382        if let Some(file_ops_caps) = language_server
11383            .capabilities()
11384            .workspace
11385            .as_ref()
11386            .and_then(|ws| ws.file_operations.as_ref())
11387        {
11388            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11389            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11390            if did_rename_caps.or(will_rename_caps).is_some() {
11391                let watcher = RenamePathsWatchedForServer::default()
11392                    .with_did_rename_patterns(did_rename_caps)
11393                    .with_will_rename_patterns(will_rename_caps);
11394                local
11395                    .language_server_paths_watched_for_rename
11396                    .insert(server_id, watcher);
11397            }
11398        }
11399
11400        self.language_server_statuses.insert(
11401            server_id,
11402            LanguageServerStatus {
11403                name: language_server.name(),
11404                pending_work: Default::default(),
11405                has_pending_diagnostic_updates: false,
11406                progress_tokens: Default::default(),
11407                worktree: Some(key.worktree_id),
11408                binary: Some(language_server.binary().clone()),
11409                configuration: Some(language_server.configuration().clone()),
11410                workspace_folders: language_server.workspace_folders(),
11411            },
11412        );
11413
11414        cx.emit(LspStoreEvent::LanguageServerAdded(
11415            server_id,
11416            language_server.name(),
11417            Some(key.worktree_id),
11418        ));
11419
11420        let server_capabilities = language_server.capabilities();
11421        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11422            downstream_client
11423                .send(proto::StartLanguageServer {
11424                    project_id: *project_id,
11425                    server: Some(proto::LanguageServer {
11426                        id: server_id.to_proto(),
11427                        name: language_server.name().to_string(),
11428                        worktree_id: Some(key.worktree_id.to_proto()),
11429                    }),
11430                    capabilities: serde_json::to_string(&server_capabilities)
11431                        .expect("serializing server LSP capabilities"),
11432                })
11433                .log_err();
11434        }
11435        self.lsp_server_capabilities
11436            .insert(server_id, server_capabilities);
11437
11438        // Tell the language server about every open buffer in the worktree that matches the language.
11439        // Also check for buffers in worktrees that reused this server
11440        let mut worktrees_using_server = vec![key.worktree_id];
11441        if let Some(local) = self.as_local() {
11442            // Find all worktrees that have this server in their language server tree
11443            for (worktree_id, servers) in &local.lsp_tree.instances {
11444                if *worktree_id != key.worktree_id {
11445                    for server_map in servers.roots.values() {
11446                        if server_map
11447                            .values()
11448                            .any(|(node, _)| node.id() == Some(server_id))
11449                        {
11450                            worktrees_using_server.push(*worktree_id);
11451                        }
11452                    }
11453                }
11454            }
11455        }
11456
11457        let mut buffer_paths_registered = Vec::new();
11458        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11459            let mut lsp_adapters = HashMap::default();
11460            for buffer_handle in buffer_store.buffers() {
11461                let buffer = buffer_handle.read(cx);
11462                let file = match File::from_dyn(buffer.file()) {
11463                    Some(file) => file,
11464                    None => continue,
11465                };
11466                let language = match buffer.language() {
11467                    Some(language) => language,
11468                    None => continue,
11469                };
11470
11471                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11472                    || !lsp_adapters
11473                        .entry(language.name())
11474                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11475                        .iter()
11476                        .any(|a| a.name == key.name)
11477                {
11478                    continue;
11479                }
11480                // didOpen
11481                let file = match file.as_local() {
11482                    Some(file) => file,
11483                    None => continue,
11484                };
11485
11486                let local = self.as_local_mut().unwrap();
11487
11488                let buffer_id = buffer.remote_id();
11489                if local.registered_buffers.contains_key(&buffer_id) {
11490                    let versions = local
11491                        .buffer_snapshots
11492                        .entry(buffer_id)
11493                        .or_default()
11494                        .entry(server_id)
11495                        .and_modify(|_| {
11496                            assert!(
11497                            false,
11498                            "There should not be an existing snapshot for a newly inserted buffer"
11499                        )
11500                        })
11501                        .or_insert_with(|| {
11502                            vec![LspBufferSnapshot {
11503                                version: 0,
11504                                snapshot: buffer.text_snapshot(),
11505                            }]
11506                        });
11507
11508                    let snapshot = versions.last().unwrap();
11509                    let version = snapshot.version;
11510                    let initial_snapshot = &snapshot.snapshot;
11511                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11512                    language_server.register_buffer(
11513                        uri,
11514                        adapter.language_id(&language.name()),
11515                        version,
11516                        initial_snapshot.text(),
11517                    );
11518                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11519                    local
11520                        .buffers_opened_in_servers
11521                        .entry(buffer_id)
11522                        .or_default()
11523                        .insert(server_id);
11524                }
11525                buffer_handle.update(cx, |buffer, cx| {
11526                    buffer.set_completion_triggers(
11527                        server_id,
11528                        language_server
11529                            .capabilities()
11530                            .completion_provider
11531                            .as_ref()
11532                            .and_then(|provider| {
11533                                provider
11534                                    .trigger_characters
11535                                    .as_ref()
11536                                    .map(|characters| characters.iter().cloned().collect())
11537                            })
11538                            .unwrap_or_default(),
11539                        cx,
11540                    )
11541                });
11542            }
11543        });
11544
11545        for (buffer_id, abs_path) in buffer_paths_registered {
11546            cx.emit(LspStoreEvent::LanguageServerUpdate {
11547                language_server_id: server_id,
11548                name: Some(adapter.name()),
11549                message: proto::update_language_server::Variant::RegisteredForBuffer(
11550                    proto::RegisteredForBuffer {
11551                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11552                        buffer_id: buffer_id.to_proto(),
11553                    },
11554                ),
11555            });
11556        }
11557
11558        cx.notify();
11559    }
11560
11561    pub fn language_servers_running_disk_based_diagnostics(
11562        &self,
11563    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11564        self.language_server_statuses
11565            .iter()
11566            .filter_map(|(id, status)| {
11567                if status.has_pending_diagnostic_updates {
11568                    Some(*id)
11569                } else {
11570                    None
11571                }
11572            })
11573    }
11574
11575    pub(crate) fn cancel_language_server_work_for_buffers(
11576        &mut self,
11577        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11578        cx: &mut Context<Self>,
11579    ) {
11580        if let Some((client, project_id)) = self.upstream_client() {
11581            let request = client.request(proto::CancelLanguageServerWork {
11582                project_id,
11583                work: Some(proto::cancel_language_server_work::Work::Buffers(
11584                    proto::cancel_language_server_work::Buffers {
11585                        buffer_ids: buffers
11586                            .into_iter()
11587                            .map(|b| b.read(cx).remote_id().to_proto())
11588                            .collect(),
11589                    },
11590                )),
11591            });
11592            cx.background_spawn(request).detach_and_log_err(cx);
11593        } else if let Some(local) = self.as_local() {
11594            let servers = buffers
11595                .into_iter()
11596                .flat_map(|buffer| {
11597                    buffer.update(cx, |buffer, cx| {
11598                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11599                    })
11600                })
11601                .collect::<HashSet<_>>();
11602            for server_id in servers {
11603                self.cancel_language_server_work(server_id, None, cx);
11604            }
11605        }
11606    }
11607
11608    pub(crate) fn cancel_language_server_work(
11609        &mut self,
11610        server_id: LanguageServerId,
11611        token_to_cancel: Option<ProgressToken>,
11612        cx: &mut Context<Self>,
11613    ) {
11614        if let Some(local) = self.as_local() {
11615            let status = self.language_server_statuses.get(&server_id);
11616            let server = local.language_servers.get(&server_id);
11617            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11618            {
11619                for (token, progress) in &status.pending_work {
11620                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11621                        && token != token_to_cancel
11622                    {
11623                        continue;
11624                    }
11625                    if progress.is_cancellable {
11626                        server
11627                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11628                                WorkDoneProgressCancelParams {
11629                                    token: token.to_lsp(),
11630                                },
11631                            )
11632                            .ok();
11633                    }
11634                }
11635            }
11636        } else if let Some((client, project_id)) = self.upstream_client() {
11637            let request = client.request(proto::CancelLanguageServerWork {
11638                project_id,
11639                work: Some(
11640                    proto::cancel_language_server_work::Work::LanguageServerWork(
11641                        proto::cancel_language_server_work::LanguageServerWork {
11642                            language_server_id: server_id.to_proto(),
11643                            token: token_to_cancel.map(|token| token.to_proto()),
11644                        },
11645                    ),
11646                ),
11647            });
11648            cx.background_spawn(request).detach_and_log_err(cx);
11649        }
11650    }
11651
11652    fn register_supplementary_language_server(
11653        &mut self,
11654        id: LanguageServerId,
11655        name: LanguageServerName,
11656        server: Arc<LanguageServer>,
11657        cx: &mut Context<Self>,
11658    ) {
11659        if let Some(local) = self.as_local_mut() {
11660            local
11661                .supplementary_language_servers
11662                .insert(id, (name.clone(), server));
11663            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11664        }
11665    }
11666
11667    fn unregister_supplementary_language_server(
11668        &mut self,
11669        id: LanguageServerId,
11670        cx: &mut Context<Self>,
11671    ) {
11672        if let Some(local) = self.as_local_mut() {
11673            local.supplementary_language_servers.remove(&id);
11674            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11675        }
11676    }
11677
11678    pub(crate) fn supplementary_language_servers(
11679        &self,
11680    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11681        self.as_local().into_iter().flat_map(|local| {
11682            local
11683                .supplementary_language_servers
11684                .iter()
11685                .map(|(id, (name, _))| (*id, name.clone()))
11686        })
11687    }
11688
11689    pub fn language_server_adapter_for_id(
11690        &self,
11691        id: LanguageServerId,
11692    ) -> Option<Arc<CachedLspAdapter>> {
11693        self.as_local()
11694            .and_then(|local| local.language_servers.get(&id))
11695            .and_then(|language_server_state| match language_server_state {
11696                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11697                _ => None,
11698            })
11699    }
11700
11701    pub(super) fn update_local_worktree_language_servers(
11702        &mut self,
11703        worktree_handle: &Entity<Worktree>,
11704        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11705        cx: &mut Context<Self>,
11706    ) {
11707        if changes.is_empty() {
11708            return;
11709        }
11710
11711        let Some(local) = self.as_local() else { return };
11712
11713        local.prettier_store.update(cx, |prettier_store, cx| {
11714            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11715        });
11716
11717        let worktree_id = worktree_handle.read(cx).id();
11718        let mut language_server_ids = local
11719            .language_server_ids
11720            .iter()
11721            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11722            .collect::<Vec<_>>();
11723        language_server_ids.sort();
11724        language_server_ids.dedup();
11725
11726        // let abs_path = worktree_handle.read(cx).abs_path();
11727        for server_id in &language_server_ids {
11728            if let Some(LanguageServerState::Running { server, .. }) =
11729                local.language_servers.get(server_id)
11730                && let Some(watched_paths) = local
11731                    .language_server_watched_paths
11732                    .get(server_id)
11733                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11734            {
11735                let params = lsp::DidChangeWatchedFilesParams {
11736                    changes: changes
11737                        .iter()
11738                        .filter_map(|(path, _, change)| {
11739                            if !watched_paths.is_match(path.as_std_path()) {
11740                                return None;
11741                            }
11742                            let typ = match change {
11743                                PathChange::Loaded => return None,
11744                                PathChange::Added => lsp::FileChangeType::CREATED,
11745                                PathChange::Removed => lsp::FileChangeType::DELETED,
11746                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11747                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11748                            };
11749                            let uri = lsp::Uri::from_file_path(
11750                                worktree_handle.read(cx).absolutize(&path),
11751                            )
11752                            .ok()?;
11753                            Some(lsp::FileEvent { uri, typ })
11754                        })
11755                        .collect(),
11756                };
11757                if !params.changes.is_empty() {
11758                    server
11759                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11760                        .ok();
11761                }
11762            }
11763        }
11764        for (path, _, _) in changes {
11765            if let Some(file_name) = path.file_name()
11766                && local.watched_manifest_filenames.contains(file_name)
11767            {
11768                self.request_workspace_config_refresh();
11769                break;
11770            }
11771        }
11772    }
11773
11774    pub fn wait_for_remote_buffer(
11775        &mut self,
11776        id: BufferId,
11777        cx: &mut Context<Self>,
11778    ) -> Task<Result<Entity<Buffer>>> {
11779        self.buffer_store.update(cx, |buffer_store, cx| {
11780            buffer_store.wait_for_remote_buffer(id, cx)
11781        })
11782    }
11783
11784    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11785        let mut result = proto::Symbol {
11786            language_server_name: symbol.language_server_name.0.to_string(),
11787            source_worktree_id: symbol.source_worktree_id.to_proto(),
11788            language_server_id: symbol.source_language_server_id.to_proto(),
11789            name: symbol.name.clone(),
11790            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11791            start: Some(proto::PointUtf16 {
11792                row: symbol.range.start.0.row,
11793                column: symbol.range.start.0.column,
11794            }),
11795            end: Some(proto::PointUtf16 {
11796                row: symbol.range.end.0.row,
11797                column: symbol.range.end.0.column,
11798            }),
11799            worktree_id: Default::default(),
11800            path: Default::default(),
11801            signature: Default::default(),
11802        };
11803        match &symbol.path {
11804            SymbolLocation::InProject(path) => {
11805                result.worktree_id = path.worktree_id.to_proto();
11806                result.path = path.path.to_proto();
11807            }
11808            SymbolLocation::OutsideProject {
11809                abs_path,
11810                signature,
11811            } => {
11812                result.path = abs_path.to_string_lossy().into_owned();
11813                result.signature = signature.to_vec();
11814            }
11815        }
11816        result
11817    }
11818
11819    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11820        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11821        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11822        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11823
11824        let path = if serialized_symbol.signature.is_empty() {
11825            SymbolLocation::InProject(ProjectPath {
11826                worktree_id,
11827                path: RelPath::from_proto(&serialized_symbol.path)
11828                    .context("invalid symbol path")?,
11829            })
11830        } else {
11831            SymbolLocation::OutsideProject {
11832                abs_path: Path::new(&serialized_symbol.path).into(),
11833                signature: serialized_symbol
11834                    .signature
11835                    .try_into()
11836                    .map_err(|_| anyhow!("invalid signature"))?,
11837            }
11838        };
11839
11840        let start = serialized_symbol.start.context("invalid start")?;
11841        let end = serialized_symbol.end.context("invalid end")?;
11842        Ok(CoreSymbol {
11843            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11844            source_worktree_id,
11845            source_language_server_id: LanguageServerId::from_proto(
11846                serialized_symbol.language_server_id,
11847            ),
11848            path,
11849            name: serialized_symbol.name,
11850            range: Unclipped(PointUtf16::new(start.row, start.column))
11851                ..Unclipped(PointUtf16::new(end.row, end.column)),
11852            kind,
11853        })
11854    }
11855
11856    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11857        let mut serialized_completion = proto::Completion {
11858            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11859            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11860            new_text: completion.new_text.clone(),
11861            ..proto::Completion::default()
11862        };
11863        match &completion.source {
11864            CompletionSource::Lsp {
11865                insert_range,
11866                server_id,
11867                lsp_completion,
11868                lsp_defaults,
11869                resolved,
11870            } => {
11871                let (old_insert_start, old_insert_end) = insert_range
11872                    .as_ref()
11873                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11874                    .unzip();
11875
11876                serialized_completion.old_insert_start = old_insert_start;
11877                serialized_completion.old_insert_end = old_insert_end;
11878                serialized_completion.source = proto::completion::Source::Lsp as i32;
11879                serialized_completion.server_id = server_id.0 as u64;
11880                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11881                serialized_completion.lsp_defaults = lsp_defaults
11882                    .as_deref()
11883                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11884                serialized_completion.resolved = *resolved;
11885            }
11886            CompletionSource::BufferWord {
11887                word_range,
11888                resolved,
11889            } => {
11890                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11891                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11892                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11893                serialized_completion.resolved = *resolved;
11894            }
11895            CompletionSource::Custom => {
11896                serialized_completion.source = proto::completion::Source::Custom as i32;
11897                serialized_completion.resolved = true;
11898            }
11899            CompletionSource::Dap { sort_text } => {
11900                serialized_completion.source = proto::completion::Source::Dap as i32;
11901                serialized_completion.sort_text = Some(sort_text.clone());
11902            }
11903        }
11904
11905        serialized_completion
11906    }
11907
11908    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11909        let old_replace_start = completion
11910            .old_replace_start
11911            .and_then(deserialize_anchor)
11912            .context("invalid old start")?;
11913        let old_replace_end = completion
11914            .old_replace_end
11915            .and_then(deserialize_anchor)
11916            .context("invalid old end")?;
11917        let insert_range = {
11918            match completion.old_insert_start.zip(completion.old_insert_end) {
11919                Some((start, end)) => {
11920                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11921                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11922                    Some(start..end)
11923                }
11924                None => None,
11925            }
11926        };
11927        Ok(CoreCompletion {
11928            replace_range: old_replace_start..old_replace_end,
11929            new_text: completion.new_text,
11930            source: match proto::completion::Source::from_i32(completion.source) {
11931                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11932                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11933                    insert_range,
11934                    server_id: LanguageServerId::from_proto(completion.server_id),
11935                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11936                    lsp_defaults: completion
11937                        .lsp_defaults
11938                        .as_deref()
11939                        .map(serde_json::from_slice)
11940                        .transpose()?,
11941                    resolved: completion.resolved,
11942                },
11943                Some(proto::completion::Source::BufferWord) => {
11944                    let word_range = completion
11945                        .buffer_word_start
11946                        .and_then(deserialize_anchor)
11947                        .context("invalid buffer word start")?
11948                        ..completion
11949                            .buffer_word_end
11950                            .and_then(deserialize_anchor)
11951                            .context("invalid buffer word end")?;
11952                    CompletionSource::BufferWord {
11953                        word_range,
11954                        resolved: completion.resolved,
11955                    }
11956                }
11957                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11958                    sort_text: completion
11959                        .sort_text
11960                        .context("expected sort text to exist")?,
11961                },
11962                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11963            },
11964        })
11965    }
11966
11967    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11968        let (kind, lsp_action) = match &action.lsp_action {
11969            LspAction::Action(code_action) => (
11970                proto::code_action::Kind::Action as i32,
11971                serde_json::to_vec(code_action).unwrap(),
11972            ),
11973            LspAction::Command(command) => (
11974                proto::code_action::Kind::Command as i32,
11975                serde_json::to_vec(command).unwrap(),
11976            ),
11977            LspAction::CodeLens(code_lens) => (
11978                proto::code_action::Kind::CodeLens as i32,
11979                serde_json::to_vec(code_lens).unwrap(),
11980            ),
11981        };
11982
11983        proto::CodeAction {
11984            server_id: action.server_id.0 as u64,
11985            start: Some(serialize_anchor(&action.range.start)),
11986            end: Some(serialize_anchor(&action.range.end)),
11987            lsp_action,
11988            kind,
11989            resolved: action.resolved,
11990        }
11991    }
11992
11993    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11994        let start = action
11995            .start
11996            .and_then(deserialize_anchor)
11997            .context("invalid start")?;
11998        let end = action
11999            .end
12000            .and_then(deserialize_anchor)
12001            .context("invalid end")?;
12002        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12003            Some(proto::code_action::Kind::Action) => {
12004                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12005            }
12006            Some(proto::code_action::Kind::Command) => {
12007                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12008            }
12009            Some(proto::code_action::Kind::CodeLens) => {
12010                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12011            }
12012            None => anyhow::bail!("Unknown action kind {}", action.kind),
12013        };
12014        Ok(CodeAction {
12015            server_id: LanguageServerId(action.server_id as usize),
12016            range: start..end,
12017            resolved: action.resolved,
12018            lsp_action,
12019        })
12020    }
12021
12022    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12023        match &formatting_result {
12024            Ok(_) => self.last_formatting_failure = None,
12025            Err(error) => {
12026                let error_string = format!("{error:#}");
12027                log::error!("Formatting failed: {error_string}");
12028                self.last_formatting_failure
12029                    .replace(error_string.lines().join(" "));
12030            }
12031        }
12032    }
12033
12034    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12035        self.lsp_server_capabilities.remove(&for_server);
12036        for lsp_data in self.lsp_data.values_mut() {
12037            lsp_data.remove_server_data(for_server);
12038        }
12039        if let Some(local) = self.as_local_mut() {
12040            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12041            local
12042                .workspace_pull_diagnostics_result_ids
12043                .remove(&for_server);
12044            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12045                buffer_servers.remove(&for_server);
12046            }
12047        }
12048    }
12049
12050    pub fn result_id_for_buffer_pull(
12051        &self,
12052        server_id: LanguageServerId,
12053        buffer_id: BufferId,
12054        registration_id: &Option<SharedString>,
12055        cx: &App,
12056    ) -> Option<SharedString> {
12057        let abs_path = self
12058            .buffer_store
12059            .read(cx)
12060            .get(buffer_id)
12061            .and_then(|b| File::from_dyn(b.read(cx).file()))
12062            .map(|f| f.abs_path(cx))?;
12063        self.as_local()?
12064            .buffer_pull_diagnostics_result_ids
12065            .get(&server_id)?
12066            .get(registration_id)?
12067            .get(&abs_path)?
12068            .clone()
12069    }
12070
12071    /// Gets all result_ids for a workspace diagnostics pull request.
12072    /// 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.
12073    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12074    pub fn result_ids_for_workspace_refresh(
12075        &self,
12076        server_id: LanguageServerId,
12077        registration_id: &Option<SharedString>,
12078    ) -> HashMap<PathBuf, SharedString> {
12079        let Some(local) = self.as_local() else {
12080            return HashMap::default();
12081        };
12082        local
12083            .workspace_pull_diagnostics_result_ids
12084            .get(&server_id)
12085            .into_iter()
12086            .filter_map(|diagnostics| diagnostics.get(registration_id))
12087            .flatten()
12088            .filter_map(|(abs_path, result_id)| {
12089                let result_id = local
12090                    .buffer_pull_diagnostics_result_ids
12091                    .get(&server_id)
12092                    .and_then(|buffer_ids_result_ids| {
12093                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12094                    })
12095                    .cloned()
12096                    .flatten()
12097                    .or_else(|| result_id.clone())?;
12098                Some((abs_path.clone(), result_id))
12099            })
12100            .collect()
12101    }
12102
12103    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12104        if let Some(LanguageServerState::Running {
12105            workspace_diagnostics_refresh_tasks,
12106            ..
12107        }) = self
12108            .as_local_mut()
12109            .and_then(|local| local.language_servers.get_mut(&server_id))
12110        {
12111            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12112                diagnostics.refresh_tx.try_send(()).ok();
12113            }
12114        }
12115    }
12116
12117    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
12118        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
12119            return;
12120        };
12121        let Some(local) = self.as_local_mut() else {
12122            return;
12123        };
12124
12125        for server_id in buffer.update(cx, |buffer, cx| {
12126            local.language_server_ids_for_buffer(buffer, cx)
12127        }) {
12128            if let Some(LanguageServerState::Running {
12129                workspace_diagnostics_refresh_tasks,
12130                ..
12131            }) = local.language_servers.get_mut(&server_id)
12132            {
12133                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12134                    diagnostics.refresh_tx.try_send(()).ok();
12135                }
12136            }
12137        }
12138    }
12139
12140    fn apply_workspace_diagnostic_report(
12141        &mut self,
12142        server_id: LanguageServerId,
12143        report: lsp::WorkspaceDiagnosticReportResult,
12144        registration_id: Option<SharedString>,
12145        cx: &mut Context<Self>,
12146    ) {
12147        let workspace_diagnostics =
12148            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12149                report,
12150                server_id,
12151                registration_id,
12152            );
12153        let mut unchanged_buffers = HashMap::default();
12154        let workspace_diagnostics_updates = workspace_diagnostics
12155            .into_iter()
12156            .filter_map(
12157                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12158                    LspPullDiagnostics::Response {
12159                        server_id,
12160                        uri,
12161                        diagnostics,
12162                        registration_id,
12163                    } => Some((
12164                        server_id,
12165                        uri,
12166                        diagnostics,
12167                        workspace_diagnostics.version,
12168                        registration_id,
12169                    )),
12170                    LspPullDiagnostics::Default => None,
12171                },
12172            )
12173            .fold(
12174                HashMap::default(),
12175                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12176                    let (result_id, diagnostics) = match diagnostics {
12177                        PulledDiagnostics::Unchanged { result_id } => {
12178                            unchanged_buffers
12179                                .entry(new_registration_id.clone())
12180                                .or_insert_with(HashSet::default)
12181                                .insert(uri.clone());
12182                            (Some(result_id), Vec::new())
12183                        }
12184                        PulledDiagnostics::Changed {
12185                            result_id,
12186                            diagnostics,
12187                        } => (result_id, diagnostics),
12188                    };
12189                    let disk_based_sources = Cow::Owned(
12190                        self.language_server_adapter_for_id(server_id)
12191                            .as_ref()
12192                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12193                            .unwrap_or(&[])
12194                            .to_vec(),
12195                    );
12196
12197                    let Some(abs_path) = uri.to_file_path().ok() else {
12198                        return acc;
12199                    };
12200                    let Some((worktree, relative_path)) =
12201                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12202                    else {
12203                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12204                        return acc;
12205                    };
12206                    let worktree_id = worktree.read(cx).id();
12207                    let project_path = ProjectPath {
12208                        worktree_id,
12209                        path: relative_path,
12210                    };
12211                    if let Some(local_lsp_store) = self.as_local_mut() {
12212                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12213                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12214                    }
12215                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12216                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12217                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12218                        acc.entry(server_id)
12219                            .or_insert_with(HashMap::default)
12220                            .entry(new_registration_id.clone())
12221                            .or_insert_with(Vec::new)
12222                            .push(DocumentDiagnosticsUpdate {
12223                                server_id,
12224                                diagnostics: lsp::PublishDiagnosticsParams {
12225                                    uri,
12226                                    diagnostics,
12227                                    version,
12228                                },
12229                                result_id,
12230                                disk_based_sources,
12231                                registration_id: new_registration_id,
12232                            });
12233                    }
12234                    acc
12235                },
12236            );
12237
12238        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12239            for (registration_id, diagnostic_updates) in diagnostic_updates {
12240                self.merge_lsp_diagnostics(
12241                    DiagnosticSourceKind::Pulled,
12242                    diagnostic_updates,
12243                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12244                        DiagnosticSourceKind::Pulled => {
12245                            old_diagnostic.registration_id != registration_id
12246                                || unchanged_buffers
12247                                    .get(&old_diagnostic.registration_id)
12248                                    .is_some_and(|unchanged_buffers| {
12249                                        unchanged_buffers.contains(&document_uri)
12250                                    })
12251                        }
12252                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12253                    },
12254                    cx,
12255                )
12256                .log_err();
12257            }
12258        }
12259    }
12260
12261    fn register_server_capabilities(
12262        &mut self,
12263        server_id: LanguageServerId,
12264        params: lsp::RegistrationParams,
12265        cx: &mut Context<Self>,
12266    ) -> anyhow::Result<()> {
12267        let server = self
12268            .language_server_for_id(server_id)
12269            .with_context(|| format!("no server {server_id} found"))?;
12270        for reg in params.registrations {
12271            match reg.method.as_str() {
12272                "workspace/didChangeWatchedFiles" => {
12273                    if let Some(options) = reg.register_options {
12274                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12275                            let caps = serde_json::from_value(options)?;
12276                            local_lsp_store
12277                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12278                            true
12279                        } else {
12280                            false
12281                        };
12282                        if notify {
12283                            notify_server_capabilities_updated(&server, cx);
12284                        }
12285                    }
12286                }
12287                "workspace/didChangeConfiguration" => {
12288                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12289                }
12290                "workspace/didChangeWorkspaceFolders" => {
12291                    // In this case register options is an empty object, we can ignore it
12292                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12293                        supported: Some(true),
12294                        change_notifications: Some(OneOf::Right(reg.id)),
12295                    };
12296                    server.update_capabilities(|capabilities| {
12297                        capabilities
12298                            .workspace
12299                            .get_or_insert_default()
12300                            .workspace_folders = Some(caps);
12301                    });
12302                    notify_server_capabilities_updated(&server, cx);
12303                }
12304                "workspace/symbol" => {
12305                    let options = parse_register_capabilities(reg)?;
12306                    server.update_capabilities(|capabilities| {
12307                        capabilities.workspace_symbol_provider = Some(options);
12308                    });
12309                    notify_server_capabilities_updated(&server, cx);
12310                }
12311                "workspace/fileOperations" => {
12312                    if let Some(options) = reg.register_options {
12313                        let caps = serde_json::from_value(options)?;
12314                        server.update_capabilities(|capabilities| {
12315                            capabilities
12316                                .workspace
12317                                .get_or_insert_default()
12318                                .file_operations = Some(caps);
12319                        });
12320                        notify_server_capabilities_updated(&server, cx);
12321                    }
12322                }
12323                "workspace/executeCommand" => {
12324                    if let Some(options) = reg.register_options {
12325                        let options = serde_json::from_value(options)?;
12326                        server.update_capabilities(|capabilities| {
12327                            capabilities.execute_command_provider = Some(options);
12328                        });
12329                        notify_server_capabilities_updated(&server, cx);
12330                    }
12331                }
12332                "textDocument/rangeFormatting" => {
12333                    let options = parse_register_capabilities(reg)?;
12334                    server.update_capabilities(|capabilities| {
12335                        capabilities.document_range_formatting_provider = Some(options);
12336                    });
12337                    notify_server_capabilities_updated(&server, cx);
12338                }
12339                "textDocument/onTypeFormatting" => {
12340                    if let Some(options) = reg
12341                        .register_options
12342                        .map(serde_json::from_value)
12343                        .transpose()?
12344                    {
12345                        server.update_capabilities(|capabilities| {
12346                            capabilities.document_on_type_formatting_provider = Some(options);
12347                        });
12348                        notify_server_capabilities_updated(&server, cx);
12349                    }
12350                }
12351                "textDocument/formatting" => {
12352                    let options = parse_register_capabilities(reg)?;
12353                    server.update_capabilities(|capabilities| {
12354                        capabilities.document_formatting_provider = Some(options);
12355                    });
12356                    notify_server_capabilities_updated(&server, cx);
12357                }
12358                "textDocument/rename" => {
12359                    let options = parse_register_capabilities(reg)?;
12360                    server.update_capabilities(|capabilities| {
12361                        capabilities.rename_provider = Some(options);
12362                    });
12363                    notify_server_capabilities_updated(&server, cx);
12364                }
12365                "textDocument/inlayHint" => {
12366                    let options = parse_register_capabilities(reg)?;
12367                    server.update_capabilities(|capabilities| {
12368                        capabilities.inlay_hint_provider = Some(options);
12369                    });
12370                    notify_server_capabilities_updated(&server, cx);
12371                }
12372                "textDocument/documentSymbol" => {
12373                    let options = parse_register_capabilities(reg)?;
12374                    server.update_capabilities(|capabilities| {
12375                        capabilities.document_symbol_provider = Some(options);
12376                    });
12377                    notify_server_capabilities_updated(&server, cx);
12378                }
12379                "textDocument/codeAction" => {
12380                    let options = parse_register_capabilities(reg)?;
12381                    let provider = match options {
12382                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12383                        OneOf::Right(caps) => caps,
12384                    };
12385                    server.update_capabilities(|capabilities| {
12386                        capabilities.code_action_provider = Some(provider);
12387                    });
12388                    notify_server_capabilities_updated(&server, cx);
12389                }
12390                "textDocument/definition" => {
12391                    let options = parse_register_capabilities(reg)?;
12392                    server.update_capabilities(|capabilities| {
12393                        capabilities.definition_provider = Some(options);
12394                    });
12395                    notify_server_capabilities_updated(&server, cx);
12396                }
12397                "textDocument/completion" => {
12398                    if let Some(caps) = reg
12399                        .register_options
12400                        .map(serde_json::from_value::<CompletionOptions>)
12401                        .transpose()?
12402                    {
12403                        server.update_capabilities(|capabilities| {
12404                            capabilities.completion_provider = Some(caps.clone());
12405                        });
12406
12407                        if let Some(local) = self.as_local() {
12408                            let mut buffers_with_language_server = Vec::new();
12409                            for handle in self.buffer_store.read(cx).buffers() {
12410                                let buffer_id = handle.read(cx).remote_id();
12411                                if local
12412                                    .buffers_opened_in_servers
12413                                    .get(&buffer_id)
12414                                    .filter(|s| s.contains(&server_id))
12415                                    .is_some()
12416                                {
12417                                    buffers_with_language_server.push(handle);
12418                                }
12419                            }
12420                            let triggers = caps
12421                                .trigger_characters
12422                                .unwrap_or_default()
12423                                .into_iter()
12424                                .collect::<BTreeSet<_>>();
12425                            for handle in buffers_with_language_server {
12426                                let triggers = triggers.clone();
12427                                let _ = handle.update(cx, move |buffer, cx| {
12428                                    buffer.set_completion_triggers(server_id, triggers, cx);
12429                                });
12430                            }
12431                        }
12432                        notify_server_capabilities_updated(&server, cx);
12433                    }
12434                }
12435                "textDocument/hover" => {
12436                    let options = parse_register_capabilities(reg)?;
12437                    let provider = match options {
12438                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12439                        OneOf::Right(caps) => caps,
12440                    };
12441                    server.update_capabilities(|capabilities| {
12442                        capabilities.hover_provider = Some(provider);
12443                    });
12444                    notify_server_capabilities_updated(&server, cx);
12445                }
12446                "textDocument/signatureHelp" => {
12447                    if let Some(caps) = reg
12448                        .register_options
12449                        .map(serde_json::from_value)
12450                        .transpose()?
12451                    {
12452                        server.update_capabilities(|capabilities| {
12453                            capabilities.signature_help_provider = Some(caps);
12454                        });
12455                        notify_server_capabilities_updated(&server, cx);
12456                    }
12457                }
12458                "textDocument/didChange" => {
12459                    if let Some(sync_kind) = reg
12460                        .register_options
12461                        .and_then(|opts| opts.get("syncKind").cloned())
12462                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12463                        .transpose()?
12464                    {
12465                        server.update_capabilities(|capabilities| {
12466                            let mut sync_options =
12467                                Self::take_text_document_sync_options(capabilities);
12468                            sync_options.change = Some(sync_kind);
12469                            capabilities.text_document_sync =
12470                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12471                        });
12472                        notify_server_capabilities_updated(&server, cx);
12473                    }
12474                }
12475                "textDocument/didSave" => {
12476                    if let Some(include_text) = reg
12477                        .register_options
12478                        .map(|opts| {
12479                            let transpose = opts
12480                                .get("includeText")
12481                                .cloned()
12482                                .map(serde_json::from_value::<Option<bool>>)
12483                                .transpose();
12484                            match transpose {
12485                                Ok(value) => Ok(value.flatten()),
12486                                Err(e) => Err(e),
12487                            }
12488                        })
12489                        .transpose()?
12490                    {
12491                        server.update_capabilities(|capabilities| {
12492                            let mut sync_options =
12493                                Self::take_text_document_sync_options(capabilities);
12494                            sync_options.save =
12495                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12496                                    include_text,
12497                                }));
12498                            capabilities.text_document_sync =
12499                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12500                        });
12501                        notify_server_capabilities_updated(&server, cx);
12502                    }
12503                }
12504                "textDocument/codeLens" => {
12505                    if let Some(caps) = reg
12506                        .register_options
12507                        .map(serde_json::from_value)
12508                        .transpose()?
12509                    {
12510                        server.update_capabilities(|capabilities| {
12511                            capabilities.code_lens_provider = Some(caps);
12512                        });
12513                        notify_server_capabilities_updated(&server, cx);
12514                    }
12515                }
12516                "textDocument/diagnostic" => {
12517                    if let Some(caps) = reg
12518                        .register_options
12519                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12520                        .transpose()?
12521                    {
12522                        let local = self
12523                            .as_local_mut()
12524                            .context("Expected LSP Store to be local")?;
12525                        let state = local
12526                            .language_servers
12527                            .get_mut(&server_id)
12528                            .context("Could not obtain Language Servers state")?;
12529                        local
12530                            .language_server_dynamic_registrations
12531                            .entry(server_id)
12532                            .or_default()
12533                            .diagnostics
12534                            .insert(Some(reg.id.clone()), caps.clone());
12535
12536                        let supports_workspace_diagnostics =
12537                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12538                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12539                                    diagnostic_options.workspace_diagnostics
12540                                }
12541                                DiagnosticServerCapabilities::RegistrationOptions(
12542                                    diagnostic_registration_options,
12543                                ) => {
12544                                    diagnostic_registration_options
12545                                        .diagnostic_options
12546                                        .workspace_diagnostics
12547                                }
12548                            };
12549
12550                        if supports_workspace_diagnostics(&caps) {
12551                            if let LanguageServerState::Running {
12552                                workspace_diagnostics_refresh_tasks,
12553                                ..
12554                            } = state
12555                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12556                                    Some(reg.id.clone()),
12557                                    caps.clone(),
12558                                    server.clone(),
12559                                    cx,
12560                                )
12561                            {
12562                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12563                            }
12564                        }
12565
12566                        server.update_capabilities(|capabilities| {
12567                            capabilities.diagnostic_provider = Some(caps);
12568                        });
12569
12570                        notify_server_capabilities_updated(&server, cx);
12571                    }
12572                }
12573                "textDocument/documentColor" => {
12574                    let options = parse_register_capabilities(reg)?;
12575                    let provider = match options {
12576                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12577                        OneOf::Right(caps) => caps,
12578                    };
12579                    server.update_capabilities(|capabilities| {
12580                        capabilities.color_provider = Some(provider);
12581                    });
12582                    notify_server_capabilities_updated(&server, cx);
12583                }
12584                _ => log::warn!("unhandled capability registration: {reg:?}"),
12585            }
12586        }
12587
12588        Ok(())
12589    }
12590
12591    fn unregister_server_capabilities(
12592        &mut self,
12593        server_id: LanguageServerId,
12594        params: lsp::UnregistrationParams,
12595        cx: &mut Context<Self>,
12596    ) -> anyhow::Result<()> {
12597        let server = self
12598            .language_server_for_id(server_id)
12599            .with_context(|| format!("no server {server_id} found"))?;
12600        for unreg in params.unregisterations.iter() {
12601            match unreg.method.as_str() {
12602                "workspace/didChangeWatchedFiles" => {
12603                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12604                        local_lsp_store
12605                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12606                        true
12607                    } else {
12608                        false
12609                    };
12610                    if notify {
12611                        notify_server_capabilities_updated(&server, cx);
12612                    }
12613                }
12614                "workspace/didChangeConfiguration" => {
12615                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12616                }
12617                "workspace/didChangeWorkspaceFolders" => {
12618                    server.update_capabilities(|capabilities| {
12619                        capabilities
12620                            .workspace
12621                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12622                                workspace_folders: None,
12623                                file_operations: None,
12624                            })
12625                            .workspace_folders = None;
12626                    });
12627                    notify_server_capabilities_updated(&server, cx);
12628                }
12629                "workspace/symbol" => {
12630                    server.update_capabilities(|capabilities| {
12631                        capabilities.workspace_symbol_provider = None
12632                    });
12633                    notify_server_capabilities_updated(&server, cx);
12634                }
12635                "workspace/fileOperations" => {
12636                    server.update_capabilities(|capabilities| {
12637                        capabilities
12638                            .workspace
12639                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12640                                workspace_folders: None,
12641                                file_operations: None,
12642                            })
12643                            .file_operations = None;
12644                    });
12645                    notify_server_capabilities_updated(&server, cx);
12646                }
12647                "workspace/executeCommand" => {
12648                    server.update_capabilities(|capabilities| {
12649                        capabilities.execute_command_provider = None;
12650                    });
12651                    notify_server_capabilities_updated(&server, cx);
12652                }
12653                "textDocument/rangeFormatting" => {
12654                    server.update_capabilities(|capabilities| {
12655                        capabilities.document_range_formatting_provider = None
12656                    });
12657                    notify_server_capabilities_updated(&server, cx);
12658                }
12659                "textDocument/onTypeFormatting" => {
12660                    server.update_capabilities(|capabilities| {
12661                        capabilities.document_on_type_formatting_provider = None;
12662                    });
12663                    notify_server_capabilities_updated(&server, cx);
12664                }
12665                "textDocument/formatting" => {
12666                    server.update_capabilities(|capabilities| {
12667                        capabilities.document_formatting_provider = None;
12668                    });
12669                    notify_server_capabilities_updated(&server, cx);
12670                }
12671                "textDocument/rename" => {
12672                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12673                    notify_server_capabilities_updated(&server, cx);
12674                }
12675                "textDocument/codeAction" => {
12676                    server.update_capabilities(|capabilities| {
12677                        capabilities.code_action_provider = None;
12678                    });
12679                    notify_server_capabilities_updated(&server, cx);
12680                }
12681                "textDocument/definition" => {
12682                    server.update_capabilities(|capabilities| {
12683                        capabilities.definition_provider = None;
12684                    });
12685                    notify_server_capabilities_updated(&server, cx);
12686                }
12687                "textDocument/completion" => {
12688                    server.update_capabilities(|capabilities| {
12689                        capabilities.completion_provider = None;
12690                    });
12691                    notify_server_capabilities_updated(&server, cx);
12692                }
12693                "textDocument/hover" => {
12694                    server.update_capabilities(|capabilities| {
12695                        capabilities.hover_provider = None;
12696                    });
12697                    notify_server_capabilities_updated(&server, cx);
12698                }
12699                "textDocument/signatureHelp" => {
12700                    server.update_capabilities(|capabilities| {
12701                        capabilities.signature_help_provider = None;
12702                    });
12703                    notify_server_capabilities_updated(&server, cx);
12704                }
12705                "textDocument/didChange" => {
12706                    server.update_capabilities(|capabilities| {
12707                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12708                        sync_options.change = None;
12709                        capabilities.text_document_sync =
12710                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12711                    });
12712                    notify_server_capabilities_updated(&server, cx);
12713                }
12714                "textDocument/didSave" => {
12715                    server.update_capabilities(|capabilities| {
12716                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12717                        sync_options.save = None;
12718                        capabilities.text_document_sync =
12719                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12720                    });
12721                    notify_server_capabilities_updated(&server, cx);
12722                }
12723                "textDocument/codeLens" => {
12724                    server.update_capabilities(|capabilities| {
12725                        capabilities.code_lens_provider = None;
12726                    });
12727                    notify_server_capabilities_updated(&server, cx);
12728                }
12729                "textDocument/diagnostic" => {
12730                    let local = self
12731                        .as_local_mut()
12732                        .context("Expected LSP Store to be local")?;
12733
12734                    let state = local
12735                        .language_servers
12736                        .get_mut(&server_id)
12737                        .context("Could not obtain Language Servers state")?;
12738                    let registrations = local
12739                        .language_server_dynamic_registrations
12740                        .get_mut(&server_id)
12741                        .with_context(|| {
12742                            format!("Expected dynamic registration to exist for server {server_id}")
12743                        })?;
12744                    registrations.diagnostics
12745                        .remove(&Some(unreg.id.clone()))
12746                        .with_context(|| format!(
12747                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12748                            unreg.id)
12749                        )?;
12750                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12751
12752                    if let LanguageServerState::Running {
12753                        workspace_diagnostics_refresh_tasks,
12754                        ..
12755                    } = state
12756                    {
12757                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12758                    }
12759
12760                    if removed_last_diagnostic_provider {
12761                        server.update_capabilities(|capabilities| {
12762                            debug_assert!(capabilities.diagnostic_provider.is_some());
12763                            capabilities.diagnostic_provider = None;
12764                        });
12765                    }
12766
12767                    notify_server_capabilities_updated(&server, cx);
12768                }
12769                "textDocument/documentColor" => {
12770                    server.update_capabilities(|capabilities| {
12771                        capabilities.color_provider = None;
12772                    });
12773                    notify_server_capabilities_updated(&server, cx);
12774                }
12775                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12776            }
12777        }
12778
12779        Ok(())
12780    }
12781
12782    async fn deduplicate_range_based_lsp_requests<T>(
12783        lsp_store: &Entity<Self>,
12784        server_id: Option<LanguageServerId>,
12785        lsp_request_id: LspRequestId,
12786        proto_request: &T::ProtoRequest,
12787        range: Range<Anchor>,
12788        cx: &mut AsyncApp,
12789    ) -> Result<()>
12790    where
12791        T: LspCommand,
12792        T::ProtoRequest: proto::LspRequestMessage,
12793    {
12794        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12795        let version = deserialize_version(proto_request.buffer_version());
12796        let buffer = lsp_store.update(cx, |this, cx| {
12797            this.buffer_store.read(cx).get_existing(buffer_id)
12798        })??;
12799        buffer
12800            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12801            .await?;
12802        lsp_store.update(cx, |lsp_store, cx| {
12803            let buffer_snapshot = buffer.read(cx).snapshot();
12804            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12805            let chunks_queried_for = lsp_data
12806                .inlay_hints
12807                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12808                .collect::<Vec<_>>();
12809            match chunks_queried_for.as_slice() {
12810                &[chunk] => {
12811                    let key = LspKey {
12812                        request_type: TypeId::of::<T>(),
12813                        server_queried: server_id,
12814                    };
12815                    let previous_request = lsp_data
12816                        .chunk_lsp_requests
12817                        .entry(key)
12818                        .or_default()
12819                        .insert(chunk, lsp_request_id);
12820                    if let Some((previous_request, running_requests)) =
12821                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12822                    {
12823                        running_requests.remove(&previous_request);
12824                    }
12825                }
12826                _ambiguous_chunks => {
12827                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12828                    // there, a buffer version-based check will be performed and outdated requests discarded.
12829                }
12830            }
12831            anyhow::Ok(())
12832        })??;
12833
12834        Ok(())
12835    }
12836
12837    async fn query_lsp_locally<T>(
12838        lsp_store: Entity<Self>,
12839        for_server_id: Option<LanguageServerId>,
12840        sender_id: proto::PeerId,
12841        lsp_request_id: LspRequestId,
12842        proto_request: T::ProtoRequest,
12843        position: Option<Anchor>,
12844        cx: &mut AsyncApp,
12845    ) -> Result<()>
12846    where
12847        T: LspCommand + Clone,
12848        T::ProtoRequest: proto::LspRequestMessage,
12849        <T::ProtoRequest as proto::RequestMessage>::Response:
12850            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12851    {
12852        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12853        let version = deserialize_version(proto_request.buffer_version());
12854        let buffer = lsp_store.update(cx, |this, cx| {
12855            this.buffer_store.read(cx).get_existing(buffer_id)
12856        })??;
12857        buffer
12858            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12859            .await?;
12860        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12861        let request =
12862            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12863        let key = LspKey {
12864            request_type: TypeId::of::<T>(),
12865            server_queried: for_server_id,
12866        };
12867        lsp_store.update(cx, |lsp_store, cx| {
12868            let request_task = match for_server_id {
12869                Some(server_id) => {
12870                    let server_task = lsp_store.request_lsp(
12871                        buffer.clone(),
12872                        LanguageServerToQuery::Other(server_id),
12873                        request.clone(),
12874                        cx,
12875                    );
12876                    cx.background_spawn(async move {
12877                        let mut responses = Vec::new();
12878                        match server_task.await {
12879                            Ok(response) => responses.push((server_id, response)),
12880                            // rust-analyzer likes to error with this when its still loading up
12881                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12882                            Err(e) => log::error!(
12883                                "Error handling response for request {request:?}: {e:#}"
12884                            ),
12885                        }
12886                        responses
12887                    })
12888                }
12889                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12890            };
12891            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12892            if T::ProtoRequest::stop_previous_requests() {
12893                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12894                    lsp_requests.clear();
12895                }
12896            }
12897            lsp_data.lsp_requests.entry(key).or_default().insert(
12898                lsp_request_id,
12899                cx.spawn(async move |lsp_store, cx| {
12900                    let response = request_task.await;
12901                    lsp_store
12902                        .update(cx, |lsp_store, cx| {
12903                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12904                            {
12905                                let response = response
12906                                    .into_iter()
12907                                    .map(|(server_id, response)| {
12908                                        (
12909                                            server_id.to_proto(),
12910                                            T::response_to_proto(
12911                                                response,
12912                                                lsp_store,
12913                                                sender_id,
12914                                                &buffer_version,
12915                                                cx,
12916                                            )
12917                                            .into(),
12918                                        )
12919                                    })
12920                                    .collect::<HashMap<_, _>>();
12921                                match client.send_lsp_response::<T::ProtoRequest>(
12922                                    project_id,
12923                                    lsp_request_id,
12924                                    response,
12925                                ) {
12926                                    Ok(()) => {}
12927                                    Err(e) => {
12928                                        log::error!("Failed to send LSP response: {e:#}",)
12929                                    }
12930                                }
12931                            }
12932                        })
12933                        .ok();
12934                }),
12935            );
12936        })?;
12937        Ok(())
12938    }
12939
12940    fn take_text_document_sync_options(
12941        capabilities: &mut lsp::ServerCapabilities,
12942    ) -> lsp::TextDocumentSyncOptions {
12943        match capabilities.text_document_sync.take() {
12944            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12945            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12946                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12947                sync_options.change = Some(sync_kind);
12948                sync_options
12949            }
12950            None => lsp::TextDocumentSyncOptions::default(),
12951        }
12952    }
12953
12954    #[cfg(any(test, feature = "test-support"))]
12955    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12956        Some(
12957            self.lsp_data
12958                .get_mut(&buffer_id)?
12959                .code_lens
12960                .take()?
12961                .update
12962                .take()?
12963                .1,
12964        )
12965    }
12966
12967    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12968        self.downstream_client.clone()
12969    }
12970
12971    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12972        self.worktree_store.clone()
12973    }
12974
12975    /// Gets what's stored in the LSP data for the given buffer.
12976    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12977        self.lsp_data.get_mut(&buffer_id)
12978    }
12979
12980    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12981    /// new [`BufferLspData`] will be created to replace the previous state.
12982    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
12983        let (buffer_id, buffer_version) =
12984            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
12985        let lsp_data = self
12986            .lsp_data
12987            .entry(buffer_id)
12988            .or_insert_with(|| BufferLspData::new(buffer, cx));
12989        if buffer_version.changed_since(&lsp_data.buffer_version) {
12990            *lsp_data = BufferLspData::new(buffer, cx);
12991        }
12992        lsp_data
12993    }
12994}
12995
12996// Registration with registerOptions as null, should fallback to true.
12997// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12998fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12999    reg: lsp::Registration,
13000) -> Result<OneOf<bool, T>> {
13001    Ok(match reg.register_options {
13002        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13003        None => OneOf::Left(true),
13004    })
13005}
13006
13007fn subscribe_to_binary_statuses(
13008    languages: &Arc<LanguageRegistry>,
13009    cx: &mut Context<'_, LspStore>,
13010) -> Task<()> {
13011    let mut server_statuses = languages.language_server_binary_statuses();
13012    cx.spawn(async move |lsp_store, cx| {
13013        while let Some((server_name, binary_status)) = server_statuses.next().await {
13014            if lsp_store
13015                .update(cx, |_, cx| {
13016                    let mut message = None;
13017                    let binary_status = match binary_status {
13018                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13019                        BinaryStatus::CheckingForUpdate => {
13020                            proto::ServerBinaryStatus::CheckingForUpdate
13021                        }
13022                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13023                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13024                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13025                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13026                        BinaryStatus::Failed { error } => {
13027                            message = Some(error);
13028                            proto::ServerBinaryStatus::Failed
13029                        }
13030                    };
13031                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13032                        // Binary updates are about the binary that might not have any language server id at that point.
13033                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13034                        language_server_id: LanguageServerId(0),
13035                        name: Some(server_name),
13036                        message: proto::update_language_server::Variant::StatusUpdate(
13037                            proto::StatusUpdate {
13038                                message,
13039                                status: Some(proto::status_update::Status::Binary(
13040                                    binary_status as i32,
13041                                )),
13042                            },
13043                        ),
13044                    });
13045                })
13046                .is_err()
13047            {
13048                break;
13049            }
13050        }
13051    })
13052}
13053
13054fn lsp_workspace_diagnostics_refresh(
13055    registration_id: Option<String>,
13056    options: DiagnosticServerCapabilities,
13057    server: Arc<LanguageServer>,
13058    cx: &mut Context<'_, LspStore>,
13059) -> Option<WorkspaceRefreshTask> {
13060    let identifier = workspace_diagnostic_identifier(&options)?;
13061    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13062
13063    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13064    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13065    refresh_tx.try_send(()).ok();
13066
13067    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13068        let mut attempts = 0;
13069        let max_attempts = 50;
13070        let mut requests = 0;
13071
13072        loop {
13073            let Some(()) = refresh_rx.recv().await else {
13074                return;
13075            };
13076
13077            'request: loop {
13078                requests += 1;
13079                if attempts > max_attempts {
13080                    log::error!(
13081                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13082                    );
13083                    return;
13084                }
13085                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13086                cx.background_executor()
13087                    .timer(Duration::from_millis(backoff_millis))
13088                    .await;
13089                attempts += 1;
13090
13091                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13092                    lsp_store
13093                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13094                        .into_iter()
13095                        .filter_map(|(abs_path, result_id)| {
13096                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13097                            Some(lsp::PreviousResultId {
13098                                uri,
13099                                value: result_id.to_string(),
13100                            })
13101                        })
13102                        .collect()
13103                }) else {
13104                    return;
13105                };
13106
13107                let token = if let Some(registration_id) = &registration_id {
13108                    format!(
13109                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13110                        server.server_id(),
13111                    )
13112                } else {
13113                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13114                };
13115
13116                progress_rx.try_recv().ok();
13117                let timer =
13118                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13119                let progress = pin!(progress_rx.recv().fuse());
13120                let response_result = server
13121                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13122                        lsp::WorkspaceDiagnosticParams {
13123                            previous_result_ids,
13124                            identifier: identifier.clone(),
13125                            work_done_progress_params: Default::default(),
13126                            partial_result_params: lsp::PartialResultParams {
13127                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13128                            },
13129                        },
13130                        select(timer, progress).then(|either| match either {
13131                            Either::Left((message, ..)) => ready(message).left_future(),
13132                            Either::Right(..) => pending::<String>().right_future(),
13133                        }),
13134                    )
13135                    .await;
13136
13137                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13138                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13139                match response_result {
13140                    ConnectionResult::Timeout => {
13141                        log::error!("Timeout during workspace diagnostics pull");
13142                        continue 'request;
13143                    }
13144                    ConnectionResult::ConnectionReset => {
13145                        log::error!("Server closed a workspace diagnostics pull request");
13146                        continue 'request;
13147                    }
13148                    ConnectionResult::Result(Err(e)) => {
13149                        log::error!("Error during workspace diagnostics pull: {e:#}");
13150                        break 'request;
13151                    }
13152                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13153                        attempts = 0;
13154                        if lsp_store
13155                            .update(cx, |lsp_store, cx| {
13156                                lsp_store.apply_workspace_diagnostic_report(
13157                                    server.server_id(),
13158                                    pulled_diagnostics,
13159                                    registration_id_shared.clone(),
13160                                    cx,
13161                                )
13162                            })
13163                            .is_err()
13164                        {
13165                            return;
13166                        }
13167                        break 'request;
13168                    }
13169                }
13170            }
13171        }
13172    });
13173
13174    Some(WorkspaceRefreshTask {
13175        refresh_tx,
13176        progress_tx,
13177        task: workspace_query_language_server,
13178    })
13179}
13180
13181fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13182    match &options {
13183        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13184            diagnostic_options.identifier.clone()
13185        }
13186        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13187            let diagnostic_options = &registration_options.diagnostic_options;
13188            diagnostic_options.identifier.clone()
13189        }
13190    }
13191}
13192
13193fn workspace_diagnostic_identifier(
13194    options: &DiagnosticServerCapabilities,
13195) -> Option<Option<String>> {
13196    match &options {
13197        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13198            if !diagnostic_options.workspace_diagnostics {
13199                return None;
13200            }
13201            Some(diagnostic_options.identifier.clone())
13202        }
13203        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13204            let diagnostic_options = &registration_options.diagnostic_options;
13205            if !diagnostic_options.workspace_diagnostics {
13206                return None;
13207            }
13208            Some(diagnostic_options.identifier.clone())
13209        }
13210    }
13211}
13212
13213fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13214    let CompletionSource::BufferWord {
13215        word_range,
13216        resolved,
13217    } = &mut completion.source
13218    else {
13219        return;
13220    };
13221    if *resolved {
13222        return;
13223    }
13224
13225    if completion.new_text
13226        != snapshot
13227            .text_for_range(word_range.clone())
13228            .collect::<String>()
13229    {
13230        return;
13231    }
13232
13233    let mut offset = 0;
13234    for chunk in snapshot.chunks(word_range.clone(), true) {
13235        let end_offset = offset + chunk.text.len();
13236        if let Some(highlight_id) = chunk.syntax_highlight_id {
13237            completion
13238                .label
13239                .runs
13240                .push((offset..end_offset, highlight_id));
13241        }
13242        offset = end_offset;
13243    }
13244    *resolved = true;
13245}
13246
13247impl EventEmitter<LspStoreEvent> for LspStore {}
13248
13249fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13250    hover
13251        .contents
13252        .retain(|hover_block| !hover_block.text.trim().is_empty());
13253    if hover.contents.is_empty() {
13254        None
13255    } else {
13256        Some(hover)
13257    }
13258}
13259
13260async fn populate_labels_for_completions(
13261    new_completions: Vec<CoreCompletion>,
13262    language: Option<Arc<Language>>,
13263    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13264) -> Vec<Completion> {
13265    let lsp_completions = new_completions
13266        .iter()
13267        .filter_map(|new_completion| {
13268            new_completion
13269                .source
13270                .lsp_completion(true)
13271                .map(|lsp_completion| lsp_completion.into_owned())
13272        })
13273        .collect::<Vec<_>>();
13274
13275    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13276        lsp_adapter
13277            .labels_for_completions(&lsp_completions, language)
13278            .await
13279            .log_err()
13280            .unwrap_or_default()
13281    } else {
13282        Vec::new()
13283    }
13284    .into_iter()
13285    .fuse();
13286
13287    let mut completions = Vec::new();
13288    for completion in new_completions {
13289        match completion.source.lsp_completion(true) {
13290            Some(lsp_completion) => {
13291                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13292
13293                let mut label = labels.next().flatten().unwrap_or_else(|| {
13294                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13295                });
13296                ensure_uniform_list_compatible_label(&mut label);
13297                completions.push(Completion {
13298                    label,
13299                    documentation,
13300                    replace_range: completion.replace_range,
13301                    new_text: completion.new_text,
13302                    insert_text_mode: lsp_completion.insert_text_mode,
13303                    source: completion.source,
13304                    icon_path: None,
13305                    confirm: None,
13306                    match_start: None,
13307                    snippet_deduplication_key: None,
13308                });
13309            }
13310            None => {
13311                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13312                ensure_uniform_list_compatible_label(&mut label);
13313                completions.push(Completion {
13314                    label,
13315                    documentation: None,
13316                    replace_range: completion.replace_range,
13317                    new_text: completion.new_text,
13318                    source: completion.source,
13319                    insert_text_mode: None,
13320                    icon_path: None,
13321                    confirm: None,
13322                    match_start: None,
13323                    snippet_deduplication_key: None,
13324                });
13325            }
13326        }
13327    }
13328    completions
13329}
13330
13331#[derive(Debug)]
13332pub enum LanguageServerToQuery {
13333    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13334    FirstCapable,
13335    /// Query a specific language server.
13336    Other(LanguageServerId),
13337}
13338
13339#[derive(Default)]
13340struct RenamePathsWatchedForServer {
13341    did_rename: Vec<RenameActionPredicate>,
13342    will_rename: Vec<RenameActionPredicate>,
13343}
13344
13345impl RenamePathsWatchedForServer {
13346    fn with_did_rename_patterns(
13347        mut self,
13348        did_rename: Option<&FileOperationRegistrationOptions>,
13349    ) -> Self {
13350        if let Some(did_rename) = did_rename {
13351            self.did_rename = did_rename
13352                .filters
13353                .iter()
13354                .filter_map(|filter| filter.try_into().log_err())
13355                .collect();
13356        }
13357        self
13358    }
13359    fn with_will_rename_patterns(
13360        mut self,
13361        will_rename: Option<&FileOperationRegistrationOptions>,
13362    ) -> Self {
13363        if let Some(will_rename) = will_rename {
13364            self.will_rename = will_rename
13365                .filters
13366                .iter()
13367                .filter_map(|filter| filter.try_into().log_err())
13368                .collect();
13369        }
13370        self
13371    }
13372
13373    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13374        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13375    }
13376    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13377        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13378    }
13379}
13380
13381impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13382    type Error = globset::Error;
13383    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13384        Ok(Self {
13385            kind: ops.pattern.matches.clone(),
13386            glob: GlobBuilder::new(&ops.pattern.glob)
13387                .case_insensitive(
13388                    ops.pattern
13389                        .options
13390                        .as_ref()
13391                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13392                )
13393                .build()?
13394                .compile_matcher(),
13395        })
13396    }
13397}
13398struct RenameActionPredicate {
13399    glob: GlobMatcher,
13400    kind: Option<FileOperationPatternKind>,
13401}
13402
13403impl RenameActionPredicate {
13404    // Returns true if language server should be notified
13405    fn eval(&self, path: &str, is_dir: bool) -> bool {
13406        self.kind.as_ref().is_none_or(|kind| {
13407            let expected_kind = if is_dir {
13408                FileOperationPatternKind::Folder
13409            } else {
13410                FileOperationPatternKind::File
13411            };
13412            kind == &expected_kind
13413        }) && self.glob.is_match(path)
13414    }
13415}
13416
13417#[derive(Default)]
13418struct LanguageServerWatchedPaths {
13419    worktree_paths: HashMap<WorktreeId, GlobSet>,
13420    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13421}
13422
13423#[derive(Default)]
13424struct LanguageServerWatchedPathsBuilder {
13425    worktree_paths: HashMap<WorktreeId, GlobSet>,
13426    abs_paths: HashMap<Arc<Path>, GlobSet>,
13427}
13428
13429impl LanguageServerWatchedPathsBuilder {
13430    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13431        self.worktree_paths.insert(worktree_id, glob_set);
13432    }
13433    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13434        self.abs_paths.insert(path, glob_set);
13435    }
13436    fn build(
13437        self,
13438        fs: Arc<dyn Fs>,
13439        language_server_id: LanguageServerId,
13440        cx: &mut Context<LspStore>,
13441    ) -> LanguageServerWatchedPaths {
13442        let lsp_store = cx.weak_entity();
13443
13444        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13445        let abs_paths = self
13446            .abs_paths
13447            .into_iter()
13448            .map(|(abs_path, globset)| {
13449                let task = cx.spawn({
13450                    let abs_path = abs_path.clone();
13451                    let fs = fs.clone();
13452
13453                    let lsp_store = lsp_store.clone();
13454                    async move |_, cx| {
13455                        maybe!(async move {
13456                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13457                            while let Some(update) = push_updates.0.next().await {
13458                                let action = lsp_store
13459                                    .update(cx, |this, _| {
13460                                        let Some(local) = this.as_local() else {
13461                                            return ControlFlow::Break(());
13462                                        };
13463                                        let Some(watcher) = local
13464                                            .language_server_watched_paths
13465                                            .get(&language_server_id)
13466                                        else {
13467                                            return ControlFlow::Break(());
13468                                        };
13469                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13470                                            "Watched abs path is not registered with a watcher",
13471                                        );
13472                                        let matching_entries = update
13473                                            .into_iter()
13474                                            .filter(|event| globs.is_match(&event.path))
13475                                            .collect::<Vec<_>>();
13476                                        this.lsp_notify_abs_paths_changed(
13477                                            language_server_id,
13478                                            matching_entries,
13479                                        );
13480                                        ControlFlow::Continue(())
13481                                    })
13482                                    .ok()?;
13483
13484                                if action.is_break() {
13485                                    break;
13486                                }
13487                            }
13488                            Some(())
13489                        })
13490                        .await;
13491                    }
13492                });
13493                (abs_path, (globset, task))
13494            })
13495            .collect();
13496        LanguageServerWatchedPaths {
13497            worktree_paths: self.worktree_paths,
13498            abs_paths,
13499        }
13500    }
13501}
13502
13503struct LspBufferSnapshot {
13504    version: i32,
13505    snapshot: TextBufferSnapshot,
13506}
13507
13508/// A prompt requested by LSP server.
13509#[derive(Clone, Debug)]
13510pub struct LanguageServerPromptRequest {
13511    pub level: PromptLevel,
13512    pub message: String,
13513    pub actions: Vec<MessageActionItem>,
13514    pub lsp_name: String,
13515    pub(crate) response_channel: Sender<MessageActionItem>,
13516}
13517
13518impl LanguageServerPromptRequest {
13519    pub async fn respond(self, index: usize) -> Option<()> {
13520        if let Some(response) = self.actions.into_iter().nth(index) {
13521            self.response_channel.send(response).await.ok()
13522        } else {
13523            None
13524        }
13525    }
13526}
13527impl PartialEq for LanguageServerPromptRequest {
13528    fn eq(&self, other: &Self) -> bool {
13529        self.message == other.message && self.actions == other.actions
13530    }
13531}
13532
13533#[derive(Clone, Debug, PartialEq)]
13534pub enum LanguageServerLogType {
13535    Log(MessageType),
13536    Trace { verbose_info: Option<String> },
13537    Rpc { received: bool },
13538}
13539
13540impl LanguageServerLogType {
13541    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13542        match self {
13543            Self::Log(log_type) => {
13544                use proto::log_message::LogLevel;
13545                let level = match *log_type {
13546                    MessageType::ERROR => LogLevel::Error,
13547                    MessageType::WARNING => LogLevel::Warning,
13548                    MessageType::INFO => LogLevel::Info,
13549                    MessageType::LOG => LogLevel::Log,
13550                    other => {
13551                        log::warn!("Unknown lsp log message type: {other:?}");
13552                        LogLevel::Log
13553                    }
13554                };
13555                proto::language_server_log::LogType::Log(proto::LogMessage {
13556                    level: level as i32,
13557                })
13558            }
13559            Self::Trace { verbose_info } => {
13560                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13561                    verbose_info: verbose_info.to_owned(),
13562                })
13563            }
13564            Self::Rpc { received } => {
13565                let kind = if *received {
13566                    proto::rpc_message::Kind::Received
13567                } else {
13568                    proto::rpc_message::Kind::Sent
13569                };
13570                let kind = kind as i32;
13571                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13572            }
13573        }
13574    }
13575
13576    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13577        use proto::log_message::LogLevel;
13578        use proto::rpc_message;
13579        match log_type {
13580            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13581                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13582                    LogLevel::Error => MessageType::ERROR,
13583                    LogLevel::Warning => MessageType::WARNING,
13584                    LogLevel::Info => MessageType::INFO,
13585                    LogLevel::Log => MessageType::LOG,
13586                },
13587            ),
13588            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13589                verbose_info: trace_message.verbose_info,
13590            },
13591            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13592                received: match rpc_message::Kind::from_i32(message.kind)
13593                    .unwrap_or(rpc_message::Kind::Received)
13594                {
13595                    rpc_message::Kind::Received => true,
13596                    rpc_message::Kind::Sent => false,
13597                },
13598            },
13599        }
13600    }
13601}
13602
13603pub struct WorkspaceRefreshTask {
13604    refresh_tx: mpsc::Sender<()>,
13605    progress_tx: mpsc::Sender<()>,
13606    #[allow(dead_code)]
13607    task: Task<()>,
13608}
13609
13610pub enum LanguageServerState {
13611    Starting {
13612        startup: Task<Option<Arc<LanguageServer>>>,
13613        /// List of language servers that will be added to the workspace once it's initialization completes.
13614        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13615    },
13616
13617    Running {
13618        adapter: Arc<CachedLspAdapter>,
13619        server: Arc<LanguageServer>,
13620        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13621        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13622    },
13623}
13624
13625impl LanguageServerState {
13626    fn add_workspace_folder(&self, uri: Uri) {
13627        match self {
13628            LanguageServerState::Starting {
13629                pending_workspace_folders,
13630                ..
13631            } => {
13632                pending_workspace_folders.lock().insert(uri);
13633            }
13634            LanguageServerState::Running { server, .. } => {
13635                server.add_workspace_folder(uri);
13636            }
13637        }
13638    }
13639    fn _remove_workspace_folder(&self, uri: Uri) {
13640        match self {
13641            LanguageServerState::Starting {
13642                pending_workspace_folders,
13643                ..
13644            } => {
13645                pending_workspace_folders.lock().remove(&uri);
13646            }
13647            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13648        }
13649    }
13650}
13651
13652impl std::fmt::Debug for LanguageServerState {
13653    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13654        match self {
13655            LanguageServerState::Starting { .. } => {
13656                f.debug_struct("LanguageServerState::Starting").finish()
13657            }
13658            LanguageServerState::Running { .. } => {
13659                f.debug_struct("LanguageServerState::Running").finish()
13660            }
13661        }
13662    }
13663}
13664
13665#[derive(Clone, Debug, Serialize)]
13666pub struct LanguageServerProgress {
13667    pub is_disk_based_diagnostics_progress: bool,
13668    pub is_cancellable: bool,
13669    pub title: Option<String>,
13670    pub message: Option<String>,
13671    pub percentage: Option<usize>,
13672    #[serde(skip_serializing)]
13673    pub last_update_at: Instant,
13674}
13675
13676#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13677pub struct DiagnosticSummary {
13678    pub error_count: usize,
13679    pub warning_count: usize,
13680}
13681
13682impl DiagnosticSummary {
13683    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13684        let mut this = Self {
13685            error_count: 0,
13686            warning_count: 0,
13687        };
13688
13689        for entry in diagnostics {
13690            if entry.diagnostic.is_primary {
13691                match entry.diagnostic.severity {
13692                    DiagnosticSeverity::ERROR => this.error_count += 1,
13693                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13694                    _ => {}
13695                }
13696            }
13697        }
13698
13699        this
13700    }
13701
13702    pub fn is_empty(&self) -> bool {
13703        self.error_count == 0 && self.warning_count == 0
13704    }
13705
13706    pub fn to_proto(
13707        self,
13708        language_server_id: LanguageServerId,
13709        path: &RelPath,
13710    ) -> proto::DiagnosticSummary {
13711        proto::DiagnosticSummary {
13712            path: path.to_proto(),
13713            language_server_id: language_server_id.0 as u64,
13714            error_count: self.error_count as u32,
13715            warning_count: self.warning_count as u32,
13716        }
13717    }
13718}
13719
13720#[derive(Clone, Debug)]
13721pub enum CompletionDocumentation {
13722    /// There is no documentation for this completion.
13723    Undocumented,
13724    /// A single line of documentation.
13725    SingleLine(SharedString),
13726    /// Multiple lines of plain text documentation.
13727    MultiLinePlainText(SharedString),
13728    /// Markdown documentation.
13729    MultiLineMarkdown(SharedString),
13730    /// Both single line and multiple lines of plain text documentation.
13731    SingleLineAndMultiLinePlainText {
13732        single_line: SharedString,
13733        plain_text: Option<SharedString>,
13734    },
13735}
13736
13737impl CompletionDocumentation {
13738    #[cfg(any(test, feature = "test-support"))]
13739    pub fn text(&self) -> SharedString {
13740        match self {
13741            CompletionDocumentation::Undocumented => "".into(),
13742            CompletionDocumentation::SingleLine(s) => s.clone(),
13743            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13744            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13745            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13746                single_line.clone()
13747            }
13748        }
13749    }
13750}
13751
13752impl From<lsp::Documentation> for CompletionDocumentation {
13753    fn from(docs: lsp::Documentation) -> Self {
13754        match docs {
13755            lsp::Documentation::String(text) => {
13756                if text.lines().count() <= 1 {
13757                    CompletionDocumentation::SingleLine(text.into())
13758                } else {
13759                    CompletionDocumentation::MultiLinePlainText(text.into())
13760                }
13761            }
13762
13763            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13764                lsp::MarkupKind::PlainText => {
13765                    if value.lines().count() <= 1 {
13766                        CompletionDocumentation::SingleLine(value.into())
13767                    } else {
13768                        CompletionDocumentation::MultiLinePlainText(value.into())
13769                    }
13770                }
13771
13772                lsp::MarkupKind::Markdown => {
13773                    CompletionDocumentation::MultiLineMarkdown(value.into())
13774                }
13775            },
13776        }
13777    }
13778}
13779
13780pub enum ResolvedHint {
13781    Resolved(InlayHint),
13782    Resolving(Shared<Task<()>>),
13783}
13784
13785fn glob_literal_prefix(glob: &Path) -> PathBuf {
13786    glob.components()
13787        .take_while(|component| match component {
13788            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13789            _ => true,
13790        })
13791        .collect()
13792}
13793
13794pub struct SshLspAdapter {
13795    name: LanguageServerName,
13796    binary: LanguageServerBinary,
13797    initialization_options: Option<String>,
13798    code_action_kinds: Option<Vec<CodeActionKind>>,
13799}
13800
13801impl SshLspAdapter {
13802    pub fn new(
13803        name: LanguageServerName,
13804        binary: LanguageServerBinary,
13805        initialization_options: Option<String>,
13806        code_action_kinds: Option<String>,
13807    ) -> Self {
13808        Self {
13809            name,
13810            binary,
13811            initialization_options,
13812            code_action_kinds: code_action_kinds
13813                .as_ref()
13814                .and_then(|c| serde_json::from_str(c).ok()),
13815        }
13816    }
13817}
13818
13819impl LspInstaller for SshLspAdapter {
13820    type BinaryVersion = ();
13821    async fn check_if_user_installed(
13822        &self,
13823        _: &dyn LspAdapterDelegate,
13824        _: Option<Toolchain>,
13825        _: &AsyncApp,
13826    ) -> Option<LanguageServerBinary> {
13827        Some(self.binary.clone())
13828    }
13829
13830    async fn cached_server_binary(
13831        &self,
13832        _: PathBuf,
13833        _: &dyn LspAdapterDelegate,
13834    ) -> Option<LanguageServerBinary> {
13835        None
13836    }
13837
13838    async fn fetch_latest_server_version(
13839        &self,
13840        _: &dyn LspAdapterDelegate,
13841        _: bool,
13842        _: &mut AsyncApp,
13843    ) -> Result<()> {
13844        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13845    }
13846
13847    async fn fetch_server_binary(
13848        &self,
13849        _: (),
13850        _: PathBuf,
13851        _: &dyn LspAdapterDelegate,
13852    ) -> Result<LanguageServerBinary> {
13853        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13854    }
13855}
13856
13857#[async_trait(?Send)]
13858impl LspAdapter for SshLspAdapter {
13859    fn name(&self) -> LanguageServerName {
13860        self.name.clone()
13861    }
13862
13863    async fn initialization_options(
13864        self: Arc<Self>,
13865        _: &Arc<dyn LspAdapterDelegate>,
13866    ) -> Result<Option<serde_json::Value>> {
13867        let Some(options) = &self.initialization_options else {
13868            return Ok(None);
13869        };
13870        let result = serde_json::from_str(options)?;
13871        Ok(result)
13872    }
13873
13874    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13875        self.code_action_kinds.clone()
13876    }
13877}
13878
13879pub fn language_server_settings<'a>(
13880    delegate: &'a dyn LspAdapterDelegate,
13881    language: &LanguageServerName,
13882    cx: &'a App,
13883) -> Option<&'a LspSettings> {
13884    language_server_settings_for(
13885        SettingsLocation {
13886            worktree_id: delegate.worktree_id(),
13887            path: RelPath::empty(),
13888        },
13889        language,
13890        cx,
13891    )
13892}
13893
13894pub fn language_server_settings_for<'a>(
13895    location: SettingsLocation<'a>,
13896    language: &LanguageServerName,
13897    cx: &'a App,
13898) -> Option<&'a LspSettings> {
13899    ProjectSettings::get(Some(location), cx).lsp.get(language)
13900}
13901
13902pub struct LocalLspAdapterDelegate {
13903    lsp_store: WeakEntity<LspStore>,
13904    worktree: worktree::Snapshot,
13905    fs: Arc<dyn Fs>,
13906    http_client: Arc<dyn HttpClient>,
13907    language_registry: Arc<LanguageRegistry>,
13908    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13909}
13910
13911impl LocalLspAdapterDelegate {
13912    pub fn new(
13913        language_registry: Arc<LanguageRegistry>,
13914        environment: &Entity<ProjectEnvironment>,
13915        lsp_store: WeakEntity<LspStore>,
13916        worktree: &Entity<Worktree>,
13917        http_client: Arc<dyn HttpClient>,
13918        fs: Arc<dyn Fs>,
13919        cx: &mut App,
13920    ) -> Arc<Self> {
13921        let load_shell_env_task =
13922            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
13923
13924        Arc::new(Self {
13925            lsp_store,
13926            worktree: worktree.read(cx).snapshot(),
13927            fs,
13928            http_client,
13929            language_registry,
13930            load_shell_env_task,
13931        })
13932    }
13933
13934    fn from_local_lsp(
13935        local: &LocalLspStore,
13936        worktree: &Entity<Worktree>,
13937        cx: &mut App,
13938    ) -> Arc<Self> {
13939        Self::new(
13940            local.languages.clone(),
13941            &local.environment,
13942            local.weak.clone(),
13943            worktree,
13944            local.http_client.clone(),
13945            local.fs.clone(),
13946            cx,
13947        )
13948    }
13949}
13950
13951#[async_trait]
13952impl LspAdapterDelegate for LocalLspAdapterDelegate {
13953    fn show_notification(&self, message: &str, cx: &mut App) {
13954        self.lsp_store
13955            .update(cx, |_, cx| {
13956                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13957            })
13958            .ok();
13959    }
13960
13961    fn http_client(&self) -> Arc<dyn HttpClient> {
13962        self.http_client.clone()
13963    }
13964
13965    fn worktree_id(&self) -> WorktreeId {
13966        self.worktree.id()
13967    }
13968
13969    fn worktree_root_path(&self) -> &Path {
13970        self.worktree.abs_path().as_ref()
13971    }
13972
13973    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
13974        self.worktree.resolve_executable_path(path)
13975    }
13976
13977    async fn shell_env(&self) -> HashMap<String, String> {
13978        let task = self.load_shell_env_task.clone();
13979        task.await.unwrap_or_default()
13980    }
13981
13982    async fn npm_package_installed_version(
13983        &self,
13984        package_name: &str,
13985    ) -> Result<Option<(PathBuf, Version)>> {
13986        let local_package_directory = self.worktree_root_path();
13987        let node_modules_directory = local_package_directory.join("node_modules");
13988
13989        if let Some(version) =
13990            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13991        {
13992            return Ok(Some((node_modules_directory, version)));
13993        }
13994        let Some(npm) = self.which("npm".as_ref()).await else {
13995            log::warn!(
13996                "Failed to find npm executable for {:?}",
13997                local_package_directory
13998            );
13999            return Ok(None);
14000        };
14001
14002        let env = self.shell_env().await;
14003        let output = util::command::new_smol_command(&npm)
14004            .args(["root", "-g"])
14005            .envs(env)
14006            .current_dir(local_package_directory)
14007            .output()
14008            .await?;
14009        let global_node_modules =
14010            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14011
14012        if let Some(version) =
14013            read_package_installed_version(global_node_modules.clone(), package_name).await?
14014        {
14015            return Ok(Some((global_node_modules, version)));
14016        }
14017        return Ok(None);
14018    }
14019
14020    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14021        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14022        if self.fs.is_file(&worktree_abs_path).await {
14023            worktree_abs_path.pop();
14024        }
14025
14026        let env = self.shell_env().await;
14027
14028        let shell_path = env.get("PATH").cloned();
14029
14030        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14031    }
14032
14033    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14034        let mut working_dir = self.worktree_root_path().to_path_buf();
14035        if self.fs.is_file(&working_dir).await {
14036            working_dir.pop();
14037        }
14038        let output = util::command::new_smol_command(&command.path)
14039            .args(command.arguments)
14040            .envs(command.env.clone().unwrap_or_default())
14041            .current_dir(working_dir)
14042            .output()
14043            .await?;
14044
14045        anyhow::ensure!(
14046            output.status.success(),
14047            "{}, stdout: {:?}, stderr: {:?}",
14048            output.status,
14049            String::from_utf8_lossy(&output.stdout),
14050            String::from_utf8_lossy(&output.stderr)
14051        );
14052        Ok(())
14053    }
14054
14055    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14056        self.language_registry
14057            .update_lsp_binary_status(server_name, status);
14058    }
14059
14060    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14061        self.language_registry
14062            .all_lsp_adapters()
14063            .into_iter()
14064            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14065            .collect()
14066    }
14067
14068    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14069        let dir = self.language_registry.language_server_download_dir(name)?;
14070
14071        if !dir.exists() {
14072            smol::fs::create_dir_all(&dir)
14073                .await
14074                .context("failed to create container directory")
14075                .log_err()?;
14076        }
14077
14078        Some(dir)
14079    }
14080
14081    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14082        let entry = self
14083            .worktree
14084            .entry_for_path(path)
14085            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14086        let abs_path = self.worktree.absolutize(&entry.path);
14087        self.fs.load(&abs_path).await
14088    }
14089}
14090
14091async fn populate_labels_for_symbols(
14092    symbols: Vec<CoreSymbol>,
14093    language_registry: &Arc<LanguageRegistry>,
14094    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14095    output: &mut Vec<Symbol>,
14096) {
14097    #[allow(clippy::mutable_key_type)]
14098    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14099
14100    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14101    for symbol in symbols {
14102        let Some(file_name) = symbol.path.file_name() else {
14103            continue;
14104        };
14105        let language = language_registry
14106            .load_language_for_file_path(Path::new(file_name))
14107            .await
14108            .ok()
14109            .or_else(|| {
14110                unknown_paths.insert(file_name.into());
14111                None
14112            });
14113        symbols_by_language
14114            .entry(language)
14115            .or_default()
14116            .push(symbol);
14117    }
14118
14119    for unknown_path in unknown_paths {
14120        log::info!("no language found for symbol in file {unknown_path:?}");
14121    }
14122
14123    let mut label_params = Vec::new();
14124    for (language, mut symbols) in symbols_by_language {
14125        label_params.clear();
14126        label_params.extend(
14127            symbols
14128                .iter_mut()
14129                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14130        );
14131
14132        let mut labels = Vec::new();
14133        if let Some(language) = language {
14134            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14135                language_registry
14136                    .lsp_adapters(&language.name())
14137                    .first()
14138                    .cloned()
14139            });
14140            if let Some(lsp_adapter) = lsp_adapter {
14141                labels = lsp_adapter
14142                    .labels_for_symbols(&label_params, &language)
14143                    .await
14144                    .log_err()
14145                    .unwrap_or_default();
14146            }
14147        }
14148
14149        for ((symbol, (name, _)), label) in symbols
14150            .into_iter()
14151            .zip(label_params.drain(..))
14152            .zip(labels.into_iter().chain(iter::repeat(None)))
14153        {
14154            output.push(Symbol {
14155                language_server_name: symbol.language_server_name,
14156                source_worktree_id: symbol.source_worktree_id,
14157                source_language_server_id: symbol.source_language_server_id,
14158                path: symbol.path,
14159                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14160                name,
14161                kind: symbol.kind,
14162                range: symbol.range,
14163            });
14164        }
14165    }
14166}
14167
14168fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14169    match server.capabilities().text_document_sync.as_ref()? {
14170        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14171            // Server wants didSave but didn't specify includeText.
14172            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14173            // Server doesn't want didSave at all.
14174            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14175            // Server provided SaveOptions.
14176            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14177                Some(save_options.include_text.unwrap_or(false))
14178            }
14179        },
14180        // We do not have any save info. Kind affects didChange only.
14181        lsp::TextDocumentSyncCapability::Kind(_) => None,
14182    }
14183}
14184
14185/// Completion items are displayed in a `UniformList`.
14186/// Usually, those items are single-line strings, but in LSP responses,
14187/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14188/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14189/// 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,
14190/// breaking the completions menu presentation.
14191///
14192/// 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.
14193fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14194    let mut new_text = String::with_capacity(label.text.len());
14195    let mut offset_map = vec![0; label.text.len() + 1];
14196    let mut last_char_was_space = false;
14197    let mut new_idx = 0;
14198    let chars = label.text.char_indices().fuse();
14199    let mut newlines_removed = false;
14200
14201    for (idx, c) in chars {
14202        offset_map[idx] = new_idx;
14203
14204        match c {
14205            '\n' if last_char_was_space => {
14206                newlines_removed = true;
14207            }
14208            '\t' | ' ' if last_char_was_space => {}
14209            '\n' if !last_char_was_space => {
14210                new_text.push(' ');
14211                new_idx += 1;
14212                last_char_was_space = true;
14213                newlines_removed = true;
14214            }
14215            ' ' | '\t' => {
14216                new_text.push(' ');
14217                new_idx += 1;
14218                last_char_was_space = true;
14219            }
14220            _ => {
14221                new_text.push(c);
14222                new_idx += c.len_utf8();
14223                last_char_was_space = false;
14224            }
14225        }
14226    }
14227    offset_map[label.text.len()] = new_idx;
14228
14229    // Only modify the label if newlines were removed.
14230    if !newlines_removed {
14231        return;
14232    }
14233
14234    let last_index = new_idx;
14235    let mut run_ranges_errors = Vec::new();
14236    label.runs.retain_mut(|(range, _)| {
14237        match offset_map.get(range.start) {
14238            Some(&start) => range.start = start,
14239            None => {
14240                run_ranges_errors.push(range.clone());
14241                return false;
14242            }
14243        }
14244
14245        match offset_map.get(range.end) {
14246            Some(&end) => range.end = end,
14247            None => {
14248                run_ranges_errors.push(range.clone());
14249                range.end = last_index;
14250            }
14251        }
14252        true
14253    });
14254    if !run_ranges_errors.is_empty() {
14255        log::error!(
14256            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14257            label.text
14258        );
14259    }
14260
14261    let mut wrong_filter_range = None;
14262    if label.filter_range == (0..label.text.len()) {
14263        label.filter_range = 0..new_text.len();
14264    } else {
14265        let mut original_filter_range = Some(label.filter_range.clone());
14266        match offset_map.get(label.filter_range.start) {
14267            Some(&start) => label.filter_range.start = start,
14268            None => {
14269                wrong_filter_range = original_filter_range.take();
14270                label.filter_range.start = last_index;
14271            }
14272        }
14273
14274        match offset_map.get(label.filter_range.end) {
14275            Some(&end) => label.filter_range.end = end,
14276            None => {
14277                wrong_filter_range = original_filter_range.take();
14278                label.filter_range.end = last_index;
14279            }
14280        }
14281    }
14282    if let Some(wrong_filter_range) = wrong_filter_range {
14283        log::error!(
14284            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14285            label.text
14286        );
14287    }
14288
14289    label.text = new_text;
14290}
14291
14292#[cfg(test)]
14293mod tests {
14294    use language::HighlightId;
14295
14296    use super::*;
14297
14298    #[test]
14299    fn test_glob_literal_prefix() {
14300        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14301        assert_eq!(
14302            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14303            Path::new("node_modules")
14304        );
14305        assert_eq!(
14306            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14307            Path::new("foo")
14308        );
14309        assert_eq!(
14310            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14311            Path::new("foo/bar/baz.js")
14312        );
14313
14314        #[cfg(target_os = "windows")]
14315        {
14316            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14317            assert_eq!(
14318                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14319                Path::new("node_modules")
14320            );
14321            assert_eq!(
14322                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14323                Path::new("foo")
14324            );
14325            assert_eq!(
14326                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14327                Path::new("foo/bar/baz.js")
14328            );
14329        }
14330    }
14331
14332    #[test]
14333    fn test_multi_len_chars_normalization() {
14334        let mut label = CodeLabel::new(
14335            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14336            0..6,
14337            vec![(0..6, HighlightId(1))],
14338        );
14339        ensure_uniform_list_compatible_label(&mut label);
14340        assert_eq!(
14341            label,
14342            CodeLabel::new(
14343                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14344                0..6,
14345                vec![(0..6, HighlightId(1))],
14346            )
14347        );
14348    }
14349}