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    redact::redact_command,
  132    rel_path::RelPath,
  133};
  134
  135pub use fs::*;
  136pub use language::Location;
  137pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  138#[cfg(any(test, feature = "test-support"))]
  139pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  140pub use worktree::{
  141    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  142    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  143};
  144
  145const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  146pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  147const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  148const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  149
  150#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  151pub enum ProgressToken {
  152    Number(i32),
  153    String(SharedString),
  154}
  155
  156impl std::fmt::Display for ProgressToken {
  157    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  158        match self {
  159            Self::Number(number) => write!(f, "{number}"),
  160            Self::String(string) => write!(f, "{string}"),
  161        }
  162    }
  163}
  164
  165impl ProgressToken {
  166    fn from_lsp(value: lsp::NumberOrString) -> Self {
  167        match value {
  168            lsp::NumberOrString::Number(number) => Self::Number(number),
  169            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  170        }
  171    }
  172
  173    fn to_lsp(&self) -> lsp::NumberOrString {
  174        match self {
  175            Self::Number(number) => lsp::NumberOrString::Number(*number),
  176            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  177        }
  178    }
  179
  180    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  181        Some(match value.value? {
  182            proto::progress_token::Value::Number(number) => Self::Number(number),
  183            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  184        })
  185    }
  186
  187    fn to_proto(&self) -> proto::ProgressToken {
  188        proto::ProgressToken {
  189            value: Some(match self {
  190                Self::Number(number) => proto::progress_token::Value::Number(*number),
  191                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  192            }),
  193        }
  194    }
  195}
  196
  197#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  198pub enum FormatTrigger {
  199    Save,
  200    Manual,
  201}
  202
  203pub enum LspFormatTarget {
  204    Buffers,
  205    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  206}
  207
  208#[derive(Clone, PartialEq, Eq, Hash)]
  209pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  210
  211struct OpenLspBuffer(Entity<Buffer>);
  212
  213impl FormatTrigger {
  214    fn from_proto(value: i32) -> FormatTrigger {
  215        match value {
  216            0 => FormatTrigger::Save,
  217            1 => FormatTrigger::Manual,
  218            _ => FormatTrigger::Save,
  219        }
  220    }
  221}
  222
  223#[derive(Clone)]
  224struct UnifiedLanguageServer {
  225    id: LanguageServerId,
  226    project_roots: HashSet<Arc<RelPath>>,
  227}
  228
  229#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  230struct LanguageServerSeed {
  231    worktree_id: WorktreeId,
  232    name: LanguageServerName,
  233    toolchain: Option<Toolchain>,
  234    settings: Arc<LspSettings>,
  235}
  236
  237#[derive(Debug)]
  238pub struct DocumentDiagnosticsUpdate<'a, D> {
  239    pub diagnostics: D,
  240    pub result_id: Option<SharedString>,
  241    pub registration_id: Option<SharedString>,
  242    pub server_id: LanguageServerId,
  243    pub disk_based_sources: Cow<'a, [String]>,
  244}
  245
  246pub struct DocumentDiagnostics {
  247    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  248    document_abs_path: PathBuf,
  249    version: Option<i32>,
  250}
  251
  252#[derive(Default, Debug)]
  253struct DynamicRegistrations {
  254    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  255    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  256}
  257
  258pub struct LocalLspStore {
  259    weak: WeakEntity<LspStore>,
  260    worktree_store: Entity<WorktreeStore>,
  261    toolchain_store: Entity<LocalToolchainStore>,
  262    http_client: Arc<dyn HttpClient>,
  263    environment: Entity<ProjectEnvironment>,
  264    fs: Arc<dyn Fs>,
  265    languages: Arc<LanguageRegistry>,
  266    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  267    yarn: Entity<YarnPathStore>,
  268    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  269    buffers_being_formatted: HashSet<BufferId>,
  270    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  271    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  272    watched_manifest_filenames: HashSet<ManifestName>,
  273    language_server_paths_watched_for_rename:
  274        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  275    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  276    supplementary_language_servers:
  277        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  278    prettier_store: Entity<PrettierStore>,
  279    next_diagnostic_group_id: usize,
  280    diagnostics: HashMap<
  281        WorktreeId,
  282        HashMap<
  283            Arc<RelPath>,
  284            Vec<(
  285                LanguageServerId,
  286                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  287            )>,
  288        >,
  289    >,
  290    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  291    _subscription: gpui::Subscription,
  292    lsp_tree: LanguageServerTree,
  293    registered_buffers: HashMap<BufferId, usize>,
  294    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  295    buffer_pull_diagnostics_result_ids: HashMap<
  296        LanguageServerId,
  297        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  298    >,
  299    workspace_pull_diagnostics_result_ids: HashMap<
  300        LanguageServerId,
  301        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  302    >,
  303    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, Receiver<()>)>,
  304}
  305
  306impl LocalLspStore {
  307    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  308    pub fn running_language_server_for_id(
  309        &self,
  310        id: LanguageServerId,
  311    ) -> Option<&Arc<LanguageServer>> {
  312        let language_server_state = self.language_servers.get(&id)?;
  313
  314        match language_server_state {
  315            LanguageServerState::Running { server, .. } => Some(server),
  316            LanguageServerState::Starting { .. } => None,
  317        }
  318    }
  319
  320    fn get_or_insert_language_server(
  321        &mut self,
  322        worktree_handle: &Entity<Worktree>,
  323        delegate: Arc<LocalLspAdapterDelegate>,
  324        disposition: &Arc<LaunchDisposition>,
  325        language_name: &LanguageName,
  326        cx: &mut App,
  327    ) -> LanguageServerId {
  328        let key = LanguageServerSeed {
  329            worktree_id: worktree_handle.read(cx).id(),
  330            name: disposition.server_name.clone(),
  331            settings: disposition.settings.clone(),
  332            toolchain: disposition.toolchain.clone(),
  333        };
  334        if let Some(state) = self.language_server_ids.get_mut(&key) {
  335            state.project_roots.insert(disposition.path.path.clone());
  336            state.id
  337        } else {
  338            let adapter = self
  339                .languages
  340                .lsp_adapters(language_name)
  341                .into_iter()
  342                .find(|adapter| adapter.name() == disposition.server_name)
  343                .expect("To find LSP adapter");
  344            let new_language_server_id = self.start_language_server(
  345                worktree_handle,
  346                delegate,
  347                adapter,
  348                disposition.settings.clone(),
  349                key.clone(),
  350                cx,
  351            );
  352            if let Some(state) = self.language_server_ids.get_mut(&key) {
  353                state.project_roots.insert(disposition.path.path.clone());
  354            } else {
  355                debug_assert!(
  356                    false,
  357                    "Expected `start_language_server` to ensure that `key` exists in a map"
  358                );
  359            }
  360            new_language_server_id
  361        }
  362    }
  363
  364    fn start_language_server(
  365        &mut self,
  366        worktree_handle: &Entity<Worktree>,
  367        delegate: Arc<LocalLspAdapterDelegate>,
  368        adapter: Arc<CachedLspAdapter>,
  369        settings: Arc<LspSettings>,
  370        key: LanguageServerSeed,
  371        cx: &mut App,
  372    ) -> LanguageServerId {
  373        let worktree = worktree_handle.read(cx);
  374
  375        let worktree_id = worktree.id();
  376        let worktree_abs_path = worktree.abs_path();
  377        let toolchain = key.toolchain.clone();
  378        let override_options = settings.initialization_options.clone();
  379
  380        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  381
  382        let server_id = self.languages.next_language_server_id();
  383        log::trace!(
  384            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  385            adapter.name.0
  386        );
  387
  388        let untrusted_worktree_task =
  389            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  390                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  391                    trusted_worktrees.can_trust(worktree_id, cx)
  392                });
  393                if can_trust {
  394                    self.restricted_worktrees_tasks.remove(&worktree_id);
  395                    None
  396                } else {
  397                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  398                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  399                        hash_map::Entry::Vacant(v) => {
  400                            let (tx, rx) = smol::channel::bounded::<()>(1);
  401                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, _| {
  402                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  403                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  404                                        tx.send_blocking(()).ok();
  405                                    }
  406                                }
  407                            });
  408                            v.insert((subscription, rx.clone()));
  409                            Some(rx)
  410                        }
  411                    }
  412                }
  413            });
  414        let update_binary_status = untrusted_worktree_task.is_none();
  415
  416        let binary = self.get_language_server_binary(
  417            worktree_abs_path.clone(),
  418            adapter.clone(),
  419            settings,
  420            toolchain.clone(),
  421            delegate.clone(),
  422            true,
  423            untrusted_worktree_task,
  424            cx,
  425        );
  426        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  427
  428        let pending_server = cx.spawn({
  429            let adapter = adapter.clone();
  430            let server_name = adapter.name.clone();
  431            let stderr_capture = stderr_capture.clone();
  432            #[cfg(any(test, feature = "test-support"))]
  433            let lsp_store = self.weak.clone();
  434            let pending_workspace_folders = pending_workspace_folders.clone();
  435            async move |cx| {
  436                let binary = binary.await?;
  437                #[cfg(any(test, feature = "test-support"))]
  438                if let Some(server) = lsp_store
  439                    .update(&mut cx.clone(), |this, cx| {
  440                        this.languages.create_fake_language_server(
  441                            server_id,
  442                            &server_name,
  443                            binary.clone(),
  444                            &mut cx.to_async(),
  445                        )
  446                    })
  447                    .ok()
  448                    .flatten()
  449                {
  450                    return Ok(server);
  451                }
  452
  453                let code_action_kinds = adapter.code_action_kinds();
  454                lsp::LanguageServer::new(
  455                    stderr_capture,
  456                    server_id,
  457                    server_name,
  458                    binary,
  459                    &worktree_abs_path,
  460                    code_action_kinds,
  461                    Some(pending_workspace_folders),
  462                    cx,
  463                )
  464            }
  465        });
  466
  467        let startup = {
  468            let server_name = adapter.name.0.clone();
  469            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  470            let key = key.clone();
  471            let adapter = adapter.clone();
  472            let lsp_store = self.weak.clone();
  473            let pending_workspace_folders = pending_workspace_folders.clone();
  474
  475            let pull_diagnostics = ProjectSettings::get_global(cx)
  476                .diagnostics
  477                .lsp_pull_diagnostics
  478                .enabled;
  479            cx.spawn(async move |cx| {
  480                let result = async {
  481                    let language_server = pending_server.await?;
  482
  483                    let workspace_config = Self::workspace_configuration_for_adapter(
  484                        adapter.adapter.clone(),
  485                        &delegate,
  486                        toolchain,
  487                        None,
  488                        cx,
  489                    )
  490                    .await?;
  491
  492                    let mut initialization_options = Self::initialization_options_for_adapter(
  493                        adapter.adapter.clone(),
  494                        &delegate,
  495                    )
  496                    .await?;
  497
  498                    match (&mut initialization_options, override_options) {
  499                        (Some(initialization_options), Some(override_options)) => {
  500                            merge_json_value_into(override_options, initialization_options);
  501                        }
  502                        (None, override_options) => initialization_options = override_options,
  503                        _ => {}
  504                    }
  505
  506                    let initialization_params = cx.update(|cx| {
  507                        let mut params =
  508                            language_server.default_initialize_params(pull_diagnostics, cx);
  509                        params.initialization_options = initialization_options;
  510                        adapter.adapter.prepare_initialize_params(params, cx)
  511                    })??;
  512
  513                    Self::setup_lsp_messages(
  514                        lsp_store.clone(),
  515                        &language_server,
  516                        delegate.clone(),
  517                        adapter.clone(),
  518                    );
  519
  520                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  521                        settings: workspace_config,
  522                    };
  523                    let language_server = cx
  524                        .update(|cx| {
  525                            language_server.initialize(
  526                                initialization_params,
  527                                Arc::new(did_change_configuration_params.clone()),
  528                                cx,
  529                            )
  530                        })?
  531                        .await
  532                        .inspect_err(|_| {
  533                            if let Some(lsp_store) = lsp_store.upgrade() {
  534                                lsp_store
  535                                    .update(cx, |lsp_store, cx| {
  536                                        lsp_store.cleanup_lsp_data(server_id);
  537                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  538                                    })
  539                                    .ok();
  540                            }
  541                        })?;
  542
  543                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  544                        did_change_configuration_params,
  545                    )?;
  546
  547                    anyhow::Ok(language_server)
  548                }
  549                .await;
  550
  551                match result {
  552                    Ok(server) => {
  553                        lsp_store
  554                            .update(cx, |lsp_store, cx| {
  555                                lsp_store.insert_newly_running_language_server(
  556                                    adapter,
  557                                    server.clone(),
  558                                    server_id,
  559                                    key,
  560                                    pending_workspace_folders,
  561                                    cx,
  562                                );
  563                            })
  564                            .ok();
  565                        stderr_capture.lock().take();
  566                        Some(server)
  567                    }
  568
  569                    Err(err) => {
  570                        let log = stderr_capture.lock().take().unwrap_or_default();
  571                        delegate.update_status(
  572                            adapter.name(),
  573                            BinaryStatus::Failed {
  574                                error: if log.is_empty() {
  575                                    format!("{err:#}")
  576                                } else {
  577                                    format!("{err:#}\n-- stderr --\n{log}")
  578                                },
  579                            },
  580                        );
  581                        log::error!(
  582                            "Failed to start language server {server_name:?}: {}",
  583                            redact_command(&format!("{err:?}"))
  584                        );
  585                        if !log.is_empty() {
  586                            log::error!("server stderr: {}", redact_command(&log));
  587                        }
  588                        None
  589                    }
  590                }
  591            })
  592        };
  593        let state = LanguageServerState::Starting {
  594            startup,
  595            pending_workspace_folders,
  596        };
  597
  598        if update_binary_status {
  599            self.languages
  600                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  601        }
  602
  603        self.language_servers.insert(server_id, state);
  604        self.language_server_ids
  605            .entry(key)
  606            .or_insert(UnifiedLanguageServer {
  607                id: server_id,
  608                project_roots: Default::default(),
  609            });
  610        server_id
  611    }
  612
  613    fn get_language_server_binary(
  614        &self,
  615        worktree_abs_path: Arc<Path>,
  616        adapter: Arc<CachedLspAdapter>,
  617        settings: Arc<LspSettings>,
  618        toolchain: Option<Toolchain>,
  619        delegate: Arc<dyn LspAdapterDelegate>,
  620        allow_binary_download: bool,
  621        untrusted_worktree_task: Option<Receiver<()>>,
  622        cx: &mut App,
  623    ) -> Task<Result<LanguageServerBinary>> {
  624        if let Some(settings) = &settings.binary
  625            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  626        {
  627            let settings = settings.clone();
  628            let languages = self.languages.clone();
  629            return cx.background_spawn(async move {
  630                if let Some(untrusted_worktree_task) = untrusted_worktree_task {
  631                    log::info!(
  632                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  633                        adapter.name(),
  634                    );
  635                    untrusted_worktree_task.recv().await.ok();
  636                    log::info!(
  637                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  638                        adapter.name(),
  639                    );
  640                    languages
  641                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  642                }
  643                let mut env = delegate.shell_env().await;
  644                env.extend(settings.env.unwrap_or_default());
  645
  646                Ok(LanguageServerBinary {
  647                    path: delegate.resolve_executable_path(path),
  648                    env: Some(env),
  649                    arguments: settings
  650                        .arguments
  651                        .unwrap_or_default()
  652                        .iter()
  653                        .map(Into::into)
  654                        .collect(),
  655                })
  656            });
  657        }
  658        let lsp_binary_options = LanguageServerBinaryOptions {
  659            allow_path_lookup: !settings
  660                .binary
  661                .as_ref()
  662                .and_then(|b| b.ignore_system_version)
  663                .unwrap_or_default(),
  664            allow_binary_download,
  665            pre_release: settings
  666                .fetch
  667                .as_ref()
  668                .and_then(|f| f.pre_release)
  669                .unwrap_or(false),
  670        };
  671
  672        cx.spawn(async move |cx| {
  673            if let Some(untrusted_worktree_task) = untrusted_worktree_task {
  674                log::info!(
  675                    "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  676                    adapter.name(),
  677                );
  678                untrusted_worktree_task.recv().await.ok();
  679                log::info!(
  680                    "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  681                    adapter.name(),
  682                );
  683            }
  684
  685            let (existing_binary, maybe_download_binary) = adapter
  686                .clone()
  687                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  688                .await
  689                .await;
  690
  691            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  692
  693            let mut binary = match (existing_binary, maybe_download_binary) {
  694                (binary, None) => binary?,
  695                (Err(_), Some(downloader)) => downloader.await?,
  696                (Ok(existing_binary), Some(downloader)) => {
  697                    let mut download_timeout = cx
  698                        .background_executor()
  699                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  700                        .fuse();
  701                    let mut downloader = downloader.fuse();
  702                    futures::select! {
  703                        _ = download_timeout => {
  704                            // Return existing binary and kick the existing work to the background.
  705                            cx.spawn(async move |_| downloader.await).detach();
  706                            Ok(existing_binary)
  707                        },
  708                        downloaded_or_existing_binary = downloader => {
  709                            // If download fails, this results in the existing binary.
  710                            downloaded_or_existing_binary
  711                        }
  712                    }?
  713                }
  714            };
  715            let mut shell_env = delegate.shell_env().await;
  716
  717            shell_env.extend(binary.env.unwrap_or_default());
  718
  719            if let Some(settings) = settings.binary.as_ref() {
  720                if let Some(arguments) = &settings.arguments {
  721                    binary.arguments = arguments.iter().map(Into::into).collect();
  722                }
  723                if let Some(env) = &settings.env {
  724                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  725                }
  726            }
  727
  728            binary.env = Some(shell_env);
  729            Ok(binary)
  730        })
  731    }
  732
  733    fn setup_lsp_messages(
  734        lsp_store: WeakEntity<LspStore>,
  735        language_server: &LanguageServer,
  736        delegate: Arc<dyn LspAdapterDelegate>,
  737        adapter: Arc<CachedLspAdapter>,
  738    ) {
  739        let name = language_server.name();
  740        let server_id = language_server.server_id();
  741        language_server
  742            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  743                let adapter = adapter.clone();
  744                let this = lsp_store.clone();
  745                move |mut params, cx| {
  746                    let adapter = adapter.clone();
  747                    if let Some(this) = this.upgrade() {
  748                        this.update(cx, |this, cx| {
  749                            {
  750                                let buffer = params
  751                                    .uri
  752                                    .to_file_path()
  753                                    .map(|file_path| this.get_buffer(&file_path, cx))
  754                                    .ok()
  755                                    .flatten();
  756                                adapter.process_diagnostics(&mut params, server_id, buffer);
  757                            }
  758
  759                            this.merge_lsp_diagnostics(
  760                                DiagnosticSourceKind::Pushed,
  761                                vec![DocumentDiagnosticsUpdate {
  762                                    server_id,
  763                                    diagnostics: params,
  764                                    result_id: None,
  765                                    disk_based_sources: Cow::Borrowed(
  766                                        &adapter.disk_based_diagnostic_sources,
  767                                    ),
  768                                    registration_id: None,
  769                                }],
  770                                |_, diagnostic, cx| match diagnostic.source_kind {
  771                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  772                                        adapter.retain_old_diagnostic(diagnostic, cx)
  773                                    }
  774                                    DiagnosticSourceKind::Pulled => true,
  775                                },
  776                                cx,
  777                            )
  778                            .log_err();
  779                        })
  780                        .ok();
  781                    }
  782                }
  783            })
  784            .detach();
  785        language_server
  786            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  787                let adapter = adapter.adapter.clone();
  788                let delegate = delegate.clone();
  789                let this = lsp_store.clone();
  790                move |params, cx| {
  791                    let adapter = adapter.clone();
  792                    let delegate = delegate.clone();
  793                    let this = this.clone();
  794                    let mut cx = cx.clone();
  795                    async move {
  796                        let toolchain_for_id = this
  797                            .update(&mut cx, |this, _| {
  798                                this.as_local()?.language_server_ids.iter().find_map(
  799                                    |(seed, value)| {
  800                                        (value.id == server_id).then(|| seed.toolchain.clone())
  801                                    },
  802                                )
  803                            })?
  804                            .context("Expected the LSP store to be in a local mode")?;
  805
  806                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  807                        for item in &params.items {
  808                            let scope_uri = item.scope_uri.clone();
  809                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  810                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  811                            else {
  812                                // We've already queried workspace configuration of this URI.
  813                                continue;
  814                            };
  815                            let workspace_config = Self::workspace_configuration_for_adapter(
  816                                adapter.clone(),
  817                                &delegate,
  818                                toolchain_for_id.clone(),
  819                                scope_uri,
  820                                &mut cx,
  821                            )
  822                            .await?;
  823                            new_scope_uri.insert(workspace_config);
  824                        }
  825
  826                        Ok(params
  827                            .items
  828                            .into_iter()
  829                            .filter_map(|item| {
  830                                let workspace_config =
  831                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  832                                if let Some(section) = &item.section {
  833                                    Some(
  834                                        workspace_config
  835                                            .get(section)
  836                                            .cloned()
  837                                            .unwrap_or(serde_json::Value::Null),
  838                                    )
  839                                } else {
  840                                    Some(workspace_config.clone())
  841                                }
  842                            })
  843                            .collect())
  844                    }
  845                }
  846            })
  847            .detach();
  848
  849        language_server
  850            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  851                let this = lsp_store.clone();
  852                move |_, cx| {
  853                    let this = this.clone();
  854                    let cx = cx.clone();
  855                    async move {
  856                        let Some(server) =
  857                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  858                        else {
  859                            return Ok(None);
  860                        };
  861                        let root = server.workspace_folders();
  862                        Ok(Some(
  863                            root.into_iter()
  864                                .map(|uri| WorkspaceFolder {
  865                                    uri,
  866                                    name: Default::default(),
  867                                })
  868                                .collect(),
  869                        ))
  870                    }
  871                }
  872            })
  873            .detach();
  874        // Even though we don't have handling for these requests, respond to them to
  875        // avoid stalling any language server like `gopls` which waits for a response
  876        // to these requests when initializing.
  877        language_server
  878            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  879                let this = lsp_store.clone();
  880                move |params, cx| {
  881                    let this = this.clone();
  882                    let mut cx = cx.clone();
  883                    async move {
  884                        this.update(&mut cx, |this, _| {
  885                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  886                            {
  887                                status
  888                                    .progress_tokens
  889                                    .insert(ProgressToken::from_lsp(params.token));
  890                            }
  891                        })?;
  892
  893                        Ok(())
  894                    }
  895                }
  896            })
  897            .detach();
  898
  899        language_server
  900            .on_request::<lsp::request::RegisterCapability, _, _>({
  901                let lsp_store = lsp_store.clone();
  902                move |params, cx| {
  903                    let lsp_store = lsp_store.clone();
  904                    let mut cx = cx.clone();
  905                    async move {
  906                        lsp_store
  907                            .update(&mut cx, |lsp_store, cx| {
  908                                if lsp_store.as_local().is_some() {
  909                                    match lsp_store
  910                                        .register_server_capabilities(server_id, params, cx)
  911                                    {
  912                                        Ok(()) => {}
  913                                        Err(e) => {
  914                                            log::error!(
  915                                                "Failed to register server capabilities: {e:#}"
  916                                            );
  917                                        }
  918                                    };
  919                                }
  920                            })
  921                            .ok();
  922                        Ok(())
  923                    }
  924                }
  925            })
  926            .detach();
  927
  928        language_server
  929            .on_request::<lsp::request::UnregisterCapability, _, _>({
  930                let lsp_store = lsp_store.clone();
  931                move |params, cx| {
  932                    let lsp_store = lsp_store.clone();
  933                    let mut cx = cx.clone();
  934                    async move {
  935                        lsp_store
  936                            .update(&mut cx, |lsp_store, cx| {
  937                                if lsp_store.as_local().is_some() {
  938                                    match lsp_store
  939                                        .unregister_server_capabilities(server_id, params, cx)
  940                                    {
  941                                        Ok(()) => {}
  942                                        Err(e) => {
  943                                            log::error!(
  944                                                "Failed to unregister server capabilities: {e:#}"
  945                                            );
  946                                        }
  947                                    }
  948                                }
  949                            })
  950                            .ok();
  951                        Ok(())
  952                    }
  953                }
  954            })
  955            .detach();
  956
  957        language_server
  958            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  959                let this = lsp_store.clone();
  960                move |params, cx| {
  961                    let mut cx = cx.clone();
  962                    let this = this.clone();
  963                    async move {
  964                        LocalLspStore::on_lsp_workspace_edit(
  965                            this.clone(),
  966                            params,
  967                            server_id,
  968                            &mut cx,
  969                        )
  970                        .await
  971                    }
  972                }
  973            })
  974            .detach();
  975
  976        language_server
  977            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  978                let lsp_store = lsp_store.clone();
  979                let request_id = Arc::new(AtomicUsize::new(0));
  980                move |(), cx| {
  981                    let lsp_store = lsp_store.clone();
  982                    let request_id = request_id.clone();
  983                    let mut cx = cx.clone();
  984                    async move {
  985                        lsp_store
  986                            .update(&mut cx, |lsp_store, cx| {
  987                                let request_id =
  988                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
  989                                cx.emit(LspStoreEvent::RefreshInlayHints {
  990                                    server_id,
  991                                    request_id,
  992                                });
  993                                lsp_store
  994                                    .downstream_client
  995                                    .as_ref()
  996                                    .map(|(client, project_id)| {
  997                                        client.send(proto::RefreshInlayHints {
  998                                            project_id: *project_id,
  999                                            server_id: server_id.to_proto(),
 1000                                            request_id: request_id.map(|id| id as u64),
 1001                                        })
 1002                                    })
 1003                            })?
 1004                            .transpose()?;
 1005                        Ok(())
 1006                    }
 1007                }
 1008            })
 1009            .detach();
 1010
 1011        language_server
 1012            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1013                let this = lsp_store.clone();
 1014                move |(), cx| {
 1015                    let this = this.clone();
 1016                    let mut cx = cx.clone();
 1017                    async move {
 1018                        this.update(&mut cx, |this, cx| {
 1019                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1020                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1021                                client.send(proto::RefreshCodeLens {
 1022                                    project_id: *project_id,
 1023                                })
 1024                            })
 1025                        })?
 1026                        .transpose()?;
 1027                        Ok(())
 1028                    }
 1029                }
 1030            })
 1031            .detach();
 1032
 1033        language_server
 1034            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1035                let this = lsp_store.clone();
 1036                move |(), cx| {
 1037                    let this = this.clone();
 1038                    let mut cx = cx.clone();
 1039                    async move {
 1040                        this.update(&mut cx, |lsp_store, _| {
 1041                            lsp_store.pull_workspace_diagnostics(server_id);
 1042                            lsp_store
 1043                                .downstream_client
 1044                                .as_ref()
 1045                                .map(|(client, project_id)| {
 1046                                    client.send(proto::PullWorkspaceDiagnostics {
 1047                                        project_id: *project_id,
 1048                                        server_id: server_id.to_proto(),
 1049                                    })
 1050                                })
 1051                        })?
 1052                        .transpose()?;
 1053                        Ok(())
 1054                    }
 1055                }
 1056            })
 1057            .detach();
 1058
 1059        language_server
 1060            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1061                let this = lsp_store.clone();
 1062                let name = name.to_string();
 1063                let adapter = adapter.clone();
 1064                move |params, cx| {
 1065                    let this = this.clone();
 1066                    let name = name.to_string();
 1067                    let adapter = adapter.clone();
 1068                    let mut cx = cx.clone();
 1069                    async move {
 1070                        let actions = params.actions.unwrap_or_default();
 1071                        let message = params.message.clone();
 1072                        let (tx, rx) = smol::channel::bounded(1);
 1073                        let request = LanguageServerPromptRequest {
 1074                            level: match params.typ {
 1075                                lsp::MessageType::ERROR => PromptLevel::Critical,
 1076                                lsp::MessageType::WARNING => PromptLevel::Warning,
 1077                                _ => PromptLevel::Info,
 1078                            },
 1079                            message: params.message,
 1080                            actions,
 1081                            response_channel: tx,
 1082                            lsp_name: name.clone(),
 1083                        };
 1084
 1085                        let did_update = this
 1086                            .update(&mut cx, |_, cx| {
 1087                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1088                            })
 1089                            .is_ok();
 1090                        if did_update {
 1091                            let response = rx.recv().await.ok();
 1092                            if let Some(ref selected_action) = response {
 1093                                let context = language::PromptResponseContext {
 1094                                    message,
 1095                                    selected_action: selected_action.clone(),
 1096                                };
 1097                                adapter.process_prompt_response(&context, &mut cx)
 1098                            }
 1099
 1100                            Ok(response)
 1101                        } else {
 1102                            Ok(None)
 1103                        }
 1104                    }
 1105                }
 1106            })
 1107            .detach();
 1108        language_server
 1109            .on_notification::<lsp::notification::ShowMessage, _>({
 1110                let this = lsp_store.clone();
 1111                let name = name.to_string();
 1112                move |params, cx| {
 1113                    let this = this.clone();
 1114                    let name = name.to_string();
 1115                    let mut cx = cx.clone();
 1116
 1117                    let (tx, _) = smol::channel::bounded(1);
 1118                    let request = LanguageServerPromptRequest {
 1119                        level: match params.typ {
 1120                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1121                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1122                            _ => PromptLevel::Info,
 1123                        },
 1124                        message: params.message,
 1125                        actions: vec![],
 1126                        response_channel: tx,
 1127                        lsp_name: name,
 1128                    };
 1129
 1130                    let _ = this.update(&mut cx, |_, cx| {
 1131                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1132                    });
 1133                }
 1134            })
 1135            .detach();
 1136
 1137        let disk_based_diagnostics_progress_token =
 1138            adapter.disk_based_diagnostics_progress_token.clone();
 1139
 1140        language_server
 1141            .on_notification::<lsp::notification::Progress, _>({
 1142                let this = lsp_store.clone();
 1143                move |params, cx| {
 1144                    if let Some(this) = this.upgrade() {
 1145                        this.update(cx, |this, cx| {
 1146                            this.on_lsp_progress(
 1147                                params,
 1148                                server_id,
 1149                                disk_based_diagnostics_progress_token.clone(),
 1150                                cx,
 1151                            );
 1152                        })
 1153                        .ok();
 1154                    }
 1155                }
 1156            })
 1157            .detach();
 1158
 1159        language_server
 1160            .on_notification::<lsp::notification::LogMessage, _>({
 1161                let this = lsp_store.clone();
 1162                move |params, cx| {
 1163                    if let Some(this) = this.upgrade() {
 1164                        this.update(cx, |_, cx| {
 1165                            cx.emit(LspStoreEvent::LanguageServerLog(
 1166                                server_id,
 1167                                LanguageServerLogType::Log(params.typ),
 1168                                params.message,
 1169                            ));
 1170                        })
 1171                        .ok();
 1172                    }
 1173                }
 1174            })
 1175            .detach();
 1176
 1177        language_server
 1178            .on_notification::<lsp::notification::LogTrace, _>({
 1179                let this = lsp_store.clone();
 1180                move |params, cx| {
 1181                    let mut cx = cx.clone();
 1182                    if let Some(this) = this.upgrade() {
 1183                        this.update(&mut cx, |_, cx| {
 1184                            cx.emit(LspStoreEvent::LanguageServerLog(
 1185                                server_id,
 1186                                LanguageServerLogType::Trace {
 1187                                    verbose_info: params.verbose,
 1188                                },
 1189                                params.message,
 1190                            ));
 1191                        })
 1192                        .ok();
 1193                    }
 1194                }
 1195            })
 1196            .detach();
 1197
 1198        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1199        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1200        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1201        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1202    }
 1203
 1204    fn shutdown_language_servers_on_quit(
 1205        &mut self,
 1206        _: &mut Context<LspStore>,
 1207    ) -> impl Future<Output = ()> + use<> {
 1208        let shutdown_futures = self
 1209            .language_servers
 1210            .drain()
 1211            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1212            .collect::<Vec<_>>();
 1213
 1214        async move {
 1215            join_all(shutdown_futures).await;
 1216        }
 1217    }
 1218
 1219    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1220        match server_state {
 1221            LanguageServerState::Running { server, .. } => {
 1222                if let Some(shutdown) = server.shutdown() {
 1223                    shutdown.await;
 1224                }
 1225            }
 1226            LanguageServerState::Starting { startup, .. } => {
 1227                if let Some(server) = startup.await
 1228                    && let Some(shutdown) = server.shutdown()
 1229                {
 1230                    shutdown.await;
 1231                }
 1232            }
 1233        }
 1234        Ok(())
 1235    }
 1236
 1237    fn language_servers_for_worktree(
 1238        &self,
 1239        worktree_id: WorktreeId,
 1240    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1241        self.language_server_ids
 1242            .iter()
 1243            .filter_map(move |(seed, state)| {
 1244                if seed.worktree_id != worktree_id {
 1245                    return None;
 1246                }
 1247
 1248                if let Some(LanguageServerState::Running { server, .. }) =
 1249                    self.language_servers.get(&state.id)
 1250                {
 1251                    Some(server)
 1252                } else {
 1253                    None
 1254                }
 1255            })
 1256    }
 1257
 1258    fn language_server_ids_for_project_path(
 1259        &self,
 1260        project_path: ProjectPath,
 1261        language: &Language,
 1262        cx: &mut App,
 1263    ) -> Vec<LanguageServerId> {
 1264        let Some(worktree) = self
 1265            .worktree_store
 1266            .read(cx)
 1267            .worktree_for_id(project_path.worktree_id, cx)
 1268        else {
 1269            return Vec::new();
 1270        };
 1271        let delegate: Arc<dyn ManifestDelegate> =
 1272            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1273
 1274        self.lsp_tree
 1275            .get(
 1276                project_path,
 1277                language.name(),
 1278                language.manifest(),
 1279                &delegate,
 1280                cx,
 1281            )
 1282            .collect::<Vec<_>>()
 1283    }
 1284
 1285    fn language_server_ids_for_buffer(
 1286        &self,
 1287        buffer: &Buffer,
 1288        cx: &mut App,
 1289    ) -> Vec<LanguageServerId> {
 1290        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1291            let worktree_id = file.worktree_id(cx);
 1292
 1293            let path: Arc<RelPath> = file
 1294                .path()
 1295                .parent()
 1296                .map(Arc::from)
 1297                .unwrap_or_else(|| file.path().clone());
 1298            let worktree_path = ProjectPath { worktree_id, path };
 1299            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1300        } else {
 1301            Vec::new()
 1302        }
 1303    }
 1304
 1305    fn language_servers_for_buffer<'a>(
 1306        &'a self,
 1307        buffer: &'a Buffer,
 1308        cx: &'a mut App,
 1309    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1310        self.language_server_ids_for_buffer(buffer, cx)
 1311            .into_iter()
 1312            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1313                LanguageServerState::Running {
 1314                    adapter, server, ..
 1315                } => Some((adapter, server)),
 1316                _ => None,
 1317            })
 1318    }
 1319
 1320    async fn execute_code_action_kind_locally(
 1321        lsp_store: WeakEntity<LspStore>,
 1322        mut buffers: Vec<Entity<Buffer>>,
 1323        kind: CodeActionKind,
 1324        push_to_history: bool,
 1325        cx: &mut AsyncApp,
 1326    ) -> anyhow::Result<ProjectTransaction> {
 1327        // Do not allow multiple concurrent code actions requests for the
 1328        // same buffer.
 1329        lsp_store.update(cx, |this, cx| {
 1330            let this = this.as_local_mut().unwrap();
 1331            buffers.retain(|buffer| {
 1332                this.buffers_being_formatted
 1333                    .insert(buffer.read(cx).remote_id())
 1334            });
 1335        })?;
 1336        let _cleanup = defer({
 1337            let this = lsp_store.clone();
 1338            let mut cx = cx.clone();
 1339            let buffers = &buffers;
 1340            move || {
 1341                this.update(&mut cx, |this, cx| {
 1342                    let this = this.as_local_mut().unwrap();
 1343                    for buffer in buffers {
 1344                        this.buffers_being_formatted
 1345                            .remove(&buffer.read(cx).remote_id());
 1346                    }
 1347                })
 1348                .ok();
 1349            }
 1350        });
 1351        let mut project_transaction = ProjectTransaction::default();
 1352
 1353        for buffer in &buffers {
 1354            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1355                buffer.update(cx, |buffer, cx| {
 1356                    lsp_store
 1357                        .as_local()
 1358                        .unwrap()
 1359                        .language_servers_for_buffer(buffer, cx)
 1360                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1361                        .collect::<Vec<_>>()
 1362                })
 1363            })?;
 1364            for (_, language_server) in adapters_and_servers.iter() {
 1365                let actions = Self::get_server_code_actions_from_action_kinds(
 1366                    &lsp_store,
 1367                    language_server.server_id(),
 1368                    vec![kind.clone()],
 1369                    buffer,
 1370                    cx,
 1371                )
 1372                .await?;
 1373                Self::execute_code_actions_on_server(
 1374                    &lsp_store,
 1375                    language_server,
 1376                    actions,
 1377                    push_to_history,
 1378                    &mut project_transaction,
 1379                    cx,
 1380                )
 1381                .await?;
 1382            }
 1383        }
 1384        Ok(project_transaction)
 1385    }
 1386
 1387    async fn format_locally(
 1388        lsp_store: WeakEntity<LspStore>,
 1389        mut buffers: Vec<FormattableBuffer>,
 1390        push_to_history: bool,
 1391        trigger: FormatTrigger,
 1392        logger: zlog::Logger,
 1393        cx: &mut AsyncApp,
 1394    ) -> anyhow::Result<ProjectTransaction> {
 1395        // Do not allow multiple concurrent formatting requests for the
 1396        // same buffer.
 1397        lsp_store.update(cx, |this, cx| {
 1398            let this = this.as_local_mut().unwrap();
 1399            buffers.retain(|buffer| {
 1400                this.buffers_being_formatted
 1401                    .insert(buffer.handle.read(cx).remote_id())
 1402            });
 1403        })?;
 1404
 1405        let _cleanup = defer({
 1406            let this = lsp_store.clone();
 1407            let mut cx = cx.clone();
 1408            let buffers = &buffers;
 1409            move || {
 1410                this.update(&mut cx, |this, cx| {
 1411                    let this = this.as_local_mut().unwrap();
 1412                    for buffer in buffers {
 1413                        this.buffers_being_formatted
 1414                            .remove(&buffer.handle.read(cx).remote_id());
 1415                    }
 1416                })
 1417                .ok();
 1418            }
 1419        });
 1420
 1421        let mut project_transaction = ProjectTransaction::default();
 1422
 1423        for buffer in &buffers {
 1424            zlog::debug!(
 1425                logger =>
 1426                "formatting buffer '{:?}'",
 1427                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1428            );
 1429            // Create an empty transaction to hold all of the formatting edits.
 1430            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1431                // ensure no transactions created while formatting are
 1432                // grouped with the previous transaction in the history
 1433                // based on the transaction group interval
 1434                buffer.finalize_last_transaction();
 1435                buffer
 1436                    .start_transaction()
 1437                    .context("transaction already open")?;
 1438                buffer.end_transaction(cx);
 1439                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1440                buffer.finalize_last_transaction();
 1441                anyhow::Ok(transaction_id)
 1442            })??;
 1443
 1444            let result = Self::format_buffer_locally(
 1445                lsp_store.clone(),
 1446                buffer,
 1447                formatting_transaction_id,
 1448                trigger,
 1449                logger,
 1450                cx,
 1451            )
 1452            .await;
 1453
 1454            buffer.handle.update(cx, |buffer, cx| {
 1455                let Some(formatting_transaction) =
 1456                    buffer.get_transaction(formatting_transaction_id).cloned()
 1457                else {
 1458                    zlog::warn!(logger => "no formatting transaction");
 1459                    return;
 1460                };
 1461                if formatting_transaction.edit_ids.is_empty() {
 1462                    zlog::debug!(logger => "no changes made while formatting");
 1463                    buffer.forget_transaction(formatting_transaction_id);
 1464                    return;
 1465                }
 1466                if !push_to_history {
 1467                    zlog::trace!(logger => "forgetting format transaction");
 1468                    buffer.forget_transaction(formatting_transaction.id);
 1469                }
 1470                project_transaction
 1471                    .0
 1472                    .insert(cx.entity(), formatting_transaction);
 1473            })?;
 1474
 1475            result?;
 1476        }
 1477
 1478        Ok(project_transaction)
 1479    }
 1480
 1481    async fn format_buffer_locally(
 1482        lsp_store: WeakEntity<LspStore>,
 1483        buffer: &FormattableBuffer,
 1484        formatting_transaction_id: clock::Lamport,
 1485        trigger: FormatTrigger,
 1486        logger: zlog::Logger,
 1487        cx: &mut AsyncApp,
 1488    ) -> Result<()> {
 1489        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1490            buffer.handle.update(cx, |buffer, cx| {
 1491                let adapters_and_servers = lsp_store
 1492                    .as_local()
 1493                    .unwrap()
 1494                    .language_servers_for_buffer(buffer, cx)
 1495                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1496                    .collect::<Vec<_>>();
 1497                let settings =
 1498                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1499                        .into_owned();
 1500                (adapters_and_servers, settings)
 1501            })
 1502        })?;
 1503
 1504        /// Apply edits to the buffer that will become part of the formatting transaction.
 1505        /// Fails if the buffer has been edited since the start of that transaction.
 1506        fn extend_formatting_transaction(
 1507            buffer: &FormattableBuffer,
 1508            formatting_transaction_id: text::TransactionId,
 1509            cx: &mut AsyncApp,
 1510            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1511        ) -> anyhow::Result<()> {
 1512            buffer.handle.update(cx, |buffer, cx| {
 1513                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1514                if last_transaction_id != Some(formatting_transaction_id) {
 1515                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1516                }
 1517                buffer.start_transaction();
 1518                operation(buffer, cx);
 1519                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1520                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1521                }
 1522                Ok(())
 1523            })?
 1524        }
 1525
 1526        // handle whitespace formatting
 1527        if settings.remove_trailing_whitespace_on_save {
 1528            zlog::trace!(logger => "removing trailing whitespace");
 1529            let diff = buffer
 1530                .handle
 1531                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1532                .await;
 1533            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1534                buffer.apply_diff(diff, cx);
 1535            })?;
 1536        }
 1537
 1538        if settings.ensure_final_newline_on_save {
 1539            zlog::trace!(logger => "ensuring final newline");
 1540            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1541                buffer.ensure_final_newline(cx);
 1542            })?;
 1543        }
 1544
 1545        // Formatter for `code_actions_on_format` that runs before
 1546        // the rest of the formatters
 1547        let mut code_actions_on_format_formatters = None;
 1548        let should_run_code_actions_on_format = !matches!(
 1549            (trigger, &settings.format_on_save),
 1550            (FormatTrigger::Save, &FormatOnSave::Off)
 1551        );
 1552        if should_run_code_actions_on_format {
 1553            let have_code_actions_to_run_on_format = settings
 1554                .code_actions_on_format
 1555                .values()
 1556                .any(|enabled| *enabled);
 1557            if have_code_actions_to_run_on_format {
 1558                zlog::trace!(logger => "going to run code actions on format");
 1559                code_actions_on_format_formatters = Some(
 1560                    settings
 1561                        .code_actions_on_format
 1562                        .iter()
 1563                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1564                        .cloned()
 1565                        .map(Formatter::CodeAction)
 1566                        .collect::<Vec<_>>(),
 1567                );
 1568            }
 1569        }
 1570
 1571        let formatters = match (trigger, &settings.format_on_save) {
 1572            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1573            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1574                settings.formatter.as_ref()
 1575            }
 1576        };
 1577
 1578        let formatters = code_actions_on_format_formatters
 1579            .iter()
 1580            .flatten()
 1581            .chain(formatters);
 1582
 1583        for formatter in formatters {
 1584            let formatter = if formatter == &Formatter::Auto {
 1585                if settings.prettier.allowed {
 1586                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1587                    &Formatter::Prettier
 1588                } else {
 1589                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1590                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1591                }
 1592            } else {
 1593                formatter
 1594            };
 1595            match formatter {
 1596                Formatter::Auto => unreachable!("Auto resolved above"),
 1597                Formatter::Prettier => {
 1598                    let logger = zlog::scoped!(logger => "prettier");
 1599                    zlog::trace!(logger => "formatting");
 1600                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1601
 1602                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1603                        lsp_store.prettier_store().unwrap().downgrade()
 1604                    })?;
 1605                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1606                        .await
 1607                        .transpose()?;
 1608                    let Some(diff) = diff else {
 1609                        zlog::trace!(logger => "No changes");
 1610                        continue;
 1611                    };
 1612
 1613                    extend_formatting_transaction(
 1614                        buffer,
 1615                        formatting_transaction_id,
 1616                        cx,
 1617                        |buffer, cx| {
 1618                            buffer.apply_diff(diff, cx);
 1619                        },
 1620                    )?;
 1621                }
 1622                Formatter::External { command, arguments } => {
 1623                    let logger = zlog::scoped!(logger => "command");
 1624                    zlog::trace!(logger => "formatting");
 1625                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1626
 1627                    let diff = Self::format_via_external_command(
 1628                        buffer,
 1629                        command.as_ref(),
 1630                        arguments.as_deref(),
 1631                        cx,
 1632                    )
 1633                    .await
 1634                    .with_context(|| {
 1635                        format!("Failed to format buffer via external command: {}", command)
 1636                    })?;
 1637                    let Some(diff) = diff else {
 1638                        zlog::trace!(logger => "No changes");
 1639                        continue;
 1640                    };
 1641
 1642                    extend_formatting_transaction(
 1643                        buffer,
 1644                        formatting_transaction_id,
 1645                        cx,
 1646                        |buffer, cx| {
 1647                            buffer.apply_diff(diff, cx);
 1648                        },
 1649                    )?;
 1650                }
 1651                Formatter::LanguageServer(specifier) => {
 1652                    let logger = zlog::scoped!(logger => "language-server");
 1653                    zlog::trace!(logger => "formatting");
 1654                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1655
 1656                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1657                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1658                        continue;
 1659                    };
 1660
 1661                    let language_server = match specifier {
 1662                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1663                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1664                                if adapter.name.0.as_ref() == name {
 1665                                    Some(server.clone())
 1666                                } else {
 1667                                    None
 1668                                }
 1669                            })
 1670                        }
 1671                        settings::LanguageServerFormatterSpecifier::Current => {
 1672                            adapters_and_servers.first().map(|e| e.1.clone())
 1673                        }
 1674                    };
 1675
 1676                    let Some(language_server) = language_server else {
 1677                        log::debug!(
 1678                            "No language server found to format buffer '{:?}'. Skipping",
 1679                            buffer_path_abs.as_path().to_string_lossy()
 1680                        );
 1681                        continue;
 1682                    };
 1683
 1684                    zlog::trace!(
 1685                        logger =>
 1686                        "Formatting buffer '{:?}' using language server '{:?}'",
 1687                        buffer_path_abs.as_path().to_string_lossy(),
 1688                        language_server.name()
 1689                    );
 1690
 1691                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1692                        zlog::trace!(logger => "formatting ranges");
 1693                        Self::format_ranges_via_lsp(
 1694                            &lsp_store,
 1695                            &buffer.handle,
 1696                            ranges,
 1697                            buffer_path_abs,
 1698                            &language_server,
 1699                            &settings,
 1700                            cx,
 1701                        )
 1702                        .await
 1703                        .context("Failed to format ranges via language server")?
 1704                    } else {
 1705                        zlog::trace!(logger => "formatting full");
 1706                        Self::format_via_lsp(
 1707                            &lsp_store,
 1708                            &buffer.handle,
 1709                            buffer_path_abs,
 1710                            &language_server,
 1711                            &settings,
 1712                            cx,
 1713                        )
 1714                        .await
 1715                        .context("failed to format via language server")?
 1716                    };
 1717
 1718                    if edits.is_empty() {
 1719                        zlog::trace!(logger => "No changes");
 1720                        continue;
 1721                    }
 1722                    extend_formatting_transaction(
 1723                        buffer,
 1724                        formatting_transaction_id,
 1725                        cx,
 1726                        |buffer, cx| {
 1727                            buffer.edit(edits, None, cx);
 1728                        },
 1729                    )?;
 1730                }
 1731                Formatter::CodeAction(code_action_name) => {
 1732                    let logger = zlog::scoped!(logger => "code-actions");
 1733                    zlog::trace!(logger => "formatting");
 1734                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1735
 1736                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1737                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1738                        continue;
 1739                    };
 1740
 1741                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1742                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1743
 1744                    let mut actions_and_servers = Vec::new();
 1745
 1746                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1747                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1748                            &lsp_store,
 1749                            language_server.server_id(),
 1750                            vec![code_action_kind.clone()],
 1751                            &buffer.handle,
 1752                            cx,
 1753                        )
 1754                        .await
 1755                        .with_context(|| {
 1756                            format!(
 1757                                "Failed to resolve code action {:?} with language server {}",
 1758                                code_action_kind,
 1759                                language_server.name()
 1760                            )
 1761                        });
 1762                        let Ok(actions) = actions_result else {
 1763                            // note: it may be better to set result to the error and break formatters here
 1764                            // but for now we try to execute the actions that we can resolve and skip the rest
 1765                            zlog::error!(
 1766                                logger =>
 1767                                "Failed to resolve code action {:?} with language server {}",
 1768                                code_action_kind,
 1769                                language_server.name()
 1770                            );
 1771                            continue;
 1772                        };
 1773                        for action in actions {
 1774                            actions_and_servers.push((action, index));
 1775                        }
 1776                    }
 1777
 1778                    if actions_and_servers.is_empty() {
 1779                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1780                        continue;
 1781                    }
 1782
 1783                    'actions: for (mut action, server_index) in actions_and_servers {
 1784                        let server = &adapters_and_servers[server_index].1;
 1785
 1786                        let describe_code_action = |action: &CodeAction| {
 1787                            format!(
 1788                                "code action '{}' with title \"{}\" on server {}",
 1789                                action
 1790                                    .lsp_action
 1791                                    .action_kind()
 1792                                    .unwrap_or("unknown".into())
 1793                                    .as_str(),
 1794                                action.lsp_action.title(),
 1795                                server.name(),
 1796                            )
 1797                        };
 1798
 1799                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1800
 1801                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1802                            zlog::error!(
 1803                                logger =>
 1804                                "Failed to resolve {}. Error: {}",
 1805                                describe_code_action(&action),
 1806                                err
 1807                            );
 1808                            continue;
 1809                        }
 1810
 1811                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1812                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1813                            // but filters out and logs warnings for code actions that require unreasonably
 1814                            // difficult handling on our part, such as:
 1815                            // - applying edits that call commands
 1816                            //   which can result in arbitrary workspace edits being sent from the server that
 1817                            //   have no way of being tied back to the command that initiated them (i.e. we
 1818                            //   can't know which edits are part of the format request, or if the server is done sending
 1819                            //   actions in response to the command)
 1820                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1821                            //   as we then would need to handle such changes correctly in the local history as well
 1822                            //   as the remote history through the ProjectTransaction
 1823                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1824                            // Supporting these actions is not impossible, but not supported as of yet.
 1825                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1826                                zlog::trace!(
 1827                                    logger =>
 1828                                    "No changes for code action. Skipping {}",
 1829                                    describe_code_action(&action),
 1830                                );
 1831                                continue;
 1832                            }
 1833
 1834                            let mut operations = Vec::new();
 1835                            if let Some(document_changes) = edit.document_changes {
 1836                                match document_changes {
 1837                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1838                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1839                                    ),
 1840                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1841                                }
 1842                            } else if let Some(changes) = edit.changes {
 1843                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1844                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1845                                        text_document:
 1846                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1847                                                uri,
 1848                                                version: None,
 1849                                            },
 1850                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1851                                    })
 1852                                }));
 1853                            }
 1854
 1855                            let mut edits = Vec::with_capacity(operations.len());
 1856
 1857                            if operations.is_empty() {
 1858                                zlog::trace!(
 1859                                    logger =>
 1860                                    "No changes for code action. Skipping {}",
 1861                                    describe_code_action(&action),
 1862                                );
 1863                                continue;
 1864                            }
 1865                            for operation in operations {
 1866                                let op = match operation {
 1867                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1868                                    lsp::DocumentChangeOperation::Op(_) => {
 1869                                        zlog::warn!(
 1870                                            logger =>
 1871                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1872                                            describe_code_action(&action),
 1873                                        );
 1874                                        continue 'actions;
 1875                                    }
 1876                                };
 1877                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1878                                    zlog::warn!(
 1879                                        logger =>
 1880                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1881                                        &op.text_document.uri,
 1882                                        describe_code_action(&action),
 1883                                    );
 1884                                    continue 'actions;
 1885                                };
 1886                                if &file_path != buffer_path_abs {
 1887                                    zlog::warn!(
 1888                                        logger =>
 1889                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1890                                        file_path,
 1891                                        buffer_path_abs,
 1892                                        describe_code_action(&action),
 1893                                    );
 1894                                    continue 'actions;
 1895                                }
 1896
 1897                                let mut lsp_edits = Vec::new();
 1898                                for edit in op.edits {
 1899                                    match edit {
 1900                                        Edit::Plain(edit) => {
 1901                                            if !lsp_edits.contains(&edit) {
 1902                                                lsp_edits.push(edit);
 1903                                            }
 1904                                        }
 1905                                        Edit::Annotated(edit) => {
 1906                                            if !lsp_edits.contains(&edit.text_edit) {
 1907                                                lsp_edits.push(edit.text_edit);
 1908                                            }
 1909                                        }
 1910                                        Edit::Snippet(_) => {
 1911                                            zlog::warn!(
 1912                                                logger =>
 1913                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1914                                                describe_code_action(&action),
 1915                                            );
 1916                                            continue 'actions;
 1917                                        }
 1918                                    }
 1919                                }
 1920                                let edits_result = lsp_store
 1921                                    .update(cx, |lsp_store, cx| {
 1922                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1923                                            &buffer.handle,
 1924                                            lsp_edits,
 1925                                            server.server_id(),
 1926                                            op.text_document.version,
 1927                                            cx,
 1928                                        )
 1929                                    })?
 1930                                    .await;
 1931                                let Ok(resolved_edits) = edits_result else {
 1932                                    zlog::warn!(
 1933                                        logger =>
 1934                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1935                                        buffer_path_abs.as_path(),
 1936                                        describe_code_action(&action),
 1937                                    );
 1938                                    continue 'actions;
 1939                                };
 1940                                edits.extend(resolved_edits);
 1941                            }
 1942
 1943                            if edits.is_empty() {
 1944                                zlog::warn!(logger => "No edits resolved from LSP");
 1945                                continue;
 1946                            }
 1947
 1948                            extend_formatting_transaction(
 1949                                buffer,
 1950                                formatting_transaction_id,
 1951                                cx,
 1952                                |buffer, cx| {
 1953                                    zlog::info!(
 1954                                        "Applying edits {edits:?}. Content: {:?}",
 1955                                        buffer.text()
 1956                                    );
 1957                                    buffer.edit(edits, None, cx);
 1958                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1959                                },
 1960                            )?;
 1961                        }
 1962
 1963                        if let Some(command) = action.lsp_action.command() {
 1964                            zlog::warn!(
 1965                                logger =>
 1966                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1967                                &command.command,
 1968                            );
 1969
 1970                            // bail early if command is invalid
 1971                            let server_capabilities = server.capabilities();
 1972                            let available_commands = server_capabilities
 1973                                .execute_command_provider
 1974                                .as_ref()
 1975                                .map(|options| options.commands.as_slice())
 1976                                .unwrap_or_default();
 1977                            if !available_commands.contains(&command.command) {
 1978                                zlog::warn!(
 1979                                    logger =>
 1980                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1981                                    command.command,
 1982                                    server.name(),
 1983                                );
 1984                                continue;
 1985                            }
 1986
 1987                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1988                            extend_formatting_transaction(
 1989                                buffer,
 1990                                formatting_transaction_id,
 1991                                cx,
 1992                                |_, _| {},
 1993                            )?;
 1994                            zlog::info!(logger => "Executing command {}", &command.command);
 1995
 1996                            lsp_store.update(cx, |this, _| {
 1997                                this.as_local_mut()
 1998                                    .unwrap()
 1999                                    .last_workspace_edits_by_language_server
 2000                                    .remove(&server.server_id());
 2001                            })?;
 2002
 2003                            let execute_command_result = server
 2004                                .request::<lsp::request::ExecuteCommand>(
 2005                                    lsp::ExecuteCommandParams {
 2006                                        command: command.command.clone(),
 2007                                        arguments: command.arguments.clone().unwrap_or_default(),
 2008                                        ..Default::default()
 2009                                    },
 2010                                )
 2011                                .await
 2012                                .into_response();
 2013
 2014                            if execute_command_result.is_err() {
 2015                                zlog::error!(
 2016                                    logger =>
 2017                                    "Failed to execute command '{}' as part of {}",
 2018                                    &command.command,
 2019                                    describe_code_action(&action),
 2020                                );
 2021                                continue 'actions;
 2022                            }
 2023
 2024                            let mut project_transaction_command =
 2025                                lsp_store.update(cx, |this, _| {
 2026                                    this.as_local_mut()
 2027                                        .unwrap()
 2028                                        .last_workspace_edits_by_language_server
 2029                                        .remove(&server.server_id())
 2030                                        .unwrap_or_default()
 2031                                })?;
 2032
 2033                            if let Some(transaction) =
 2034                                project_transaction_command.0.remove(&buffer.handle)
 2035                            {
 2036                                zlog::trace!(
 2037                                    logger =>
 2038                                    "Successfully captured {} edits that resulted from command {}",
 2039                                    transaction.edit_ids.len(),
 2040                                    &command.command,
 2041                                );
 2042                                let transaction_id_project_transaction = transaction.id;
 2043                                buffer.handle.update(cx, |buffer, _| {
 2044                                    // it may have been removed from history if push_to_history was
 2045                                    // false in deserialize_workspace_edit. If so push it so we
 2046                                    // can merge it with the format transaction
 2047                                    // and pop the combined transaction off the history stack
 2048                                    // later if push_to_history is false
 2049                                    if buffer.get_transaction(transaction.id).is_none() {
 2050                                        buffer.push_transaction(transaction, Instant::now());
 2051                                    }
 2052                                    buffer.merge_transactions(
 2053                                        transaction_id_project_transaction,
 2054                                        formatting_transaction_id,
 2055                                    );
 2056                                })?;
 2057                            }
 2058
 2059                            if !project_transaction_command.0.is_empty() {
 2060                                let mut extra_buffers = String::new();
 2061                                for buffer in project_transaction_command.0.keys() {
 2062                                    buffer
 2063                                        .read_with(cx, |b, cx| {
 2064                                            if let Some(path) = b.project_path(cx) {
 2065                                                if !extra_buffers.is_empty() {
 2066                                                    extra_buffers.push_str(", ");
 2067                                                }
 2068                                                extra_buffers.push_str(path.path.as_unix_str());
 2069                                            }
 2070                                        })
 2071                                        .ok();
 2072                                }
 2073                                zlog::warn!(
 2074                                    logger =>
 2075                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2076                                    &command.command,
 2077                                    extra_buffers,
 2078                                );
 2079                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2080                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2081                                // add it so it's included, and merge it into the format transaction when its created later
 2082                            }
 2083                        }
 2084                    }
 2085                }
 2086            }
 2087        }
 2088
 2089        Ok(())
 2090    }
 2091
 2092    pub async fn format_ranges_via_lsp(
 2093        this: &WeakEntity<LspStore>,
 2094        buffer_handle: &Entity<Buffer>,
 2095        ranges: &[Range<Anchor>],
 2096        abs_path: &Path,
 2097        language_server: &Arc<LanguageServer>,
 2098        settings: &LanguageSettings,
 2099        cx: &mut AsyncApp,
 2100    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2101        let capabilities = &language_server.capabilities();
 2102        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2103        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2104            anyhow::bail!(
 2105                "{} language server does not support range formatting",
 2106                language_server.name()
 2107            );
 2108        }
 2109
 2110        let uri = file_path_to_lsp_url(abs_path)?;
 2111        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2112
 2113        let lsp_edits = {
 2114            let mut lsp_ranges = Vec::new();
 2115            this.update(cx, |_this, cx| {
 2116                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2117                // not have been sent to the language server. This seems like a fairly systemic
 2118                // issue, though, the resolution probably is not specific to formatting.
 2119                //
 2120                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2121                // LSP.
 2122                let snapshot = buffer_handle.read(cx).snapshot();
 2123                for range in ranges {
 2124                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2125                }
 2126                anyhow::Ok(())
 2127            })??;
 2128
 2129            let mut edits = None;
 2130            for range in lsp_ranges {
 2131                if let Some(mut edit) = language_server
 2132                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2133                        text_document: text_document.clone(),
 2134                        range,
 2135                        options: lsp_command::lsp_formatting_options(settings),
 2136                        work_done_progress_params: Default::default(),
 2137                    })
 2138                    .await
 2139                    .into_response()?
 2140                {
 2141                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2142                }
 2143            }
 2144            edits
 2145        };
 2146
 2147        if let Some(lsp_edits) = lsp_edits {
 2148            this.update(cx, |this, cx| {
 2149                this.as_local_mut().unwrap().edits_from_lsp(
 2150                    buffer_handle,
 2151                    lsp_edits,
 2152                    language_server.server_id(),
 2153                    None,
 2154                    cx,
 2155                )
 2156            })?
 2157            .await
 2158        } else {
 2159            Ok(Vec::with_capacity(0))
 2160        }
 2161    }
 2162
 2163    async fn format_via_lsp(
 2164        this: &WeakEntity<LspStore>,
 2165        buffer: &Entity<Buffer>,
 2166        abs_path: &Path,
 2167        language_server: &Arc<LanguageServer>,
 2168        settings: &LanguageSettings,
 2169        cx: &mut AsyncApp,
 2170    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2171        let logger = zlog::scoped!("lsp_format");
 2172        zlog::debug!(logger => "Formatting via LSP");
 2173
 2174        let uri = file_path_to_lsp_url(abs_path)?;
 2175        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2176        let capabilities = &language_server.capabilities();
 2177
 2178        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2179        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2180
 2181        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2182            let _timer = zlog::time!(logger => "format-full");
 2183            language_server
 2184                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2185                    text_document,
 2186                    options: lsp_command::lsp_formatting_options(settings),
 2187                    work_done_progress_params: Default::default(),
 2188                })
 2189                .await
 2190                .into_response()?
 2191        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2192            let _timer = zlog::time!(logger => "format-range");
 2193            let buffer_start = lsp::Position::new(0, 0);
 2194            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2195            language_server
 2196                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2197                    text_document: text_document.clone(),
 2198                    range: lsp::Range::new(buffer_start, buffer_end),
 2199                    options: lsp_command::lsp_formatting_options(settings),
 2200                    work_done_progress_params: Default::default(),
 2201                })
 2202                .await
 2203                .into_response()?
 2204        } else {
 2205            None
 2206        };
 2207
 2208        if let Some(lsp_edits) = lsp_edits {
 2209            this.update(cx, |this, cx| {
 2210                this.as_local_mut().unwrap().edits_from_lsp(
 2211                    buffer,
 2212                    lsp_edits,
 2213                    language_server.server_id(),
 2214                    None,
 2215                    cx,
 2216                )
 2217            })?
 2218            .await
 2219        } else {
 2220            Ok(Vec::with_capacity(0))
 2221        }
 2222    }
 2223
 2224    async fn format_via_external_command(
 2225        buffer: &FormattableBuffer,
 2226        command: &str,
 2227        arguments: Option<&[String]>,
 2228        cx: &mut AsyncApp,
 2229    ) -> Result<Option<Diff>> {
 2230        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2231            let file = File::from_dyn(buffer.file())?;
 2232            let worktree = file.worktree.read(cx);
 2233            let mut worktree_path = worktree.abs_path().to_path_buf();
 2234            if worktree.root_entry()?.is_file() {
 2235                worktree_path.pop();
 2236            }
 2237            Some(worktree_path)
 2238        })?;
 2239
 2240        let mut child = util::command::new_smol_command(command);
 2241
 2242        if let Some(buffer_env) = buffer.env.as_ref() {
 2243            child.envs(buffer_env);
 2244        }
 2245
 2246        if let Some(working_dir_path) = working_dir_path {
 2247            child.current_dir(working_dir_path);
 2248        }
 2249
 2250        if let Some(arguments) = arguments {
 2251            child.args(arguments.iter().map(|arg| {
 2252                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2253                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2254                } else {
 2255                    arg.replace("{buffer_path}", "Untitled")
 2256                }
 2257            }));
 2258        }
 2259
 2260        let mut child = child
 2261            .stdin(smol::process::Stdio::piped())
 2262            .stdout(smol::process::Stdio::piped())
 2263            .stderr(smol::process::Stdio::piped())
 2264            .spawn()?;
 2265
 2266        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2267        let text = buffer
 2268            .handle
 2269            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2270        for chunk in text.chunks() {
 2271            stdin.write_all(chunk.as_bytes()).await?;
 2272        }
 2273        stdin.flush().await?;
 2274
 2275        let output = child.output().await?;
 2276        anyhow::ensure!(
 2277            output.status.success(),
 2278            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2279            output.status.code(),
 2280            String::from_utf8_lossy(&output.stdout),
 2281            String::from_utf8_lossy(&output.stderr),
 2282        );
 2283
 2284        let stdout = String::from_utf8(output.stdout)?;
 2285        Ok(Some(
 2286            buffer
 2287                .handle
 2288                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2289                .await,
 2290        ))
 2291    }
 2292
 2293    async fn try_resolve_code_action(
 2294        lang_server: &LanguageServer,
 2295        action: &mut CodeAction,
 2296    ) -> anyhow::Result<()> {
 2297        match &mut action.lsp_action {
 2298            LspAction::Action(lsp_action) => {
 2299                if !action.resolved
 2300                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2301                    && lsp_action.data.is_some()
 2302                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2303                {
 2304                    **lsp_action = lang_server
 2305                        .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2306                        .await
 2307                        .into_response()?;
 2308                }
 2309            }
 2310            LspAction::CodeLens(lens) => {
 2311                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2312                    *lens = lang_server
 2313                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2314                        .await
 2315                        .into_response()?;
 2316                }
 2317            }
 2318            LspAction::Command(_) => {}
 2319        }
 2320
 2321        action.resolved = true;
 2322        anyhow::Ok(())
 2323    }
 2324
 2325    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2326        let buffer = buffer_handle.read(cx);
 2327
 2328        let file = buffer.file().cloned();
 2329
 2330        let Some(file) = File::from_dyn(file.as_ref()) else {
 2331            return;
 2332        };
 2333        if !file.is_local() {
 2334            return;
 2335        }
 2336        let path = ProjectPath::from_file(file, cx);
 2337        let worktree_id = file.worktree_id(cx);
 2338        let language = buffer.language().cloned();
 2339
 2340        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2341            for (server_id, diagnostics) in
 2342                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2343            {
 2344                self.update_buffer_diagnostics(
 2345                    buffer_handle,
 2346                    server_id,
 2347                    None,
 2348                    None,
 2349                    None,
 2350                    Vec::new(),
 2351                    diagnostics,
 2352                    cx,
 2353                )
 2354                .log_err();
 2355            }
 2356        }
 2357        let Some(language) = language else {
 2358            return;
 2359        };
 2360        let Some(snapshot) = self
 2361            .worktree_store
 2362            .read(cx)
 2363            .worktree_for_id(worktree_id, cx)
 2364            .map(|worktree| worktree.read(cx).snapshot())
 2365        else {
 2366            return;
 2367        };
 2368        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2369
 2370        for server_id in
 2371            self.lsp_tree
 2372                .get(path, language.name(), language.manifest(), &delegate, cx)
 2373        {
 2374            let server = self
 2375                .language_servers
 2376                .get(&server_id)
 2377                .and_then(|server_state| {
 2378                    if let LanguageServerState::Running { server, .. } = server_state {
 2379                        Some(server.clone())
 2380                    } else {
 2381                        None
 2382                    }
 2383                });
 2384            let server = match server {
 2385                Some(server) => server,
 2386                None => continue,
 2387            };
 2388
 2389            buffer_handle.update(cx, |buffer, cx| {
 2390                buffer.set_completion_triggers(
 2391                    server.server_id(),
 2392                    server
 2393                        .capabilities()
 2394                        .completion_provider
 2395                        .as_ref()
 2396                        .and_then(|provider| {
 2397                            provider
 2398                                .trigger_characters
 2399                                .as_ref()
 2400                                .map(|characters| characters.iter().cloned().collect())
 2401                        })
 2402                        .unwrap_or_default(),
 2403                    cx,
 2404                );
 2405            });
 2406        }
 2407    }
 2408
 2409    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2410        buffer.update(cx, |buffer, cx| {
 2411            let Some(language) = buffer.language() else {
 2412                return;
 2413            };
 2414            let path = ProjectPath {
 2415                worktree_id: old_file.worktree_id(cx),
 2416                path: old_file.path.clone(),
 2417            };
 2418            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2419                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2420                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2421            }
 2422        });
 2423    }
 2424
 2425    fn update_buffer_diagnostics(
 2426        &mut self,
 2427        buffer: &Entity<Buffer>,
 2428        server_id: LanguageServerId,
 2429        registration_id: Option<Option<SharedString>>,
 2430        result_id: Option<SharedString>,
 2431        version: Option<i32>,
 2432        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2433        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2434        cx: &mut Context<LspStore>,
 2435    ) -> Result<()> {
 2436        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2437            Ordering::Equal
 2438                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2439                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2440                .then_with(|| a.severity.cmp(&b.severity))
 2441                .then_with(|| a.message.cmp(&b.message))
 2442        }
 2443
 2444        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2445        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2446        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2447
 2448        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2449            Ordering::Equal
 2450                .then_with(|| a.range.start.cmp(&b.range.start))
 2451                .then_with(|| b.range.end.cmp(&a.range.end))
 2452                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2453        });
 2454
 2455        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2456
 2457        let edits_since_save = std::cell::LazyCell::new(|| {
 2458            let saved_version = buffer.read(cx).saved_version();
 2459            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2460        });
 2461
 2462        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2463
 2464        for (new_diagnostic, entry) in diagnostics {
 2465            let start;
 2466            let end;
 2467            if new_diagnostic && entry.diagnostic.is_disk_based {
 2468                // Some diagnostics are based on files on disk instead of buffers'
 2469                // current contents. Adjust these diagnostics' ranges to reflect
 2470                // any unsaved edits.
 2471                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2472                // and were properly adjusted on reuse.
 2473                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2474                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2475            } else {
 2476                start = entry.range.start;
 2477                end = entry.range.end;
 2478            }
 2479
 2480            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2481                ..snapshot.clip_point_utf16(end, Bias::Right);
 2482
 2483            // Expand empty ranges by one codepoint
 2484            if range.start == range.end {
 2485                // This will be go to the next boundary when being clipped
 2486                range.end.column += 1;
 2487                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2488                if range.start == range.end && range.end.column > 0 {
 2489                    range.start.column -= 1;
 2490                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2491                }
 2492            }
 2493
 2494            sanitized_diagnostics.push(DiagnosticEntry {
 2495                range,
 2496                diagnostic: entry.diagnostic,
 2497            });
 2498        }
 2499        drop(edits_since_save);
 2500
 2501        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2502        buffer.update(cx, |buffer, cx| {
 2503            if let Some(registration_id) = registration_id {
 2504                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2505                    self.buffer_pull_diagnostics_result_ids
 2506                        .entry(server_id)
 2507                        .or_default()
 2508                        .entry(registration_id)
 2509                        .or_default()
 2510                        .insert(abs_path, result_id);
 2511                }
 2512            }
 2513
 2514            buffer.update_diagnostics(server_id, set, cx)
 2515        });
 2516
 2517        Ok(())
 2518    }
 2519
 2520    fn register_language_server_for_invisible_worktree(
 2521        &mut self,
 2522        worktree: &Entity<Worktree>,
 2523        language_server_id: LanguageServerId,
 2524        cx: &mut App,
 2525    ) {
 2526        let worktree = worktree.read(cx);
 2527        let worktree_id = worktree.id();
 2528        debug_assert!(!worktree.is_visible());
 2529        let Some(mut origin_seed) = self
 2530            .language_server_ids
 2531            .iter()
 2532            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2533        else {
 2534            return;
 2535        };
 2536        origin_seed.worktree_id = worktree_id;
 2537        self.language_server_ids
 2538            .entry(origin_seed)
 2539            .or_insert_with(|| UnifiedLanguageServer {
 2540                id: language_server_id,
 2541                project_roots: Default::default(),
 2542            });
 2543    }
 2544
 2545    fn register_buffer_with_language_servers(
 2546        &mut self,
 2547        buffer_handle: &Entity<Buffer>,
 2548        only_register_servers: HashSet<LanguageServerSelector>,
 2549        cx: &mut Context<LspStore>,
 2550    ) {
 2551        let buffer = buffer_handle.read(cx);
 2552        let buffer_id = buffer.remote_id();
 2553
 2554        let Some(file) = File::from_dyn(buffer.file()) else {
 2555            return;
 2556        };
 2557        if !file.is_local() {
 2558            return;
 2559        }
 2560
 2561        let abs_path = file.abs_path(cx);
 2562        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2563            return;
 2564        };
 2565        let initial_snapshot = buffer.text_snapshot();
 2566        let worktree_id = file.worktree_id(cx);
 2567
 2568        let Some(language) = buffer.language().cloned() else {
 2569            return;
 2570        };
 2571        let path: Arc<RelPath> = file
 2572            .path()
 2573            .parent()
 2574            .map(Arc::from)
 2575            .unwrap_or_else(|| file.path().clone());
 2576        let Some(worktree) = self
 2577            .worktree_store
 2578            .read(cx)
 2579            .worktree_for_id(worktree_id, cx)
 2580        else {
 2581            return;
 2582        };
 2583        let language_name = language.name();
 2584        let (reused, delegate, servers) = self
 2585            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2586            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2587            .unwrap_or_else(|| {
 2588                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2589                let delegate: Arc<dyn ManifestDelegate> =
 2590                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2591
 2592                let servers = self
 2593                    .lsp_tree
 2594                    .walk(
 2595                        ProjectPath { worktree_id, path },
 2596                        language.name(),
 2597                        language.manifest(),
 2598                        &delegate,
 2599                        cx,
 2600                    )
 2601                    .collect::<Vec<_>>();
 2602                (false, lsp_delegate, servers)
 2603            });
 2604        let servers_and_adapters = servers
 2605            .into_iter()
 2606            .filter_map(|server_node| {
 2607                if reused && server_node.server_id().is_none() {
 2608                    return None;
 2609                }
 2610                if !only_register_servers.is_empty() {
 2611                    if let Some(server_id) = server_node.server_id()
 2612                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2613                    {
 2614                        return None;
 2615                    }
 2616                    if let Some(name) = server_node.name()
 2617                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2618                    {
 2619                        return None;
 2620                    }
 2621                }
 2622
 2623                let server_id = server_node.server_id_or_init(|disposition| {
 2624                    let path = &disposition.path;
 2625
 2626                    {
 2627                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2628
 2629                        let server_id = self.get_or_insert_language_server(
 2630                            &worktree,
 2631                            delegate.clone(),
 2632                            disposition,
 2633                            &language_name,
 2634                            cx,
 2635                        );
 2636
 2637                        if let Some(state) = self.language_servers.get(&server_id)
 2638                            && let Ok(uri) = uri
 2639                        {
 2640                            state.add_workspace_folder(uri);
 2641                        };
 2642                        server_id
 2643                    }
 2644                })?;
 2645                let server_state = self.language_servers.get(&server_id)?;
 2646                if let LanguageServerState::Running {
 2647                    server, adapter, ..
 2648                } = server_state
 2649                {
 2650                    Some((server.clone(), adapter.clone()))
 2651                } else {
 2652                    None
 2653                }
 2654            })
 2655            .collect::<Vec<_>>();
 2656        for (server, adapter) in servers_and_adapters {
 2657            buffer_handle.update(cx, |buffer, cx| {
 2658                buffer.set_completion_triggers(
 2659                    server.server_id(),
 2660                    server
 2661                        .capabilities()
 2662                        .completion_provider
 2663                        .as_ref()
 2664                        .and_then(|provider| {
 2665                            provider
 2666                                .trigger_characters
 2667                                .as_ref()
 2668                                .map(|characters| characters.iter().cloned().collect())
 2669                        })
 2670                        .unwrap_or_default(),
 2671                    cx,
 2672                );
 2673            });
 2674
 2675            let snapshot = LspBufferSnapshot {
 2676                version: 0,
 2677                snapshot: initial_snapshot.clone(),
 2678            };
 2679
 2680            let mut registered = false;
 2681            self.buffer_snapshots
 2682                .entry(buffer_id)
 2683                .or_default()
 2684                .entry(server.server_id())
 2685                .or_insert_with(|| {
 2686                    registered = true;
 2687                    server.register_buffer(
 2688                        uri.clone(),
 2689                        adapter.language_id(&language.name()),
 2690                        0,
 2691                        initial_snapshot.text(),
 2692                    );
 2693
 2694                    vec![snapshot]
 2695                });
 2696
 2697            self.buffers_opened_in_servers
 2698                .entry(buffer_id)
 2699                .or_default()
 2700                .insert(server.server_id());
 2701            if registered {
 2702                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2703                    language_server_id: server.server_id(),
 2704                    name: None,
 2705                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2706                        proto::RegisteredForBuffer {
 2707                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2708                            buffer_id: buffer_id.to_proto(),
 2709                        },
 2710                    ),
 2711                });
 2712            }
 2713        }
 2714    }
 2715
 2716    fn reuse_existing_language_server<'lang_name>(
 2717        &self,
 2718        server_tree: &LanguageServerTree,
 2719        worktree: &Entity<Worktree>,
 2720        language_name: &'lang_name LanguageName,
 2721        cx: &mut App,
 2722    ) -> Option<(
 2723        Arc<LocalLspAdapterDelegate>,
 2724        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2725    )> {
 2726        if worktree.read(cx).is_visible() {
 2727            return None;
 2728        }
 2729
 2730        let worktree_store = self.worktree_store.read(cx);
 2731        let servers = server_tree
 2732            .instances
 2733            .iter()
 2734            .filter(|(worktree_id, _)| {
 2735                worktree_store
 2736                    .worktree_for_id(**worktree_id, cx)
 2737                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2738            })
 2739            .flat_map(|(worktree_id, servers)| {
 2740                servers
 2741                    .roots
 2742                    .iter()
 2743                    .flat_map(|(_, language_servers)| language_servers)
 2744                    .map(move |(_, (server_node, server_languages))| {
 2745                        (worktree_id, server_node, server_languages)
 2746                    })
 2747                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2748                    .map(|(worktree_id, server_node, _)| {
 2749                        (
 2750                            *worktree_id,
 2751                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2752                        )
 2753                    })
 2754            })
 2755            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2756                acc.entry(worktree_id)
 2757                    .or_insert_with(Vec::new)
 2758                    .push(server_node);
 2759                acc
 2760            })
 2761            .into_values()
 2762            .max_by_key(|servers| servers.len())?;
 2763
 2764        let worktree_id = worktree.read(cx).id();
 2765        let apply = move |tree: &mut LanguageServerTree| {
 2766            for server_node in &servers {
 2767                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2768            }
 2769            servers
 2770        };
 2771
 2772        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2773        Some((delegate, apply))
 2774    }
 2775
 2776    pub(crate) fn unregister_old_buffer_from_language_servers(
 2777        &mut self,
 2778        buffer: &Entity<Buffer>,
 2779        old_file: &File,
 2780        cx: &mut App,
 2781    ) {
 2782        let old_path = match old_file.as_local() {
 2783            Some(local) => local.abs_path(cx),
 2784            None => return,
 2785        };
 2786
 2787        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2788            debug_panic!("{old_path:?} is not parseable as an URI");
 2789            return;
 2790        };
 2791        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2792    }
 2793
 2794    pub(crate) fn unregister_buffer_from_language_servers(
 2795        &mut self,
 2796        buffer: &Entity<Buffer>,
 2797        file_url: &lsp::Uri,
 2798        cx: &mut App,
 2799    ) {
 2800        buffer.update(cx, |buffer, cx| {
 2801            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2802
 2803            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2804                if snapshots
 2805                    .as_mut()
 2806                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2807                {
 2808                    language_server.unregister_buffer(file_url.clone());
 2809                }
 2810            }
 2811        });
 2812    }
 2813
 2814    fn buffer_snapshot_for_lsp_version(
 2815        &mut self,
 2816        buffer: &Entity<Buffer>,
 2817        server_id: LanguageServerId,
 2818        version: Option<i32>,
 2819        cx: &App,
 2820    ) -> Result<TextBufferSnapshot> {
 2821        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2822
 2823        if let Some(version) = version {
 2824            let buffer_id = buffer.read(cx).remote_id();
 2825            let snapshots = if let Some(snapshots) = self
 2826                .buffer_snapshots
 2827                .get_mut(&buffer_id)
 2828                .and_then(|m| m.get_mut(&server_id))
 2829            {
 2830                snapshots
 2831            } else if version == 0 {
 2832                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2833                // We detect this case and treat it as if the version was `None`.
 2834                return Ok(buffer.read(cx).text_snapshot());
 2835            } else {
 2836                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2837            };
 2838
 2839            let found_snapshot = snapshots
 2840                    .binary_search_by_key(&version, |e| e.version)
 2841                    .map(|ix| snapshots[ix].snapshot.clone())
 2842                    .map_err(|_| {
 2843                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2844                    })?;
 2845
 2846            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2847            Ok(found_snapshot)
 2848        } else {
 2849            Ok((buffer.read(cx)).text_snapshot())
 2850        }
 2851    }
 2852
 2853    async fn get_server_code_actions_from_action_kinds(
 2854        lsp_store: &WeakEntity<LspStore>,
 2855        language_server_id: LanguageServerId,
 2856        code_action_kinds: Vec<lsp::CodeActionKind>,
 2857        buffer: &Entity<Buffer>,
 2858        cx: &mut AsyncApp,
 2859    ) -> Result<Vec<CodeAction>> {
 2860        let actions = lsp_store
 2861            .update(cx, move |this, cx| {
 2862                let request = GetCodeActions {
 2863                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 2864                    kinds: Some(code_action_kinds),
 2865                };
 2866                let server = LanguageServerToQuery::Other(language_server_id);
 2867                this.request_lsp(buffer.clone(), server, request, cx)
 2868            })?
 2869            .await?;
 2870        Ok(actions)
 2871    }
 2872
 2873    pub async fn execute_code_actions_on_server(
 2874        lsp_store: &WeakEntity<LspStore>,
 2875        language_server: &Arc<LanguageServer>,
 2876
 2877        actions: Vec<CodeAction>,
 2878        push_to_history: bool,
 2879        project_transaction: &mut ProjectTransaction,
 2880        cx: &mut AsyncApp,
 2881    ) -> anyhow::Result<()> {
 2882        for mut action in actions {
 2883            Self::try_resolve_code_action(language_server, &mut action)
 2884                .await
 2885                .context("resolving a formatting code action")?;
 2886
 2887            if let Some(edit) = action.lsp_action.edit() {
 2888                if edit.changes.is_none() && edit.document_changes.is_none() {
 2889                    continue;
 2890                }
 2891
 2892                let new = Self::deserialize_workspace_edit(
 2893                    lsp_store.upgrade().context("project dropped")?,
 2894                    edit.clone(),
 2895                    push_to_history,
 2896                    language_server.clone(),
 2897                    cx,
 2898                )
 2899                .await?;
 2900                project_transaction.0.extend(new.0);
 2901            }
 2902
 2903            if let Some(command) = action.lsp_action.command() {
 2904                let server_capabilities = language_server.capabilities();
 2905                let available_commands = server_capabilities
 2906                    .execute_command_provider
 2907                    .as_ref()
 2908                    .map(|options| options.commands.as_slice())
 2909                    .unwrap_or_default();
 2910                if available_commands.contains(&command.command) {
 2911                    lsp_store.update(cx, |lsp_store, _| {
 2912                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2913                            mode.last_workspace_edits_by_language_server
 2914                                .remove(&language_server.server_id());
 2915                        }
 2916                    })?;
 2917
 2918                    language_server
 2919                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2920                            command: command.command.clone(),
 2921                            arguments: command.arguments.clone().unwrap_or_default(),
 2922                            ..Default::default()
 2923                        })
 2924                        .await
 2925                        .into_response()
 2926                        .context("execute command")?;
 2927
 2928                    lsp_store.update(cx, |this, _| {
 2929                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2930                            project_transaction.0.extend(
 2931                                mode.last_workspace_edits_by_language_server
 2932                                    .remove(&language_server.server_id())
 2933                                    .unwrap_or_default()
 2934                                    .0,
 2935                            )
 2936                        }
 2937                    })?;
 2938                } else {
 2939                    log::warn!(
 2940                        "Cannot execute a command {} not listed in the language server capabilities",
 2941                        command.command
 2942                    )
 2943                }
 2944            }
 2945        }
 2946        Ok(())
 2947    }
 2948
 2949    pub async fn deserialize_text_edits(
 2950        this: Entity<LspStore>,
 2951        buffer_to_edit: Entity<Buffer>,
 2952        edits: Vec<lsp::TextEdit>,
 2953        push_to_history: bool,
 2954        _: Arc<CachedLspAdapter>,
 2955        language_server: Arc<LanguageServer>,
 2956        cx: &mut AsyncApp,
 2957    ) -> Result<Option<Transaction>> {
 2958        let edits = this
 2959            .update(cx, |this, cx| {
 2960                this.as_local_mut().unwrap().edits_from_lsp(
 2961                    &buffer_to_edit,
 2962                    edits,
 2963                    language_server.server_id(),
 2964                    None,
 2965                    cx,
 2966                )
 2967            })?
 2968            .await?;
 2969
 2970        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2971            buffer.finalize_last_transaction();
 2972            buffer.start_transaction();
 2973            for (range, text) in edits {
 2974                buffer.edit([(range, text)], None, cx);
 2975            }
 2976
 2977            if buffer.end_transaction(cx).is_some() {
 2978                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2979                if !push_to_history {
 2980                    buffer.forget_transaction(transaction.id);
 2981                }
 2982                Some(transaction)
 2983            } else {
 2984                None
 2985            }
 2986        })?;
 2987
 2988        Ok(transaction)
 2989    }
 2990
 2991    #[allow(clippy::type_complexity)]
 2992    pub(crate) fn edits_from_lsp(
 2993        &mut self,
 2994        buffer: &Entity<Buffer>,
 2995        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2996        server_id: LanguageServerId,
 2997        version: Option<i32>,
 2998        cx: &mut Context<LspStore>,
 2999    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3000        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3001        cx.background_spawn(async move {
 3002            let snapshot = snapshot?;
 3003            let mut lsp_edits = lsp_edits
 3004                .into_iter()
 3005                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3006                .collect::<Vec<_>>();
 3007
 3008            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 3009
 3010            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3011            let mut edits = Vec::new();
 3012            while let Some((range, mut new_text)) = lsp_edits.next() {
 3013                // Clip invalid ranges provided by the language server.
 3014                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3015                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3016
 3017                // Combine any LSP edits that are adjacent.
 3018                //
 3019                // Also, combine LSP edits that are separated from each other by only
 3020                // a newline. This is important because for some code actions,
 3021                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3022                // are separated by unchanged newline characters.
 3023                //
 3024                // In order for the diffing logic below to work properly, any edits that
 3025                // cancel each other out must be combined into one.
 3026                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3027                    if next_range.start.0 > range.end {
 3028                        if next_range.start.0.row > range.end.row + 1
 3029                            || next_range.start.0.column > 0
 3030                            || snapshot.clip_point_utf16(
 3031                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3032                                Bias::Left,
 3033                            ) > range.end
 3034                        {
 3035                            break;
 3036                        }
 3037                        new_text.push('\n');
 3038                    }
 3039                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3040                    new_text.push_str(next_text);
 3041                    lsp_edits.next();
 3042                }
 3043
 3044                // For multiline edits, perform a diff of the old and new text so that
 3045                // we can identify the changes more precisely, preserving the locations
 3046                // of any anchors positioned in the unchanged regions.
 3047                if range.end.row > range.start.row {
 3048                    let offset = range.start.to_offset(&snapshot);
 3049                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3050                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3051                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3052                        (
 3053                            snapshot.anchor_after(offset + range.start)
 3054                                ..snapshot.anchor_before(offset + range.end),
 3055                            replacement,
 3056                        )
 3057                    }));
 3058                } else if range.end == range.start {
 3059                    let anchor = snapshot.anchor_after(range.start);
 3060                    edits.push((anchor..anchor, new_text.into()));
 3061                } else {
 3062                    let edit_start = snapshot.anchor_after(range.start);
 3063                    let edit_end = snapshot.anchor_before(range.end);
 3064                    edits.push((edit_start..edit_end, new_text.into()));
 3065                }
 3066            }
 3067
 3068            Ok(edits)
 3069        })
 3070    }
 3071
 3072    pub(crate) async fn deserialize_workspace_edit(
 3073        this: Entity<LspStore>,
 3074        edit: lsp::WorkspaceEdit,
 3075        push_to_history: bool,
 3076        language_server: Arc<LanguageServer>,
 3077        cx: &mut AsyncApp,
 3078    ) -> Result<ProjectTransaction> {
 3079        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 3080
 3081        let mut operations = Vec::new();
 3082        if let Some(document_changes) = edit.document_changes {
 3083            match document_changes {
 3084                lsp::DocumentChanges::Edits(edits) => {
 3085                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3086                }
 3087                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3088            }
 3089        } else if let Some(changes) = edit.changes {
 3090            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3091                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3092                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3093                        uri,
 3094                        version: None,
 3095                    },
 3096                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3097                })
 3098            }));
 3099        }
 3100
 3101        let mut project_transaction = ProjectTransaction::default();
 3102        for operation in operations {
 3103            match operation {
 3104                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3105                    let abs_path = op
 3106                        .uri
 3107                        .to_file_path()
 3108                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3109
 3110                    if let Some(parent_path) = abs_path.parent() {
 3111                        fs.create_dir(parent_path).await?;
 3112                    }
 3113                    if abs_path.ends_with("/") {
 3114                        fs.create_dir(&abs_path).await?;
 3115                    } else {
 3116                        fs.create_file(
 3117                            &abs_path,
 3118                            op.options
 3119                                .map(|options| fs::CreateOptions {
 3120                                    overwrite: options.overwrite.unwrap_or(false),
 3121                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3122                                })
 3123                                .unwrap_or_default(),
 3124                        )
 3125                        .await?;
 3126                    }
 3127                }
 3128
 3129                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3130                    let source_abs_path = op
 3131                        .old_uri
 3132                        .to_file_path()
 3133                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3134                    let target_abs_path = op
 3135                        .new_uri
 3136                        .to_file_path()
 3137                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3138
 3139                    let options = fs::RenameOptions {
 3140                        overwrite: op
 3141                            .options
 3142                            .as_ref()
 3143                            .and_then(|options| options.overwrite)
 3144                            .unwrap_or(false),
 3145                        ignore_if_exists: op
 3146                            .options
 3147                            .as_ref()
 3148                            .and_then(|options| options.ignore_if_exists)
 3149                            .unwrap_or(false),
 3150                        create_parents: true,
 3151                    };
 3152
 3153                    fs.rename(&source_abs_path, &target_abs_path, options)
 3154                        .await?;
 3155                }
 3156
 3157                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3158                    let abs_path = op
 3159                        .uri
 3160                        .to_file_path()
 3161                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3162                    let options = op
 3163                        .options
 3164                        .map(|options| fs::RemoveOptions {
 3165                            recursive: options.recursive.unwrap_or(false),
 3166                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3167                        })
 3168                        .unwrap_or_default();
 3169                    if abs_path.ends_with("/") {
 3170                        fs.remove_dir(&abs_path, options).await?;
 3171                    } else {
 3172                        fs.remove_file(&abs_path, options).await?;
 3173                    }
 3174                }
 3175
 3176                lsp::DocumentChangeOperation::Edit(op) => {
 3177                    let buffer_to_edit = this
 3178                        .update(cx, |this, cx| {
 3179                            this.open_local_buffer_via_lsp(
 3180                                op.text_document.uri.clone(),
 3181                                language_server.server_id(),
 3182                                cx,
 3183                            )
 3184                        })?
 3185                        .await?;
 3186
 3187                    let edits = this
 3188                        .update(cx, |this, cx| {
 3189                            let path = buffer_to_edit.read(cx).project_path(cx);
 3190                            let active_entry = this.active_entry;
 3191                            let is_active_entry = path.is_some_and(|project_path| {
 3192                                this.worktree_store
 3193                                    .read(cx)
 3194                                    .entry_for_path(&project_path, cx)
 3195                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3196                            });
 3197                            let local = this.as_local_mut().unwrap();
 3198
 3199                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3200                            for edit in op.edits {
 3201                                match edit {
 3202                                    Edit::Plain(edit) => {
 3203                                        if !edits.contains(&edit) {
 3204                                            edits.push(edit)
 3205                                        }
 3206                                    }
 3207                                    Edit::Annotated(edit) => {
 3208                                        if !edits.contains(&edit.text_edit) {
 3209                                            edits.push(edit.text_edit)
 3210                                        }
 3211                                    }
 3212                                    Edit::Snippet(edit) => {
 3213                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3214                                        else {
 3215                                            continue;
 3216                                        };
 3217
 3218                                        if is_active_entry {
 3219                                            snippet_edits.push((edit.range, snippet));
 3220                                        } else {
 3221                                            // Since this buffer is not focused, apply a normal edit.
 3222                                            let new_edit = TextEdit {
 3223                                                range: edit.range,
 3224                                                new_text: snippet.text,
 3225                                            };
 3226                                            if !edits.contains(&new_edit) {
 3227                                                edits.push(new_edit);
 3228                                            }
 3229                                        }
 3230                                    }
 3231                                }
 3232                            }
 3233                            if !snippet_edits.is_empty() {
 3234                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3235                                let version = if let Some(buffer_version) = op.text_document.version
 3236                                {
 3237                                    local
 3238                                        .buffer_snapshot_for_lsp_version(
 3239                                            &buffer_to_edit,
 3240                                            language_server.server_id(),
 3241                                            Some(buffer_version),
 3242                                            cx,
 3243                                        )
 3244                                        .ok()
 3245                                        .map(|snapshot| snapshot.version)
 3246                                } else {
 3247                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3248                                };
 3249
 3250                                let most_recent_edit =
 3251                                    version.and_then(|version| version.most_recent());
 3252                                // Check if the edit that triggered that edit has been made by this participant.
 3253
 3254                                if let Some(most_recent_edit) = most_recent_edit {
 3255                                    cx.emit(LspStoreEvent::SnippetEdit {
 3256                                        buffer_id,
 3257                                        edits: snippet_edits,
 3258                                        most_recent_edit,
 3259                                    });
 3260                                }
 3261                            }
 3262
 3263                            local.edits_from_lsp(
 3264                                &buffer_to_edit,
 3265                                edits,
 3266                                language_server.server_id(),
 3267                                op.text_document.version,
 3268                                cx,
 3269                            )
 3270                        })?
 3271                        .await?;
 3272
 3273                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3274                        buffer.finalize_last_transaction();
 3275                        buffer.start_transaction();
 3276                        for (range, text) in edits {
 3277                            buffer.edit([(range, text)], None, cx);
 3278                        }
 3279
 3280                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3281                            if push_to_history {
 3282                                buffer.finalize_last_transaction();
 3283                                buffer.get_transaction(transaction_id).cloned()
 3284                            } else {
 3285                                buffer.forget_transaction(transaction_id)
 3286                            }
 3287                        })
 3288                    })?;
 3289                    if let Some(transaction) = transaction {
 3290                        project_transaction.0.insert(buffer_to_edit, transaction);
 3291                    }
 3292                }
 3293            }
 3294        }
 3295
 3296        Ok(project_transaction)
 3297    }
 3298
 3299    async fn on_lsp_workspace_edit(
 3300        this: WeakEntity<LspStore>,
 3301        params: lsp::ApplyWorkspaceEditParams,
 3302        server_id: LanguageServerId,
 3303        cx: &mut AsyncApp,
 3304    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3305        let this = this.upgrade().context("project project closed")?;
 3306        let language_server = this
 3307            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3308            .context("language server not found")?;
 3309        let transaction = Self::deserialize_workspace_edit(
 3310            this.clone(),
 3311            params.edit,
 3312            true,
 3313            language_server.clone(),
 3314            cx,
 3315        )
 3316        .await
 3317        .log_err();
 3318        this.update(cx, |this, cx| {
 3319            if let Some(transaction) = transaction {
 3320                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3321
 3322                this.as_local_mut()
 3323                    .unwrap()
 3324                    .last_workspace_edits_by_language_server
 3325                    .insert(server_id, transaction);
 3326            }
 3327        })?;
 3328        Ok(lsp::ApplyWorkspaceEditResponse {
 3329            applied: true,
 3330            failed_change: None,
 3331            failure_reason: None,
 3332        })
 3333    }
 3334
 3335    fn remove_worktree(
 3336        &mut self,
 3337        id_to_remove: WorktreeId,
 3338        cx: &mut Context<LspStore>,
 3339    ) -> Vec<LanguageServerId> {
 3340        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3341        self.diagnostics.remove(&id_to_remove);
 3342        self.prettier_store.update(cx, |prettier_store, cx| {
 3343            prettier_store.remove_worktree(id_to_remove, cx);
 3344        });
 3345
 3346        let mut servers_to_remove = BTreeSet::default();
 3347        let mut servers_to_preserve = HashSet::default();
 3348        for (seed, state) in &self.language_server_ids {
 3349            if seed.worktree_id == id_to_remove {
 3350                servers_to_remove.insert(state.id);
 3351            } else {
 3352                servers_to_preserve.insert(state.id);
 3353            }
 3354        }
 3355        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3356        self.language_server_ids
 3357            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3358        for server_id_to_remove in &servers_to_remove {
 3359            self.language_server_watched_paths
 3360                .remove(server_id_to_remove);
 3361            self.language_server_paths_watched_for_rename
 3362                .remove(server_id_to_remove);
 3363            self.last_workspace_edits_by_language_server
 3364                .remove(server_id_to_remove);
 3365            self.language_servers.remove(server_id_to_remove);
 3366            self.buffer_pull_diagnostics_result_ids
 3367                .remove(server_id_to_remove);
 3368            self.workspace_pull_diagnostics_result_ids
 3369                .remove(server_id_to_remove);
 3370            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3371                buffer_servers.remove(server_id_to_remove);
 3372            }
 3373            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3374        }
 3375        servers_to_remove.into_iter().collect()
 3376    }
 3377
 3378    fn rebuild_watched_paths_inner<'a>(
 3379        &'a self,
 3380        language_server_id: LanguageServerId,
 3381        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3382        cx: &mut Context<LspStore>,
 3383    ) -> LanguageServerWatchedPathsBuilder {
 3384        let worktrees = self
 3385            .worktree_store
 3386            .read(cx)
 3387            .worktrees()
 3388            .filter_map(|worktree| {
 3389                self.language_servers_for_worktree(worktree.read(cx).id())
 3390                    .find(|server| server.server_id() == language_server_id)
 3391                    .map(|_| worktree)
 3392            })
 3393            .collect::<Vec<_>>();
 3394
 3395        let mut worktree_globs = HashMap::default();
 3396        let mut abs_globs = HashMap::default();
 3397        log::trace!(
 3398            "Processing new watcher paths for language server with id {}",
 3399            language_server_id
 3400        );
 3401
 3402        for watcher in watchers {
 3403            if let Some((worktree, literal_prefix, pattern)) =
 3404                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3405            {
 3406                worktree.update(cx, |worktree, _| {
 3407                    if let Some((tree, glob)) =
 3408                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3409                    {
 3410                        tree.add_path_prefix_to_scan(literal_prefix);
 3411                        worktree_globs
 3412                            .entry(tree.id())
 3413                            .or_insert_with(GlobSetBuilder::new)
 3414                            .add(glob);
 3415                    }
 3416                });
 3417            } else {
 3418                let (path, pattern) = match &watcher.glob_pattern {
 3419                    lsp::GlobPattern::String(s) => {
 3420                        let watcher_path = SanitizedPath::new(s);
 3421                        let path = glob_literal_prefix(watcher_path.as_path());
 3422                        let pattern = watcher_path
 3423                            .as_path()
 3424                            .strip_prefix(&path)
 3425                            .map(|p| p.to_string_lossy().into_owned())
 3426                            .unwrap_or_else(|e| {
 3427                                debug_panic!(
 3428                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3429                                    s,
 3430                                    path.display(),
 3431                                    e
 3432                                );
 3433                                watcher_path.as_path().to_string_lossy().into_owned()
 3434                            });
 3435                        (path, pattern)
 3436                    }
 3437                    lsp::GlobPattern::Relative(rp) => {
 3438                        let Ok(mut base_uri) = match &rp.base_uri {
 3439                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3440                            lsp::OneOf::Right(base_uri) => base_uri,
 3441                        }
 3442                        .to_file_path() else {
 3443                            continue;
 3444                        };
 3445
 3446                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3447                        let pattern = Path::new(&rp.pattern)
 3448                            .strip_prefix(&path)
 3449                            .map(|p| p.to_string_lossy().into_owned())
 3450                            .unwrap_or_else(|e| {
 3451                                debug_panic!(
 3452                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3453                                    rp.pattern,
 3454                                    path.display(),
 3455                                    e
 3456                                );
 3457                                rp.pattern.clone()
 3458                            });
 3459                        base_uri.push(path);
 3460                        (base_uri, pattern)
 3461                    }
 3462                };
 3463
 3464                if let Some(glob) = Glob::new(&pattern).log_err() {
 3465                    if !path
 3466                        .components()
 3467                        .any(|c| matches!(c, path::Component::Normal(_)))
 3468                    {
 3469                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3470                        // rather than adding a new watcher for `/`.
 3471                        for worktree in &worktrees {
 3472                            worktree_globs
 3473                                .entry(worktree.read(cx).id())
 3474                                .or_insert_with(GlobSetBuilder::new)
 3475                                .add(glob.clone());
 3476                        }
 3477                    } else {
 3478                        abs_globs
 3479                            .entry(path.into())
 3480                            .or_insert_with(GlobSetBuilder::new)
 3481                            .add(glob);
 3482                    }
 3483                }
 3484            }
 3485        }
 3486
 3487        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3488        for (worktree_id, builder) in worktree_globs {
 3489            if let Ok(globset) = builder.build() {
 3490                watch_builder.watch_worktree(worktree_id, globset);
 3491            }
 3492        }
 3493        for (abs_path, builder) in abs_globs {
 3494            if let Ok(globset) = builder.build() {
 3495                watch_builder.watch_abs_path(abs_path, globset);
 3496            }
 3497        }
 3498        watch_builder
 3499    }
 3500
 3501    fn worktree_and_path_for_file_watcher(
 3502        worktrees: &[Entity<Worktree>],
 3503        watcher: &FileSystemWatcher,
 3504        cx: &App,
 3505    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3506        worktrees.iter().find_map(|worktree| {
 3507            let tree = worktree.read(cx);
 3508            let worktree_root_path = tree.abs_path();
 3509            let path_style = tree.path_style();
 3510            match &watcher.glob_pattern {
 3511                lsp::GlobPattern::String(s) => {
 3512                    let watcher_path = SanitizedPath::new(s);
 3513                    let relative = watcher_path
 3514                        .as_path()
 3515                        .strip_prefix(&worktree_root_path)
 3516                        .ok()?;
 3517                    let literal_prefix = glob_literal_prefix(relative);
 3518                    Some((
 3519                        worktree.clone(),
 3520                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3521                        relative.to_string_lossy().into_owned(),
 3522                    ))
 3523                }
 3524                lsp::GlobPattern::Relative(rp) => {
 3525                    let base_uri = match &rp.base_uri {
 3526                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3527                        lsp::OneOf::Right(base_uri) => base_uri,
 3528                    }
 3529                    .to_file_path()
 3530                    .ok()?;
 3531                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3532                    let mut literal_prefix = relative.to_owned();
 3533                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3534                    Some((
 3535                        worktree.clone(),
 3536                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3537                        rp.pattern.clone(),
 3538                    ))
 3539                }
 3540            }
 3541        })
 3542    }
 3543
 3544    fn rebuild_watched_paths(
 3545        &mut self,
 3546        language_server_id: LanguageServerId,
 3547        cx: &mut Context<LspStore>,
 3548    ) {
 3549        let Some(registrations) = self
 3550            .language_server_dynamic_registrations
 3551            .get(&language_server_id)
 3552        else {
 3553            return;
 3554        };
 3555
 3556        let watch_builder = self.rebuild_watched_paths_inner(
 3557            language_server_id,
 3558            registrations.did_change_watched_files.values().flatten(),
 3559            cx,
 3560        );
 3561        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3562        self.language_server_watched_paths
 3563            .insert(language_server_id, watcher);
 3564
 3565        cx.notify();
 3566    }
 3567
 3568    fn on_lsp_did_change_watched_files(
 3569        &mut self,
 3570        language_server_id: LanguageServerId,
 3571        registration_id: &str,
 3572        params: DidChangeWatchedFilesRegistrationOptions,
 3573        cx: &mut Context<LspStore>,
 3574    ) {
 3575        let registrations = self
 3576            .language_server_dynamic_registrations
 3577            .entry(language_server_id)
 3578            .or_default();
 3579
 3580        registrations
 3581            .did_change_watched_files
 3582            .insert(registration_id.to_string(), params.watchers);
 3583
 3584        self.rebuild_watched_paths(language_server_id, cx);
 3585    }
 3586
 3587    fn on_lsp_unregister_did_change_watched_files(
 3588        &mut self,
 3589        language_server_id: LanguageServerId,
 3590        registration_id: &str,
 3591        cx: &mut Context<LspStore>,
 3592    ) {
 3593        let registrations = self
 3594            .language_server_dynamic_registrations
 3595            .entry(language_server_id)
 3596            .or_default();
 3597
 3598        if registrations
 3599            .did_change_watched_files
 3600            .remove(registration_id)
 3601            .is_some()
 3602        {
 3603            log::info!(
 3604                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3605                language_server_id,
 3606                registration_id
 3607            );
 3608        } else {
 3609            log::warn!(
 3610                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3611                language_server_id,
 3612                registration_id
 3613            );
 3614        }
 3615
 3616        self.rebuild_watched_paths(language_server_id, cx);
 3617    }
 3618
 3619    async fn initialization_options_for_adapter(
 3620        adapter: Arc<dyn LspAdapter>,
 3621        delegate: &Arc<dyn LspAdapterDelegate>,
 3622    ) -> Result<Option<serde_json::Value>> {
 3623        let Some(mut initialization_config) =
 3624            adapter.clone().initialization_options(delegate).await?
 3625        else {
 3626            return Ok(None);
 3627        };
 3628
 3629        for other_adapter in delegate.registered_lsp_adapters() {
 3630            if other_adapter.name() == adapter.name() {
 3631                continue;
 3632            }
 3633            if let Ok(Some(target_config)) = other_adapter
 3634                .clone()
 3635                .additional_initialization_options(adapter.name(), delegate)
 3636                .await
 3637            {
 3638                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3639            }
 3640        }
 3641
 3642        Ok(Some(initialization_config))
 3643    }
 3644
 3645    async fn workspace_configuration_for_adapter(
 3646        adapter: Arc<dyn LspAdapter>,
 3647        delegate: &Arc<dyn LspAdapterDelegate>,
 3648        toolchain: Option<Toolchain>,
 3649        requested_uri: Option<Uri>,
 3650        cx: &mut AsyncApp,
 3651    ) -> Result<serde_json::Value> {
 3652        let mut workspace_config = adapter
 3653            .clone()
 3654            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3655            .await?;
 3656
 3657        for other_adapter in delegate.registered_lsp_adapters() {
 3658            if other_adapter.name() == adapter.name() {
 3659                continue;
 3660            }
 3661            if let Ok(Some(target_config)) = other_adapter
 3662                .clone()
 3663                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3664                .await
 3665            {
 3666                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3667            }
 3668        }
 3669
 3670        Ok(workspace_config)
 3671    }
 3672
 3673    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3674        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3675            Some(server.clone())
 3676        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3677            Some(Arc::clone(server))
 3678        } else {
 3679            None
 3680        }
 3681    }
 3682}
 3683
 3684fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3685    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3686        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3687            language_server_id: server.server_id(),
 3688            name: Some(server.name()),
 3689            message: proto::update_language_server::Variant::MetadataUpdated(
 3690                proto::ServerMetadataUpdated {
 3691                    capabilities: Some(capabilities),
 3692                    binary: Some(proto::LanguageServerBinaryInfo {
 3693                        path: server.binary().path.to_string_lossy().into_owned(),
 3694                        arguments: server
 3695                            .binary()
 3696                            .arguments
 3697                            .iter()
 3698                            .map(|arg| arg.to_string_lossy().into_owned())
 3699                            .collect(),
 3700                    }),
 3701                    configuration: serde_json::to_string(server.configuration()).ok(),
 3702                    workspace_folders: server
 3703                        .workspace_folders()
 3704                        .iter()
 3705                        .map(|uri| uri.to_string())
 3706                        .collect(),
 3707                },
 3708            ),
 3709        });
 3710    }
 3711}
 3712
 3713#[derive(Debug)]
 3714pub struct FormattableBuffer {
 3715    handle: Entity<Buffer>,
 3716    abs_path: Option<PathBuf>,
 3717    env: Option<HashMap<String, String>>,
 3718    ranges: Option<Vec<Range<Anchor>>>,
 3719}
 3720
 3721pub struct RemoteLspStore {
 3722    upstream_client: Option<AnyProtoClient>,
 3723    upstream_project_id: u64,
 3724}
 3725
 3726pub(crate) enum LspStoreMode {
 3727    Local(LocalLspStore),   // ssh host and collab host
 3728    Remote(RemoteLspStore), // collab guest
 3729}
 3730
 3731impl LspStoreMode {
 3732    fn is_local(&self) -> bool {
 3733        matches!(self, LspStoreMode::Local(_))
 3734    }
 3735}
 3736
 3737pub struct LspStore {
 3738    mode: LspStoreMode,
 3739    last_formatting_failure: Option<String>,
 3740    downstream_client: Option<(AnyProtoClient, u64)>,
 3741    nonce: u128,
 3742    buffer_store: Entity<BufferStore>,
 3743    worktree_store: Entity<WorktreeStore>,
 3744    pub languages: Arc<LanguageRegistry>,
 3745    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3746    active_entry: Option<ProjectEntryId>,
 3747    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3748    _maintain_buffer_languages: Task<()>,
 3749    diagnostic_summaries:
 3750        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3751    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3752    lsp_data: HashMap<BufferId, BufferLspData>,
 3753    next_hint_id: Arc<AtomicUsize>,
 3754}
 3755
 3756#[derive(Debug)]
 3757pub struct BufferLspData {
 3758    buffer_version: Global,
 3759    document_colors: Option<DocumentColorData>,
 3760    code_lens: Option<CodeLensData>,
 3761    inlay_hints: BufferInlayHints,
 3762    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3763    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3764}
 3765
 3766#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3767struct LspKey {
 3768    request_type: TypeId,
 3769    server_queried: Option<LanguageServerId>,
 3770}
 3771
 3772impl BufferLspData {
 3773    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3774        Self {
 3775            buffer_version: buffer.read(cx).version(),
 3776            document_colors: None,
 3777            code_lens: None,
 3778            inlay_hints: BufferInlayHints::new(buffer, cx),
 3779            lsp_requests: HashMap::default(),
 3780            chunk_lsp_requests: HashMap::default(),
 3781        }
 3782    }
 3783
 3784    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3785        if let Some(document_colors) = &mut self.document_colors {
 3786            document_colors.colors.remove(&for_server);
 3787            document_colors.cache_version += 1;
 3788        }
 3789
 3790        if let Some(code_lens) = &mut self.code_lens {
 3791            code_lens.lens.remove(&for_server);
 3792        }
 3793
 3794        self.inlay_hints.remove_server_data(for_server);
 3795    }
 3796
 3797    #[cfg(any(test, feature = "test-support"))]
 3798    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3799        &self.inlay_hints
 3800    }
 3801}
 3802
 3803#[derive(Debug, Default, Clone)]
 3804pub struct DocumentColors {
 3805    pub colors: HashSet<DocumentColor>,
 3806    pub cache_version: Option<usize>,
 3807}
 3808
 3809type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3810type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3811
 3812#[derive(Debug, Default)]
 3813struct DocumentColorData {
 3814    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3815    cache_version: usize,
 3816    colors_update: Option<(Global, DocumentColorTask)>,
 3817}
 3818
 3819#[derive(Debug, Default)]
 3820struct CodeLensData {
 3821    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3822    update: Option<(Global, CodeLensTask)>,
 3823}
 3824
 3825#[derive(Debug)]
 3826pub enum LspStoreEvent {
 3827    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3828    LanguageServerRemoved(LanguageServerId),
 3829    LanguageServerUpdate {
 3830        language_server_id: LanguageServerId,
 3831        name: Option<LanguageServerName>,
 3832        message: proto::update_language_server::Variant,
 3833    },
 3834    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3835    LanguageServerPrompt(LanguageServerPromptRequest),
 3836    LanguageDetected {
 3837        buffer: Entity<Buffer>,
 3838        new_language: Option<Arc<Language>>,
 3839    },
 3840    Notification(String),
 3841    RefreshInlayHints {
 3842        server_id: LanguageServerId,
 3843        request_id: Option<usize>,
 3844    },
 3845    RefreshCodeLens,
 3846    DiagnosticsUpdated {
 3847        server_id: LanguageServerId,
 3848        paths: Vec<ProjectPath>,
 3849    },
 3850    DiskBasedDiagnosticsStarted {
 3851        language_server_id: LanguageServerId,
 3852    },
 3853    DiskBasedDiagnosticsFinished {
 3854        language_server_id: LanguageServerId,
 3855    },
 3856    SnippetEdit {
 3857        buffer_id: BufferId,
 3858        edits: Vec<(lsp::Range, Snippet)>,
 3859        most_recent_edit: clock::Lamport,
 3860    },
 3861    WorkspaceEditApplied(ProjectTransaction),
 3862}
 3863
 3864#[derive(Clone, Debug, Serialize)]
 3865pub struct LanguageServerStatus {
 3866    pub name: LanguageServerName,
 3867    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3868    pub has_pending_diagnostic_updates: bool,
 3869    pub progress_tokens: HashSet<ProgressToken>,
 3870    pub worktree: Option<WorktreeId>,
 3871    pub binary: Option<LanguageServerBinary>,
 3872    pub configuration: Option<Value>,
 3873    pub workspace_folders: BTreeSet<Uri>,
 3874}
 3875
 3876#[derive(Clone, Debug)]
 3877struct CoreSymbol {
 3878    pub language_server_name: LanguageServerName,
 3879    pub source_worktree_id: WorktreeId,
 3880    pub source_language_server_id: LanguageServerId,
 3881    pub path: SymbolLocation,
 3882    pub name: String,
 3883    pub kind: lsp::SymbolKind,
 3884    pub range: Range<Unclipped<PointUtf16>>,
 3885}
 3886
 3887#[derive(Clone, Debug, PartialEq, Eq)]
 3888pub enum SymbolLocation {
 3889    InProject(ProjectPath),
 3890    OutsideProject {
 3891        abs_path: Arc<Path>,
 3892        signature: [u8; 32],
 3893    },
 3894}
 3895
 3896impl SymbolLocation {
 3897    fn file_name(&self) -> Option<&str> {
 3898        match self {
 3899            Self::InProject(path) => path.path.file_name(),
 3900            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3901        }
 3902    }
 3903}
 3904
 3905impl LspStore {
 3906    pub fn init(client: &AnyProtoClient) {
 3907        client.add_entity_request_handler(Self::handle_lsp_query);
 3908        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3909        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3910        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3911        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3912        client.add_entity_message_handler(Self::handle_start_language_server);
 3913        client.add_entity_message_handler(Self::handle_update_language_server);
 3914        client.add_entity_message_handler(Self::handle_language_server_log);
 3915        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3916        client.add_entity_request_handler(Self::handle_format_buffers);
 3917        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3918        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3919        client.add_entity_request_handler(Self::handle_apply_code_action);
 3920        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3921        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3922        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3923        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3924        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3925        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3926        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3927        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3928        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3929        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3930        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3931        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3932        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3933        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3934        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3935        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3936        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3937
 3938        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3939        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3940        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3941        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3942        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3943        client.add_entity_request_handler(
 3944            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3945        );
 3946        client.add_entity_request_handler(
 3947            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3948        );
 3949        client.add_entity_request_handler(
 3950            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3951        );
 3952    }
 3953
 3954    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3955        match &self.mode {
 3956            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3957            _ => None,
 3958        }
 3959    }
 3960
 3961    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3962        match &self.mode {
 3963            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3964            _ => None,
 3965        }
 3966    }
 3967
 3968    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3969        match &mut self.mode {
 3970            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3971            _ => None,
 3972        }
 3973    }
 3974
 3975    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3976        match &self.mode {
 3977            LspStoreMode::Remote(RemoteLspStore {
 3978                upstream_client: Some(upstream_client),
 3979                upstream_project_id,
 3980                ..
 3981            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3982
 3983            LspStoreMode::Remote(RemoteLspStore {
 3984                upstream_client: None,
 3985                ..
 3986            }) => None,
 3987            LspStoreMode::Local(_) => None,
 3988        }
 3989    }
 3990
 3991    pub fn new_local(
 3992        buffer_store: Entity<BufferStore>,
 3993        worktree_store: Entity<WorktreeStore>,
 3994        prettier_store: Entity<PrettierStore>,
 3995        toolchain_store: Entity<LocalToolchainStore>,
 3996        environment: Entity<ProjectEnvironment>,
 3997        manifest_tree: Entity<ManifestTree>,
 3998        languages: Arc<LanguageRegistry>,
 3999        http_client: Arc<dyn HttpClient>,
 4000        fs: Arc<dyn Fs>,
 4001        cx: &mut Context<Self>,
 4002    ) -> Self {
 4003        let yarn = YarnPathStore::new(fs.clone(), cx);
 4004        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4005            .detach();
 4006        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4007            .detach();
 4008        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4009            .detach();
 4010        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4011            .detach();
 4012        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4013            .detach();
 4014        subscribe_to_binary_statuses(&languages, cx).detach();
 4015
 4016        let _maintain_workspace_config = {
 4017            let (sender, receiver) = watch::channel();
 4018            (Self::maintain_workspace_config(receiver, cx), sender)
 4019        };
 4020
 4021        Self {
 4022            mode: LspStoreMode::Local(LocalLspStore {
 4023                weak: cx.weak_entity(),
 4024                worktree_store: worktree_store.clone(),
 4025
 4026                supplementary_language_servers: Default::default(),
 4027                languages: languages.clone(),
 4028                language_server_ids: Default::default(),
 4029                language_servers: Default::default(),
 4030                last_workspace_edits_by_language_server: Default::default(),
 4031                language_server_watched_paths: Default::default(),
 4032                language_server_paths_watched_for_rename: Default::default(),
 4033                language_server_dynamic_registrations: Default::default(),
 4034                buffers_being_formatted: Default::default(),
 4035                buffer_snapshots: Default::default(),
 4036                prettier_store,
 4037                environment,
 4038                http_client,
 4039                fs,
 4040                yarn,
 4041                next_diagnostic_group_id: Default::default(),
 4042                diagnostics: Default::default(),
 4043                _subscription: cx.on_app_quit(|this, cx| {
 4044                    this.as_local_mut()
 4045                        .unwrap()
 4046                        .shutdown_language_servers_on_quit(cx)
 4047                }),
 4048                lsp_tree: LanguageServerTree::new(
 4049                    manifest_tree,
 4050                    languages.clone(),
 4051                    toolchain_store.clone(),
 4052                ),
 4053                toolchain_store,
 4054                registered_buffers: HashMap::default(),
 4055                buffers_opened_in_servers: HashMap::default(),
 4056                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4057                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4058                restricted_worktrees_tasks: HashMap::default(),
 4059                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4060                    .manifest_file_names(),
 4061            }),
 4062            last_formatting_failure: None,
 4063            downstream_client: None,
 4064            buffer_store,
 4065            worktree_store,
 4066            languages: languages.clone(),
 4067            language_server_statuses: Default::default(),
 4068            nonce: StdRng::from_os_rng().random(),
 4069            diagnostic_summaries: HashMap::default(),
 4070            lsp_server_capabilities: HashMap::default(),
 4071            lsp_data: HashMap::default(),
 4072            next_hint_id: Arc::default(),
 4073            active_entry: None,
 4074            _maintain_workspace_config,
 4075            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4076        }
 4077    }
 4078
 4079    fn send_lsp_proto_request<R: LspCommand>(
 4080        &self,
 4081        buffer: Entity<Buffer>,
 4082        client: AnyProtoClient,
 4083        upstream_project_id: u64,
 4084        request: R,
 4085        cx: &mut Context<LspStore>,
 4086    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4087        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4088            return Task::ready(Ok(R::Response::default()));
 4089        }
 4090        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4091        cx.spawn(async move |this, cx| {
 4092            let response = client.request(message).await?;
 4093            let this = this.upgrade().context("project dropped")?;
 4094            request
 4095                .response_from_proto(response, this, buffer, cx.clone())
 4096                .await
 4097        })
 4098    }
 4099
 4100    pub(super) fn new_remote(
 4101        buffer_store: Entity<BufferStore>,
 4102        worktree_store: Entity<WorktreeStore>,
 4103        languages: Arc<LanguageRegistry>,
 4104        upstream_client: AnyProtoClient,
 4105        project_id: u64,
 4106        cx: &mut Context<Self>,
 4107    ) -> Self {
 4108        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4109            .detach();
 4110        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4111            .detach();
 4112        subscribe_to_binary_statuses(&languages, cx).detach();
 4113        let _maintain_workspace_config = {
 4114            let (sender, receiver) = watch::channel();
 4115            (Self::maintain_workspace_config(receiver, cx), sender)
 4116        };
 4117        Self {
 4118            mode: LspStoreMode::Remote(RemoteLspStore {
 4119                upstream_client: Some(upstream_client),
 4120                upstream_project_id: project_id,
 4121            }),
 4122            downstream_client: None,
 4123            last_formatting_failure: None,
 4124            buffer_store,
 4125            worktree_store,
 4126            languages: languages.clone(),
 4127            language_server_statuses: Default::default(),
 4128            nonce: StdRng::from_os_rng().random(),
 4129            diagnostic_summaries: HashMap::default(),
 4130            lsp_server_capabilities: HashMap::default(),
 4131            next_hint_id: Arc::default(),
 4132            lsp_data: HashMap::default(),
 4133            active_entry: None,
 4134
 4135            _maintain_workspace_config,
 4136            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4137        }
 4138    }
 4139
 4140    fn on_buffer_store_event(
 4141        &mut self,
 4142        _: Entity<BufferStore>,
 4143        event: &BufferStoreEvent,
 4144        cx: &mut Context<Self>,
 4145    ) {
 4146        match event {
 4147            BufferStoreEvent::BufferAdded(buffer) => {
 4148                self.on_buffer_added(buffer, cx).log_err();
 4149            }
 4150            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4151                let buffer_id = buffer.read(cx).remote_id();
 4152                if let Some(local) = self.as_local_mut()
 4153                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4154                {
 4155                    local.reset_buffer(buffer, old_file, cx);
 4156
 4157                    if local.registered_buffers.contains_key(&buffer_id) {
 4158                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4159                    }
 4160                }
 4161
 4162                self.detect_language_for_buffer(buffer, cx);
 4163                if let Some(local) = self.as_local_mut() {
 4164                    local.initialize_buffer(buffer, cx);
 4165                    if local.registered_buffers.contains_key(&buffer_id) {
 4166                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4167                    }
 4168                }
 4169            }
 4170            _ => {}
 4171        }
 4172    }
 4173
 4174    fn on_worktree_store_event(
 4175        &mut self,
 4176        _: Entity<WorktreeStore>,
 4177        event: &WorktreeStoreEvent,
 4178        cx: &mut Context<Self>,
 4179    ) {
 4180        match event {
 4181            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4182                if !worktree.read(cx).is_local() {
 4183                    return;
 4184                }
 4185                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4186                    worktree::Event::UpdatedEntries(changes) => {
 4187                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4188                    }
 4189                    worktree::Event::UpdatedGitRepositories(_)
 4190                    | worktree::Event::DeletedEntry(_) => {}
 4191                })
 4192                .detach()
 4193            }
 4194            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4195            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4196                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4197            }
 4198            WorktreeStoreEvent::WorktreeReleased(..)
 4199            | WorktreeStoreEvent::WorktreeOrderChanged
 4200            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4201            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4202            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4203        }
 4204    }
 4205
 4206    fn on_prettier_store_event(
 4207        &mut self,
 4208        _: Entity<PrettierStore>,
 4209        event: &PrettierStoreEvent,
 4210        cx: &mut Context<Self>,
 4211    ) {
 4212        match event {
 4213            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4214                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4215            }
 4216            PrettierStoreEvent::LanguageServerAdded {
 4217                new_server_id,
 4218                name,
 4219                prettier_server,
 4220            } => {
 4221                self.register_supplementary_language_server(
 4222                    *new_server_id,
 4223                    name.clone(),
 4224                    prettier_server.clone(),
 4225                    cx,
 4226                );
 4227            }
 4228        }
 4229    }
 4230
 4231    fn on_toolchain_store_event(
 4232        &mut self,
 4233        _: Entity<LocalToolchainStore>,
 4234        event: &ToolchainStoreEvent,
 4235        _: &mut Context<Self>,
 4236    ) {
 4237        if let ToolchainStoreEvent::ToolchainActivated = event {
 4238            self.request_workspace_config_refresh()
 4239        }
 4240    }
 4241
 4242    fn request_workspace_config_refresh(&mut self) {
 4243        *self._maintain_workspace_config.1.borrow_mut() = ();
 4244    }
 4245
 4246    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4247        self.as_local().map(|local| local.prettier_store.clone())
 4248    }
 4249
 4250    fn on_buffer_event(
 4251        &mut self,
 4252        buffer: Entity<Buffer>,
 4253        event: &language::BufferEvent,
 4254        cx: &mut Context<Self>,
 4255    ) {
 4256        match event {
 4257            language::BufferEvent::Edited => {
 4258                self.on_buffer_edited(buffer, cx);
 4259            }
 4260
 4261            language::BufferEvent::Saved => {
 4262                self.on_buffer_saved(buffer, cx);
 4263            }
 4264
 4265            _ => {}
 4266        }
 4267    }
 4268
 4269    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4270        buffer
 4271            .read(cx)
 4272            .set_language_registry(self.languages.clone());
 4273
 4274        cx.subscribe(buffer, |this, buffer, event, cx| {
 4275            this.on_buffer_event(buffer, event, cx);
 4276        })
 4277        .detach();
 4278
 4279        self.detect_language_for_buffer(buffer, cx);
 4280        if let Some(local) = self.as_local_mut() {
 4281            local.initialize_buffer(buffer, cx);
 4282        }
 4283
 4284        Ok(())
 4285    }
 4286
 4287    pub(crate) fn register_buffer_with_language_servers(
 4288        &mut self,
 4289        buffer: &Entity<Buffer>,
 4290        only_register_servers: HashSet<LanguageServerSelector>,
 4291        ignore_refcounts: bool,
 4292        cx: &mut Context<Self>,
 4293    ) -> OpenLspBufferHandle {
 4294        let buffer_id = buffer.read(cx).remote_id();
 4295        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4296        if let Some(local) = self.as_local_mut() {
 4297            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4298            if !ignore_refcounts {
 4299                *refcount += 1;
 4300            }
 4301
 4302            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4303            // 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
 4304            // 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
 4305            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4306            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4307                return handle;
 4308            };
 4309            if !file.is_local() {
 4310                return handle;
 4311            }
 4312
 4313            if ignore_refcounts || *refcount == 1 {
 4314                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4315            }
 4316            if !ignore_refcounts {
 4317                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4318                    let refcount = {
 4319                        let local = lsp_store.as_local_mut().unwrap();
 4320                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4321                            debug_panic!("bad refcounting");
 4322                            return;
 4323                        };
 4324
 4325                        *refcount -= 1;
 4326                        *refcount
 4327                    };
 4328                    if refcount == 0 {
 4329                        lsp_store.lsp_data.remove(&buffer_id);
 4330                        let local = lsp_store.as_local_mut().unwrap();
 4331                        local.registered_buffers.remove(&buffer_id);
 4332
 4333                        local.buffers_opened_in_servers.remove(&buffer_id);
 4334                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4335                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4336
 4337                            let buffer_abs_path = file.abs_path(cx);
 4338                            for (_, buffer_pull_diagnostics_result_ids) in
 4339                                &mut local.buffer_pull_diagnostics_result_ids
 4340                            {
 4341                                buffer_pull_diagnostics_result_ids.retain(
 4342                                    |_, buffer_result_ids| {
 4343                                        buffer_result_ids.remove(&buffer_abs_path);
 4344                                        !buffer_result_ids.is_empty()
 4345                                    },
 4346                                );
 4347                            }
 4348
 4349                            let diagnostic_updates = local
 4350                                .language_servers
 4351                                .keys()
 4352                                .cloned()
 4353                                .map(|server_id| DocumentDiagnosticsUpdate {
 4354                                    diagnostics: DocumentDiagnostics {
 4355                                        document_abs_path: buffer_abs_path.clone(),
 4356                                        version: None,
 4357                                        diagnostics: Vec::new(),
 4358                                    },
 4359                                    result_id: None,
 4360                                    registration_id: None,
 4361                                    server_id: server_id,
 4362                                    disk_based_sources: Cow::Borrowed(&[]),
 4363                                })
 4364                                .collect::<Vec<_>>();
 4365
 4366                            lsp_store
 4367                                .merge_diagnostic_entries(
 4368                                    diagnostic_updates,
 4369                                    |_, diagnostic, _| {
 4370                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4371                                    },
 4372                                    cx,
 4373                                )
 4374                                .context("Clearing diagnostics for the closed buffer")
 4375                                .log_err();
 4376                        }
 4377                    }
 4378                })
 4379                .detach();
 4380            }
 4381        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4382            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4383            cx.background_spawn(async move {
 4384                upstream_client
 4385                    .request(proto::RegisterBufferWithLanguageServers {
 4386                        project_id: upstream_project_id,
 4387                        buffer_id,
 4388                        only_servers: only_register_servers
 4389                            .into_iter()
 4390                            .map(|selector| {
 4391                                let selector = match selector {
 4392                                    LanguageServerSelector::Id(language_server_id) => {
 4393                                        proto::language_server_selector::Selector::ServerId(
 4394                                            language_server_id.to_proto(),
 4395                                        )
 4396                                    }
 4397                                    LanguageServerSelector::Name(language_server_name) => {
 4398                                        proto::language_server_selector::Selector::Name(
 4399                                            language_server_name.to_string(),
 4400                                        )
 4401                                    }
 4402                                };
 4403                                proto::LanguageServerSelector {
 4404                                    selector: Some(selector),
 4405                                }
 4406                            })
 4407                            .collect(),
 4408                    })
 4409                    .await
 4410            })
 4411            .detach();
 4412        } else {
 4413            // Our remote connection got closed
 4414        }
 4415        handle
 4416    }
 4417
 4418    fn maintain_buffer_languages(
 4419        languages: Arc<LanguageRegistry>,
 4420        cx: &mut Context<Self>,
 4421    ) -> Task<()> {
 4422        let mut subscription = languages.subscribe();
 4423        let mut prev_reload_count = languages.reload_count();
 4424        cx.spawn(async move |this, cx| {
 4425            while let Some(()) = subscription.next().await {
 4426                if let Some(this) = this.upgrade() {
 4427                    // If the language registry has been reloaded, then remove and
 4428                    // re-assign the languages on all open buffers.
 4429                    let reload_count = languages.reload_count();
 4430                    if reload_count > prev_reload_count {
 4431                        prev_reload_count = reload_count;
 4432                        this.update(cx, |this, cx| {
 4433                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4434                                for buffer in buffer_store.buffers() {
 4435                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4436                                    {
 4437                                        buffer.update(cx, |buffer, cx| {
 4438                                            buffer.set_language_async(None, cx)
 4439                                        });
 4440                                        if let Some(local) = this.as_local_mut() {
 4441                                            local.reset_buffer(&buffer, &f, cx);
 4442
 4443                                            if local
 4444                                                .registered_buffers
 4445                                                .contains_key(&buffer.read(cx).remote_id())
 4446                                                && let Some(file_url) =
 4447                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4448                                            {
 4449                                                local.unregister_buffer_from_language_servers(
 4450                                                    &buffer, &file_url, cx,
 4451                                                );
 4452                                            }
 4453                                        }
 4454                                    }
 4455                                }
 4456                            });
 4457                        })
 4458                        .ok();
 4459                    }
 4460
 4461                    this.update(cx, |this, cx| {
 4462                        let mut plain_text_buffers = Vec::new();
 4463                        let mut buffers_with_unknown_injections = Vec::new();
 4464                        for handle in this.buffer_store.read(cx).buffers() {
 4465                            let buffer = handle.read(cx);
 4466                            if buffer.language().is_none()
 4467                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4468                            {
 4469                                plain_text_buffers.push(handle);
 4470                            } else if buffer.contains_unknown_injections() {
 4471                                buffers_with_unknown_injections.push(handle);
 4472                            }
 4473                        }
 4474
 4475                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4476                        // and reused later in the invisible worktrees.
 4477                        plain_text_buffers.sort_by_key(|buffer| {
 4478                            Reverse(
 4479                                File::from_dyn(buffer.read(cx).file())
 4480                                    .map(|file| file.worktree.read(cx).is_visible()),
 4481                            )
 4482                        });
 4483
 4484                        for buffer in plain_text_buffers {
 4485                            this.detect_language_for_buffer(&buffer, cx);
 4486                            if let Some(local) = this.as_local_mut() {
 4487                                local.initialize_buffer(&buffer, cx);
 4488                                if local
 4489                                    .registered_buffers
 4490                                    .contains_key(&buffer.read(cx).remote_id())
 4491                                {
 4492                                    local.register_buffer_with_language_servers(
 4493                                        &buffer,
 4494                                        HashSet::default(),
 4495                                        cx,
 4496                                    );
 4497                                }
 4498                            }
 4499                        }
 4500
 4501                        for buffer in buffers_with_unknown_injections {
 4502                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4503                        }
 4504                    })
 4505                    .ok();
 4506                }
 4507            }
 4508        })
 4509    }
 4510
 4511    fn detect_language_for_buffer(
 4512        &mut self,
 4513        buffer_handle: &Entity<Buffer>,
 4514        cx: &mut Context<Self>,
 4515    ) -> Option<language::AvailableLanguage> {
 4516        // If the buffer has a language, set it and start the language server if we haven't already.
 4517        let buffer = buffer_handle.read(cx);
 4518        let file = buffer.file()?;
 4519
 4520        let content = buffer.as_rope();
 4521        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4522        if let Some(available_language) = &available_language {
 4523            if let Some(Ok(Ok(new_language))) = self
 4524                .languages
 4525                .load_language(available_language)
 4526                .now_or_never()
 4527            {
 4528                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4529            }
 4530        } else {
 4531            cx.emit(LspStoreEvent::LanguageDetected {
 4532                buffer: buffer_handle.clone(),
 4533                new_language: None,
 4534            });
 4535        }
 4536
 4537        available_language
 4538    }
 4539
 4540    pub(crate) fn set_language_for_buffer(
 4541        &mut self,
 4542        buffer_entity: &Entity<Buffer>,
 4543        new_language: Arc<Language>,
 4544        cx: &mut Context<Self>,
 4545    ) {
 4546        let buffer = buffer_entity.read(cx);
 4547        let buffer_file = buffer.file().cloned();
 4548        let buffer_id = buffer.remote_id();
 4549        if let Some(local_store) = self.as_local_mut()
 4550            && local_store.registered_buffers.contains_key(&buffer_id)
 4551            && let Some(abs_path) =
 4552                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4553            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4554        {
 4555            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4556        }
 4557        buffer_entity.update(cx, |buffer, cx| {
 4558            if buffer
 4559                .language()
 4560                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4561            {
 4562                buffer.set_language_async(Some(new_language.clone()), cx);
 4563            }
 4564        });
 4565
 4566        let settings =
 4567            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4568        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4569
 4570        let worktree_id = if let Some(file) = buffer_file {
 4571            let worktree = file.worktree.clone();
 4572
 4573            if let Some(local) = self.as_local_mut()
 4574                && local.registered_buffers.contains_key(&buffer_id)
 4575            {
 4576                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4577            }
 4578            Some(worktree.read(cx).id())
 4579        } else {
 4580            None
 4581        };
 4582
 4583        if settings.prettier.allowed
 4584            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4585        {
 4586            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4587            if let Some(prettier_store) = prettier_store {
 4588                prettier_store.update(cx, |prettier_store, cx| {
 4589                    prettier_store.install_default_prettier(
 4590                        worktree_id,
 4591                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4592                        cx,
 4593                    )
 4594                })
 4595            }
 4596        }
 4597
 4598        cx.emit(LspStoreEvent::LanguageDetected {
 4599            buffer: buffer_entity.clone(),
 4600            new_language: Some(new_language),
 4601        })
 4602    }
 4603
 4604    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4605        self.buffer_store.clone()
 4606    }
 4607
 4608    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4609        self.active_entry = active_entry;
 4610    }
 4611
 4612    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4613        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4614            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4615        {
 4616            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4617                summaries
 4618                    .iter()
 4619                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4620            });
 4621            if let Some(summary) = summaries.next() {
 4622                client
 4623                    .send(proto::UpdateDiagnosticSummary {
 4624                        project_id: downstream_project_id,
 4625                        worktree_id: worktree.id().to_proto(),
 4626                        summary: Some(summary),
 4627                        more_summaries: summaries.collect(),
 4628                    })
 4629                    .log_err();
 4630            }
 4631        }
 4632    }
 4633
 4634    fn is_capable_for_proto_request<R>(
 4635        &self,
 4636        buffer: &Entity<Buffer>,
 4637        request: &R,
 4638        cx: &App,
 4639    ) -> bool
 4640    where
 4641        R: LspCommand,
 4642    {
 4643        self.check_if_capable_for_proto_request(
 4644            buffer,
 4645            |capabilities| {
 4646                request.check_capabilities(AdapterServerCapabilities {
 4647                    server_capabilities: capabilities.clone(),
 4648                    code_action_kinds: None,
 4649                })
 4650            },
 4651            cx,
 4652        )
 4653    }
 4654
 4655    fn check_if_capable_for_proto_request<F>(
 4656        &self,
 4657        buffer: &Entity<Buffer>,
 4658        check: F,
 4659        cx: &App,
 4660    ) -> bool
 4661    where
 4662        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4663    {
 4664        let Some(language) = buffer.read(cx).language().cloned() else {
 4665            return false;
 4666        };
 4667        let relevant_language_servers = self
 4668            .languages
 4669            .lsp_adapters(&language.name())
 4670            .into_iter()
 4671            .map(|lsp_adapter| lsp_adapter.name())
 4672            .collect::<HashSet<_>>();
 4673        self.language_server_statuses
 4674            .iter()
 4675            .filter_map(|(server_id, server_status)| {
 4676                relevant_language_servers
 4677                    .contains(&server_status.name)
 4678                    .then_some(server_id)
 4679            })
 4680            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4681            .any(check)
 4682    }
 4683
 4684    fn all_capable_for_proto_request<F>(
 4685        &self,
 4686        buffer: &Entity<Buffer>,
 4687        mut check: F,
 4688        cx: &App,
 4689    ) -> Vec<lsp::LanguageServerId>
 4690    where
 4691        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4692    {
 4693        let Some(language) = buffer.read(cx).language().cloned() else {
 4694            return Vec::default();
 4695        };
 4696        let relevant_language_servers = self
 4697            .languages
 4698            .lsp_adapters(&language.name())
 4699            .into_iter()
 4700            .map(|lsp_adapter| lsp_adapter.name())
 4701            .collect::<HashSet<_>>();
 4702        self.language_server_statuses
 4703            .iter()
 4704            .filter_map(|(server_id, server_status)| {
 4705                relevant_language_servers
 4706                    .contains(&server_status.name)
 4707                    .then_some((server_id, &server_status.name))
 4708            })
 4709            .filter_map(|(server_id, server_name)| {
 4710                self.lsp_server_capabilities
 4711                    .get(server_id)
 4712                    .map(|c| (server_id, server_name, c))
 4713            })
 4714            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4715            .map(|(server_id, _, _)| *server_id)
 4716            .collect()
 4717    }
 4718
 4719    pub fn request_lsp<R>(
 4720        &mut self,
 4721        buffer: Entity<Buffer>,
 4722        server: LanguageServerToQuery,
 4723        request: R,
 4724        cx: &mut Context<Self>,
 4725    ) -> Task<Result<R::Response>>
 4726    where
 4727        R: LspCommand,
 4728        <R::LspRequest as lsp::request::Request>::Result: Send,
 4729        <R::LspRequest as lsp::request::Request>::Params: Send,
 4730    {
 4731        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4732            return self.send_lsp_proto_request(
 4733                buffer,
 4734                upstream_client,
 4735                upstream_project_id,
 4736                request,
 4737                cx,
 4738            );
 4739        }
 4740
 4741        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4742            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4743                local
 4744                    .language_servers_for_buffer(buffer, cx)
 4745                    .find(|(_, server)| {
 4746                        request.check_capabilities(server.adapter_server_capabilities())
 4747                    })
 4748                    .map(|(_, server)| server.clone())
 4749            }),
 4750            LanguageServerToQuery::Other(id) => self
 4751                .language_server_for_local_buffer(buffer, id, cx)
 4752                .and_then(|(_, server)| {
 4753                    request
 4754                        .check_capabilities(server.adapter_server_capabilities())
 4755                        .then(|| Arc::clone(server))
 4756                }),
 4757        }) else {
 4758            return Task::ready(Ok(Default::default()));
 4759        };
 4760
 4761        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4762
 4763        let Some(file) = file else {
 4764            return Task::ready(Ok(Default::default()));
 4765        };
 4766
 4767        let lsp_params = match request.to_lsp_params_or_response(
 4768            &file.abs_path(cx),
 4769            buffer.read(cx),
 4770            &language_server,
 4771            cx,
 4772        ) {
 4773            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4774            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4775            Err(err) => {
 4776                let message = format!(
 4777                    "{} via {} failed: {}",
 4778                    request.display_name(),
 4779                    language_server.name(),
 4780                    err
 4781                );
 4782                // rust-analyzer likes to error with this when its still loading up
 4783                if !message.ends_with("content modified") {
 4784                    log::warn!("{message}");
 4785                }
 4786                return Task::ready(Err(anyhow!(message)));
 4787            }
 4788        };
 4789
 4790        let status = request.status();
 4791        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4792            return Task::ready(Ok(Default::default()));
 4793        }
 4794        cx.spawn(async move |this, cx| {
 4795            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4796
 4797            let id = lsp_request.id();
 4798            let _cleanup = if status.is_some() {
 4799                cx.update(|cx| {
 4800                    this.update(cx, |this, cx| {
 4801                        this.on_lsp_work_start(
 4802                            language_server.server_id(),
 4803                            ProgressToken::Number(id),
 4804                            LanguageServerProgress {
 4805                                is_disk_based_diagnostics_progress: false,
 4806                                is_cancellable: false,
 4807                                title: None,
 4808                                message: status.clone(),
 4809                                percentage: None,
 4810                                last_update_at: cx.background_executor().now(),
 4811                            },
 4812                            cx,
 4813                        );
 4814                    })
 4815                })
 4816                .log_err();
 4817
 4818                Some(defer(|| {
 4819                    cx.update(|cx| {
 4820                        this.update(cx, |this, cx| {
 4821                            this.on_lsp_work_end(
 4822                                language_server.server_id(),
 4823                                ProgressToken::Number(id),
 4824                                cx,
 4825                            );
 4826                        })
 4827                    })
 4828                    .log_err();
 4829                }))
 4830            } else {
 4831                None
 4832            };
 4833
 4834            let result = lsp_request.await.into_response();
 4835
 4836            let response = result.map_err(|err| {
 4837                let message = format!(
 4838                    "{} via {} failed: {}",
 4839                    request.display_name(),
 4840                    language_server.name(),
 4841                    err
 4842                );
 4843                // rust-analyzer likes to error with this when its still loading up
 4844                if !message.ends_with("content modified") {
 4845                    log::warn!("{message}");
 4846                }
 4847                anyhow::anyhow!(message)
 4848            })?;
 4849
 4850            request
 4851                .response_from_lsp(
 4852                    response,
 4853                    this.upgrade().context("no app context")?,
 4854                    buffer,
 4855                    language_server.server_id(),
 4856                    cx.clone(),
 4857                )
 4858                .await
 4859        })
 4860    }
 4861
 4862    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4863        let mut language_formatters_to_check = Vec::new();
 4864        for buffer in self.buffer_store.read(cx).buffers() {
 4865            let buffer = buffer.read(cx);
 4866            let buffer_file = File::from_dyn(buffer.file());
 4867            let buffer_language = buffer.language();
 4868            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4869            if buffer_language.is_some() {
 4870                language_formatters_to_check.push((
 4871                    buffer_file.map(|f| f.worktree_id(cx)),
 4872                    settings.into_owned(),
 4873                ));
 4874            }
 4875        }
 4876
 4877        self.request_workspace_config_refresh();
 4878
 4879        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4880            prettier_store.update(cx, |prettier_store, cx| {
 4881                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4882            })
 4883        }
 4884
 4885        cx.notify();
 4886    }
 4887
 4888    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4889        let buffer_store = self.buffer_store.clone();
 4890        let Some(local) = self.as_local_mut() else {
 4891            return;
 4892        };
 4893        let mut adapters = BTreeMap::default();
 4894        let get_adapter = {
 4895            let languages = local.languages.clone();
 4896            let environment = local.environment.clone();
 4897            let weak = local.weak.clone();
 4898            let worktree_store = local.worktree_store.clone();
 4899            let http_client = local.http_client.clone();
 4900            let fs = local.fs.clone();
 4901            move |worktree_id, cx: &mut App| {
 4902                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4903                Some(LocalLspAdapterDelegate::new(
 4904                    languages.clone(),
 4905                    &environment,
 4906                    weak.clone(),
 4907                    &worktree,
 4908                    http_client.clone(),
 4909                    fs.clone(),
 4910                    cx,
 4911                ))
 4912            }
 4913        };
 4914
 4915        let mut messages_to_report = Vec::new();
 4916        let (new_tree, to_stop) = {
 4917            let mut rebase = local.lsp_tree.rebase();
 4918            let buffers = buffer_store
 4919                .read(cx)
 4920                .buffers()
 4921                .filter_map(|buffer| {
 4922                    let raw_buffer = buffer.read(cx);
 4923                    if !local
 4924                        .registered_buffers
 4925                        .contains_key(&raw_buffer.remote_id())
 4926                    {
 4927                        return None;
 4928                    }
 4929                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4930                    let language = raw_buffer.language().cloned()?;
 4931                    Some((file, language, raw_buffer.remote_id()))
 4932                })
 4933                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4934            for (file, language, buffer_id) in buffers {
 4935                let worktree_id = file.worktree_id(cx);
 4936                let Some(worktree) = local
 4937                    .worktree_store
 4938                    .read(cx)
 4939                    .worktree_for_id(worktree_id, cx)
 4940                else {
 4941                    continue;
 4942                };
 4943
 4944                if let Some((_, apply)) = local.reuse_existing_language_server(
 4945                    rebase.server_tree(),
 4946                    &worktree,
 4947                    &language.name(),
 4948                    cx,
 4949                ) {
 4950                    (apply)(rebase.server_tree());
 4951                } else if let Some(lsp_delegate) = adapters
 4952                    .entry(worktree_id)
 4953                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4954                    .clone()
 4955                {
 4956                    let delegate =
 4957                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4958                    let path = file
 4959                        .path()
 4960                        .parent()
 4961                        .map(Arc::from)
 4962                        .unwrap_or_else(|| file.path().clone());
 4963                    let worktree_path = ProjectPath { worktree_id, path };
 4964                    let abs_path = file.abs_path(cx);
 4965                    let nodes = rebase
 4966                        .walk(
 4967                            worktree_path,
 4968                            language.name(),
 4969                            language.manifest(),
 4970                            delegate.clone(),
 4971                            cx,
 4972                        )
 4973                        .collect::<Vec<_>>();
 4974                    for node in nodes {
 4975                        let server_id = node.server_id_or_init(|disposition| {
 4976                            let path = &disposition.path;
 4977                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4978                            let key = LanguageServerSeed {
 4979                                worktree_id,
 4980                                name: disposition.server_name.clone(),
 4981                                settings: disposition.settings.clone(),
 4982                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4983                                    path.worktree_id,
 4984                                    &path.path,
 4985                                    language.name(),
 4986                                ),
 4987                            };
 4988                            local.language_server_ids.remove(&key);
 4989
 4990                            let server_id = local.get_or_insert_language_server(
 4991                                &worktree,
 4992                                lsp_delegate.clone(),
 4993                                disposition,
 4994                                &language.name(),
 4995                                cx,
 4996                            );
 4997                            if let Some(state) = local.language_servers.get(&server_id)
 4998                                && let Ok(uri) = uri
 4999                            {
 5000                                state.add_workspace_folder(uri);
 5001                            };
 5002                            server_id
 5003                        });
 5004
 5005                        if let Some(language_server_id) = server_id {
 5006                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5007                                language_server_id,
 5008                                name: node.name(),
 5009                                message:
 5010                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5011                                        proto::RegisteredForBuffer {
 5012                                            buffer_abs_path: abs_path
 5013                                                .to_string_lossy()
 5014                                                .into_owned(),
 5015                                            buffer_id: buffer_id.to_proto(),
 5016                                        },
 5017                                    ),
 5018                            });
 5019                        }
 5020                    }
 5021                } else {
 5022                    continue;
 5023                }
 5024            }
 5025            rebase.finish()
 5026        };
 5027        for message in messages_to_report {
 5028            cx.emit(message);
 5029        }
 5030        local.lsp_tree = new_tree;
 5031        for (id, _) in to_stop {
 5032            self.stop_local_language_server(id, cx).detach();
 5033        }
 5034    }
 5035
 5036    pub fn apply_code_action(
 5037        &self,
 5038        buffer_handle: Entity<Buffer>,
 5039        mut action: CodeAction,
 5040        push_to_history: bool,
 5041        cx: &mut Context<Self>,
 5042    ) -> Task<Result<ProjectTransaction>> {
 5043        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5044            let request = proto::ApplyCodeAction {
 5045                project_id,
 5046                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5047                action: Some(Self::serialize_code_action(&action)),
 5048            };
 5049            let buffer_store = self.buffer_store();
 5050            cx.spawn(async move |_, cx| {
 5051                let response = upstream_client
 5052                    .request(request)
 5053                    .await?
 5054                    .transaction
 5055                    .context("missing transaction")?;
 5056
 5057                buffer_store
 5058                    .update(cx, |buffer_store, cx| {
 5059                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5060                    })?
 5061                    .await
 5062            })
 5063        } else if self.mode.is_local() {
 5064            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 5065                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5066                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 5067            }) else {
 5068                return Task::ready(Ok(ProjectTransaction::default()));
 5069            };
 5070            cx.spawn(async move |this,  cx| {
 5071                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 5072                    .await
 5073                    .context("resolving a code action")?;
 5074                if let Some(edit) = action.lsp_action.edit()
 5075                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5076                        return LocalLspStore::deserialize_workspace_edit(
 5077                            this.upgrade().context("no app present")?,
 5078                            edit.clone(),
 5079                            push_to_history,
 5080
 5081                            lang_server.clone(),
 5082                            cx,
 5083                        )
 5084                        .await;
 5085                    }
 5086
 5087                if let Some(command) = action.lsp_action.command() {
 5088                    let server_capabilities = lang_server.capabilities();
 5089                    let available_commands = server_capabilities
 5090                        .execute_command_provider
 5091                        .as_ref()
 5092                        .map(|options| options.commands.as_slice())
 5093                        .unwrap_or_default();
 5094                    if available_commands.contains(&command.command) {
 5095                        this.update(cx, |this, _| {
 5096                            this.as_local_mut()
 5097                                .unwrap()
 5098                                .last_workspace_edits_by_language_server
 5099                                .remove(&lang_server.server_id());
 5100                        })?;
 5101
 5102                        let _result = lang_server
 5103                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5104                                command: command.command.clone(),
 5105                                arguments: command.arguments.clone().unwrap_or_default(),
 5106                                ..lsp::ExecuteCommandParams::default()
 5107                            })
 5108                            .await.into_response()
 5109                            .context("execute command")?;
 5110
 5111                        return this.update(cx, |this, _| {
 5112                            this.as_local_mut()
 5113                                .unwrap()
 5114                                .last_workspace_edits_by_language_server
 5115                                .remove(&lang_server.server_id())
 5116                                .unwrap_or_default()
 5117                        });
 5118                    } else {
 5119                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5120                    }
 5121                }
 5122
 5123                Ok(ProjectTransaction::default())
 5124            })
 5125        } else {
 5126            Task::ready(Err(anyhow!("no upstream client and not local")))
 5127        }
 5128    }
 5129
 5130    pub fn apply_code_action_kind(
 5131        &mut self,
 5132        buffers: HashSet<Entity<Buffer>>,
 5133        kind: CodeActionKind,
 5134        push_to_history: bool,
 5135        cx: &mut Context<Self>,
 5136    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5137        if self.as_local().is_some() {
 5138            cx.spawn(async move |lsp_store, cx| {
 5139                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5140                let result = LocalLspStore::execute_code_action_kind_locally(
 5141                    lsp_store.clone(),
 5142                    buffers,
 5143                    kind,
 5144                    push_to_history,
 5145                    cx,
 5146                )
 5147                .await;
 5148                lsp_store.update(cx, |lsp_store, _| {
 5149                    lsp_store.update_last_formatting_failure(&result);
 5150                })?;
 5151                result
 5152            })
 5153        } else if let Some((client, project_id)) = self.upstream_client() {
 5154            let buffer_store = self.buffer_store();
 5155            cx.spawn(async move |lsp_store, cx| {
 5156                let result = client
 5157                    .request(proto::ApplyCodeActionKind {
 5158                        project_id,
 5159                        kind: kind.as_str().to_owned(),
 5160                        buffer_ids: buffers
 5161                            .iter()
 5162                            .map(|buffer| {
 5163                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5164                            })
 5165                            .collect::<Result<_>>()?,
 5166                    })
 5167                    .await
 5168                    .and_then(|result| result.transaction.context("missing transaction"));
 5169                lsp_store.update(cx, |lsp_store, _| {
 5170                    lsp_store.update_last_formatting_failure(&result);
 5171                })?;
 5172
 5173                let transaction_response = result?;
 5174                buffer_store
 5175                    .update(cx, |buffer_store, cx| {
 5176                        buffer_store.deserialize_project_transaction(
 5177                            transaction_response,
 5178                            push_to_history,
 5179                            cx,
 5180                        )
 5181                    })?
 5182                    .await
 5183            })
 5184        } else {
 5185            Task::ready(Ok(ProjectTransaction::default()))
 5186        }
 5187    }
 5188
 5189    pub fn resolved_hint(
 5190        &mut self,
 5191        buffer_id: BufferId,
 5192        id: InlayId,
 5193        cx: &mut Context<Self>,
 5194    ) -> Option<ResolvedHint> {
 5195        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5196
 5197        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5198        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5199        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5200        let (server_id, resolve_data) = match &hint.resolve_state {
 5201            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5202            ResolveState::Resolving => {
 5203                return Some(ResolvedHint::Resolving(
 5204                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5205                ));
 5206            }
 5207            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5208        };
 5209
 5210        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5211        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5212        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5213            id,
 5214            cx.spawn(async move |lsp_store, cx| {
 5215                let resolved_hint = resolve_task.await;
 5216                lsp_store
 5217                    .update(cx, |lsp_store, _| {
 5218                        if let Some(old_inlay_hint) = lsp_store
 5219                            .lsp_data
 5220                            .get_mut(&buffer_id)
 5221                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5222                        {
 5223                            match resolved_hint {
 5224                                Ok(resolved_hint) => {
 5225                                    *old_inlay_hint = resolved_hint;
 5226                                }
 5227                                Err(e) => {
 5228                                    old_inlay_hint.resolve_state =
 5229                                        ResolveState::CanResolve(server_id, resolve_data);
 5230                                    log::error!("Inlay hint resolve failed: {e:#}");
 5231                                }
 5232                            }
 5233                        }
 5234                    })
 5235                    .ok();
 5236            })
 5237            .shared(),
 5238        );
 5239        debug_assert!(
 5240            previous_task.is_none(),
 5241            "Did not change hint's resolve state after spawning its resolve"
 5242        );
 5243        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5244        None
 5245    }
 5246
 5247    fn resolve_inlay_hint(
 5248        &self,
 5249        mut hint: InlayHint,
 5250        buffer: Entity<Buffer>,
 5251        server_id: LanguageServerId,
 5252        cx: &mut Context<Self>,
 5253    ) -> Task<anyhow::Result<InlayHint>> {
 5254        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5255            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5256            {
 5257                hint.resolve_state = ResolveState::Resolved;
 5258                return Task::ready(Ok(hint));
 5259            }
 5260            let request = proto::ResolveInlayHint {
 5261                project_id,
 5262                buffer_id: buffer.read(cx).remote_id().into(),
 5263                language_server_id: server_id.0 as u64,
 5264                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5265            };
 5266            cx.background_spawn(async move {
 5267                let response = upstream_client
 5268                    .request(request)
 5269                    .await
 5270                    .context("inlay hints proto request")?;
 5271                match response.hint {
 5272                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5273                        .context("inlay hints proto resolve response conversion"),
 5274                    None => Ok(hint),
 5275                }
 5276            })
 5277        } else {
 5278            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5279                self.language_server_for_local_buffer(buffer, server_id, cx)
 5280                    .map(|(_, server)| server.clone())
 5281            }) else {
 5282                return Task::ready(Ok(hint));
 5283            };
 5284            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5285                return Task::ready(Ok(hint));
 5286            }
 5287            let buffer_snapshot = buffer.read(cx).snapshot();
 5288            cx.spawn(async move |_, cx| {
 5289                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5290                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5291                );
 5292                let resolved_hint = resolve_task
 5293                    .await
 5294                    .into_response()
 5295                    .context("inlay hint resolve LSP request")?;
 5296                let resolved_hint = InlayHints::lsp_to_project_hint(
 5297                    resolved_hint,
 5298                    &buffer,
 5299                    server_id,
 5300                    ResolveState::Resolved,
 5301                    false,
 5302                    cx,
 5303                )
 5304                .await?;
 5305                Ok(resolved_hint)
 5306            })
 5307        }
 5308    }
 5309
 5310    pub fn resolve_color_presentation(
 5311        &mut self,
 5312        mut color: DocumentColor,
 5313        buffer: Entity<Buffer>,
 5314        server_id: LanguageServerId,
 5315        cx: &mut Context<Self>,
 5316    ) -> Task<Result<DocumentColor>> {
 5317        if color.resolved {
 5318            return Task::ready(Ok(color));
 5319        }
 5320
 5321        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5322            let start = color.lsp_range.start;
 5323            let end = color.lsp_range.end;
 5324            let request = proto::GetColorPresentation {
 5325                project_id,
 5326                server_id: server_id.to_proto(),
 5327                buffer_id: buffer.read(cx).remote_id().into(),
 5328                color: Some(proto::ColorInformation {
 5329                    red: color.color.red,
 5330                    green: color.color.green,
 5331                    blue: color.color.blue,
 5332                    alpha: color.color.alpha,
 5333                    lsp_range_start: Some(proto::PointUtf16 {
 5334                        row: start.line,
 5335                        column: start.character,
 5336                    }),
 5337                    lsp_range_end: Some(proto::PointUtf16 {
 5338                        row: end.line,
 5339                        column: end.character,
 5340                    }),
 5341                }),
 5342            };
 5343            cx.background_spawn(async move {
 5344                let response = upstream_client
 5345                    .request(request)
 5346                    .await
 5347                    .context("color presentation proto request")?;
 5348                color.resolved = true;
 5349                color.color_presentations = response
 5350                    .presentations
 5351                    .into_iter()
 5352                    .map(|presentation| ColorPresentation {
 5353                        label: SharedString::from(presentation.label),
 5354                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5355                        additional_text_edits: presentation
 5356                            .additional_text_edits
 5357                            .into_iter()
 5358                            .filter_map(deserialize_lsp_edit)
 5359                            .collect(),
 5360                    })
 5361                    .collect();
 5362                Ok(color)
 5363            })
 5364        } else {
 5365            let path = match buffer
 5366                .update(cx, |buffer, cx| {
 5367                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5368                })
 5369                .context("buffer with the missing path")
 5370            {
 5371                Ok(path) => path,
 5372                Err(e) => return Task::ready(Err(e)),
 5373            };
 5374            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5375                self.language_server_for_local_buffer(buffer, server_id, cx)
 5376                    .map(|(_, server)| server.clone())
 5377            }) else {
 5378                return Task::ready(Ok(color));
 5379            };
 5380            cx.background_spawn(async move {
 5381                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5382                    lsp::ColorPresentationParams {
 5383                        text_document: make_text_document_identifier(&path)?,
 5384                        color: color.color,
 5385                        range: color.lsp_range,
 5386                        work_done_progress_params: Default::default(),
 5387                        partial_result_params: Default::default(),
 5388                    },
 5389                );
 5390                color.color_presentations = resolve_task
 5391                    .await
 5392                    .into_response()
 5393                    .context("color presentation resolve LSP request")?
 5394                    .into_iter()
 5395                    .map(|presentation| ColorPresentation {
 5396                        label: SharedString::from(presentation.label),
 5397                        text_edit: presentation.text_edit,
 5398                        additional_text_edits: presentation
 5399                            .additional_text_edits
 5400                            .unwrap_or_default(),
 5401                    })
 5402                    .collect();
 5403                color.resolved = true;
 5404                Ok(color)
 5405            })
 5406        }
 5407    }
 5408
 5409    pub(crate) fn linked_edits(
 5410        &mut self,
 5411        buffer: &Entity<Buffer>,
 5412        position: Anchor,
 5413        cx: &mut Context<Self>,
 5414    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5415        let snapshot = buffer.read(cx).snapshot();
 5416        let scope = snapshot.language_scope_at(position);
 5417        let Some(server_id) = self
 5418            .as_local()
 5419            .and_then(|local| {
 5420                buffer.update(cx, |buffer, cx| {
 5421                    local
 5422                        .language_servers_for_buffer(buffer, cx)
 5423                        .filter(|(_, server)| {
 5424                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5425                        })
 5426                        .filter(|(adapter, _)| {
 5427                            scope
 5428                                .as_ref()
 5429                                .map(|scope| scope.language_allowed(&adapter.name))
 5430                                .unwrap_or(true)
 5431                        })
 5432                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5433                        .next()
 5434                })
 5435            })
 5436            .or_else(|| {
 5437                self.upstream_client()
 5438                    .is_some()
 5439                    .then_some(LanguageServerToQuery::FirstCapable)
 5440            })
 5441            .filter(|_| {
 5442                maybe!({
 5443                    let language = buffer.read(cx).language_at(position)?;
 5444                    Some(
 5445                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5446                            .linked_edits,
 5447                    )
 5448                }) == Some(true)
 5449            })
 5450        else {
 5451            return Task::ready(Ok(Vec::new()));
 5452        };
 5453
 5454        self.request_lsp(
 5455            buffer.clone(),
 5456            server_id,
 5457            LinkedEditingRange { position },
 5458            cx,
 5459        )
 5460    }
 5461
 5462    fn apply_on_type_formatting(
 5463        &mut self,
 5464        buffer: Entity<Buffer>,
 5465        position: Anchor,
 5466        trigger: String,
 5467        cx: &mut Context<Self>,
 5468    ) -> Task<Result<Option<Transaction>>> {
 5469        if let Some((client, project_id)) = self.upstream_client() {
 5470            if !self.check_if_capable_for_proto_request(
 5471                &buffer,
 5472                |capabilities| {
 5473                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5474                },
 5475                cx,
 5476            ) {
 5477                return Task::ready(Ok(None));
 5478            }
 5479            let request = proto::OnTypeFormatting {
 5480                project_id,
 5481                buffer_id: buffer.read(cx).remote_id().into(),
 5482                position: Some(serialize_anchor(&position)),
 5483                trigger,
 5484                version: serialize_version(&buffer.read(cx).version()),
 5485            };
 5486            cx.background_spawn(async move {
 5487                client
 5488                    .request(request)
 5489                    .await?
 5490                    .transaction
 5491                    .map(language::proto::deserialize_transaction)
 5492                    .transpose()
 5493            })
 5494        } else if let Some(local) = self.as_local_mut() {
 5495            let buffer_id = buffer.read(cx).remote_id();
 5496            local.buffers_being_formatted.insert(buffer_id);
 5497            cx.spawn(async move |this, cx| {
 5498                let _cleanup = defer({
 5499                    let this = this.clone();
 5500                    let mut cx = cx.clone();
 5501                    move || {
 5502                        this.update(&mut cx, |this, _| {
 5503                            if let Some(local) = this.as_local_mut() {
 5504                                local.buffers_being_formatted.remove(&buffer_id);
 5505                            }
 5506                        })
 5507                        .ok();
 5508                    }
 5509                });
 5510
 5511                buffer
 5512                    .update(cx, |buffer, _| {
 5513                        buffer.wait_for_edits(Some(position.timestamp))
 5514                    })?
 5515                    .await?;
 5516                this.update(cx, |this, cx| {
 5517                    let position = position.to_point_utf16(buffer.read(cx));
 5518                    this.on_type_format(buffer, position, trigger, false, cx)
 5519                })?
 5520                .await
 5521            })
 5522        } else {
 5523            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5524        }
 5525    }
 5526
 5527    pub fn on_type_format<T: ToPointUtf16>(
 5528        &mut self,
 5529        buffer: Entity<Buffer>,
 5530        position: T,
 5531        trigger: String,
 5532        push_to_history: bool,
 5533        cx: &mut Context<Self>,
 5534    ) -> Task<Result<Option<Transaction>>> {
 5535        let position = position.to_point_utf16(buffer.read(cx));
 5536        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5537    }
 5538
 5539    fn on_type_format_impl(
 5540        &mut self,
 5541        buffer: Entity<Buffer>,
 5542        position: PointUtf16,
 5543        trigger: String,
 5544        push_to_history: bool,
 5545        cx: &mut Context<Self>,
 5546    ) -> Task<Result<Option<Transaction>>> {
 5547        let options = buffer.update(cx, |buffer, cx| {
 5548            lsp_command::lsp_formatting_options(
 5549                language_settings(
 5550                    buffer.language_at(position).map(|l| l.name()),
 5551                    buffer.file(),
 5552                    cx,
 5553                )
 5554                .as_ref(),
 5555            )
 5556        });
 5557
 5558        cx.spawn(async move |this, cx| {
 5559            if let Some(waiter) =
 5560                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5561            {
 5562                waiter.await?;
 5563            }
 5564            cx.update(|cx| {
 5565                this.update(cx, |this, cx| {
 5566                    this.request_lsp(
 5567                        buffer.clone(),
 5568                        LanguageServerToQuery::FirstCapable,
 5569                        OnTypeFormatting {
 5570                            position,
 5571                            trigger,
 5572                            options,
 5573                            push_to_history,
 5574                        },
 5575                        cx,
 5576                    )
 5577                })
 5578            })??
 5579            .await
 5580        })
 5581    }
 5582
 5583    pub fn definitions(
 5584        &mut self,
 5585        buffer: &Entity<Buffer>,
 5586        position: PointUtf16,
 5587        cx: &mut Context<Self>,
 5588    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5589        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5590            let request = GetDefinitions { position };
 5591            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5592                return Task::ready(Ok(None));
 5593            }
 5594            let request_task = upstream_client.request_lsp(
 5595                project_id,
 5596                None,
 5597                LSP_REQUEST_TIMEOUT,
 5598                cx.background_executor().clone(),
 5599                request.to_proto(project_id, buffer.read(cx)),
 5600            );
 5601            let buffer = buffer.clone();
 5602            cx.spawn(async move |weak_lsp_store, cx| {
 5603                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5604                    return Ok(None);
 5605                };
 5606                let Some(responses) = request_task.await? else {
 5607                    return Ok(None);
 5608                };
 5609                let actions = join_all(responses.payload.into_iter().map(|response| {
 5610                    GetDefinitions { position }.response_from_proto(
 5611                        response.response,
 5612                        lsp_store.clone(),
 5613                        buffer.clone(),
 5614                        cx.clone(),
 5615                    )
 5616                }))
 5617                .await;
 5618
 5619                Ok(Some(
 5620                    actions
 5621                        .into_iter()
 5622                        .collect::<Result<Vec<Vec<_>>>>()?
 5623                        .into_iter()
 5624                        .flatten()
 5625                        .dedup()
 5626                        .collect(),
 5627                ))
 5628            })
 5629        } else {
 5630            let definitions_task = self.request_multiple_lsp_locally(
 5631                buffer,
 5632                Some(position),
 5633                GetDefinitions { position },
 5634                cx,
 5635            );
 5636            cx.background_spawn(async move {
 5637                Ok(Some(
 5638                    definitions_task
 5639                        .await
 5640                        .into_iter()
 5641                        .flat_map(|(_, definitions)| definitions)
 5642                        .dedup()
 5643                        .collect(),
 5644                ))
 5645            })
 5646        }
 5647    }
 5648
 5649    pub fn declarations(
 5650        &mut self,
 5651        buffer: &Entity<Buffer>,
 5652        position: PointUtf16,
 5653        cx: &mut Context<Self>,
 5654    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5655        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5656            let request = GetDeclarations { position };
 5657            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5658                return Task::ready(Ok(None));
 5659            }
 5660            let request_task = upstream_client.request_lsp(
 5661                project_id,
 5662                None,
 5663                LSP_REQUEST_TIMEOUT,
 5664                cx.background_executor().clone(),
 5665                request.to_proto(project_id, buffer.read(cx)),
 5666            );
 5667            let buffer = buffer.clone();
 5668            cx.spawn(async move |weak_lsp_store, cx| {
 5669                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5670                    return Ok(None);
 5671                };
 5672                let Some(responses) = request_task.await? else {
 5673                    return Ok(None);
 5674                };
 5675                let actions = join_all(responses.payload.into_iter().map(|response| {
 5676                    GetDeclarations { position }.response_from_proto(
 5677                        response.response,
 5678                        lsp_store.clone(),
 5679                        buffer.clone(),
 5680                        cx.clone(),
 5681                    )
 5682                }))
 5683                .await;
 5684
 5685                Ok(Some(
 5686                    actions
 5687                        .into_iter()
 5688                        .collect::<Result<Vec<Vec<_>>>>()?
 5689                        .into_iter()
 5690                        .flatten()
 5691                        .dedup()
 5692                        .collect(),
 5693                ))
 5694            })
 5695        } else {
 5696            let declarations_task = self.request_multiple_lsp_locally(
 5697                buffer,
 5698                Some(position),
 5699                GetDeclarations { position },
 5700                cx,
 5701            );
 5702            cx.background_spawn(async move {
 5703                Ok(Some(
 5704                    declarations_task
 5705                        .await
 5706                        .into_iter()
 5707                        .flat_map(|(_, declarations)| declarations)
 5708                        .dedup()
 5709                        .collect(),
 5710                ))
 5711            })
 5712        }
 5713    }
 5714
 5715    pub fn type_definitions(
 5716        &mut self,
 5717        buffer: &Entity<Buffer>,
 5718        position: PointUtf16,
 5719        cx: &mut Context<Self>,
 5720    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5721        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5722            let request = GetTypeDefinitions { position };
 5723            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5724                return Task::ready(Ok(None));
 5725            }
 5726            let request_task = upstream_client.request_lsp(
 5727                project_id,
 5728                None,
 5729                LSP_REQUEST_TIMEOUT,
 5730                cx.background_executor().clone(),
 5731                request.to_proto(project_id, buffer.read(cx)),
 5732            );
 5733            let buffer = buffer.clone();
 5734            cx.spawn(async move |weak_lsp_store, cx| {
 5735                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5736                    return Ok(None);
 5737                };
 5738                let Some(responses) = request_task.await? else {
 5739                    return Ok(None);
 5740                };
 5741                let actions = join_all(responses.payload.into_iter().map(|response| {
 5742                    GetTypeDefinitions { position }.response_from_proto(
 5743                        response.response,
 5744                        lsp_store.clone(),
 5745                        buffer.clone(),
 5746                        cx.clone(),
 5747                    )
 5748                }))
 5749                .await;
 5750
 5751                Ok(Some(
 5752                    actions
 5753                        .into_iter()
 5754                        .collect::<Result<Vec<Vec<_>>>>()?
 5755                        .into_iter()
 5756                        .flatten()
 5757                        .dedup()
 5758                        .collect(),
 5759                ))
 5760            })
 5761        } else {
 5762            let type_definitions_task = self.request_multiple_lsp_locally(
 5763                buffer,
 5764                Some(position),
 5765                GetTypeDefinitions { position },
 5766                cx,
 5767            );
 5768            cx.background_spawn(async move {
 5769                Ok(Some(
 5770                    type_definitions_task
 5771                        .await
 5772                        .into_iter()
 5773                        .flat_map(|(_, type_definitions)| type_definitions)
 5774                        .dedup()
 5775                        .collect(),
 5776                ))
 5777            })
 5778        }
 5779    }
 5780
 5781    pub fn implementations(
 5782        &mut self,
 5783        buffer: &Entity<Buffer>,
 5784        position: PointUtf16,
 5785        cx: &mut Context<Self>,
 5786    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5787        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5788            let request = GetImplementations { position };
 5789            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5790                return Task::ready(Ok(None));
 5791            }
 5792            let request_task = upstream_client.request_lsp(
 5793                project_id,
 5794                None,
 5795                LSP_REQUEST_TIMEOUT,
 5796                cx.background_executor().clone(),
 5797                request.to_proto(project_id, buffer.read(cx)),
 5798            );
 5799            let buffer = buffer.clone();
 5800            cx.spawn(async move |weak_lsp_store, cx| {
 5801                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5802                    return Ok(None);
 5803                };
 5804                let Some(responses) = request_task.await? else {
 5805                    return Ok(None);
 5806                };
 5807                let actions = join_all(responses.payload.into_iter().map(|response| {
 5808                    GetImplementations { position }.response_from_proto(
 5809                        response.response,
 5810                        lsp_store.clone(),
 5811                        buffer.clone(),
 5812                        cx.clone(),
 5813                    )
 5814                }))
 5815                .await;
 5816
 5817                Ok(Some(
 5818                    actions
 5819                        .into_iter()
 5820                        .collect::<Result<Vec<Vec<_>>>>()?
 5821                        .into_iter()
 5822                        .flatten()
 5823                        .dedup()
 5824                        .collect(),
 5825                ))
 5826            })
 5827        } else {
 5828            let implementations_task = self.request_multiple_lsp_locally(
 5829                buffer,
 5830                Some(position),
 5831                GetImplementations { position },
 5832                cx,
 5833            );
 5834            cx.background_spawn(async move {
 5835                Ok(Some(
 5836                    implementations_task
 5837                        .await
 5838                        .into_iter()
 5839                        .flat_map(|(_, implementations)| implementations)
 5840                        .dedup()
 5841                        .collect(),
 5842                ))
 5843            })
 5844        }
 5845    }
 5846
 5847    pub fn references(
 5848        &mut self,
 5849        buffer: &Entity<Buffer>,
 5850        position: PointUtf16,
 5851        cx: &mut Context<Self>,
 5852    ) -> Task<Result<Option<Vec<Location>>>> {
 5853        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5854            let request = GetReferences { position };
 5855            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5856                return Task::ready(Ok(None));
 5857            }
 5858
 5859            let request_task = upstream_client.request_lsp(
 5860                project_id,
 5861                None,
 5862                LSP_REQUEST_TIMEOUT,
 5863                cx.background_executor().clone(),
 5864                request.to_proto(project_id, buffer.read(cx)),
 5865            );
 5866            let buffer = buffer.clone();
 5867            cx.spawn(async move |weak_lsp_store, cx| {
 5868                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5869                    return Ok(None);
 5870                };
 5871                let Some(responses) = request_task.await? else {
 5872                    return Ok(None);
 5873                };
 5874
 5875                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5876                    GetReferences { position }.response_from_proto(
 5877                        lsp_response.response,
 5878                        lsp_store.clone(),
 5879                        buffer.clone(),
 5880                        cx.clone(),
 5881                    )
 5882                }))
 5883                .await
 5884                .into_iter()
 5885                .collect::<Result<Vec<Vec<_>>>>()?
 5886                .into_iter()
 5887                .flatten()
 5888                .dedup()
 5889                .collect();
 5890                Ok(Some(locations))
 5891            })
 5892        } else {
 5893            let references_task = self.request_multiple_lsp_locally(
 5894                buffer,
 5895                Some(position),
 5896                GetReferences { position },
 5897                cx,
 5898            );
 5899            cx.background_spawn(async move {
 5900                Ok(Some(
 5901                    references_task
 5902                        .await
 5903                        .into_iter()
 5904                        .flat_map(|(_, references)| references)
 5905                        .dedup()
 5906                        .collect(),
 5907                ))
 5908            })
 5909        }
 5910    }
 5911
 5912    pub fn code_actions(
 5913        &mut self,
 5914        buffer: &Entity<Buffer>,
 5915        range: Range<Anchor>,
 5916        kinds: Option<Vec<CodeActionKind>>,
 5917        cx: &mut Context<Self>,
 5918    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5919        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5920            let request = GetCodeActions {
 5921                range: range.clone(),
 5922                kinds: kinds.clone(),
 5923            };
 5924            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5925                return Task::ready(Ok(None));
 5926            }
 5927            let request_task = upstream_client.request_lsp(
 5928                project_id,
 5929                None,
 5930                LSP_REQUEST_TIMEOUT,
 5931                cx.background_executor().clone(),
 5932                request.to_proto(project_id, buffer.read(cx)),
 5933            );
 5934            let buffer = buffer.clone();
 5935            cx.spawn(async move |weak_lsp_store, cx| {
 5936                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5937                    return Ok(None);
 5938                };
 5939                let Some(responses) = request_task.await? else {
 5940                    return Ok(None);
 5941                };
 5942                let actions = join_all(responses.payload.into_iter().map(|response| {
 5943                    GetCodeActions {
 5944                        range: range.clone(),
 5945                        kinds: kinds.clone(),
 5946                    }
 5947                    .response_from_proto(
 5948                        response.response,
 5949                        lsp_store.clone(),
 5950                        buffer.clone(),
 5951                        cx.clone(),
 5952                    )
 5953                }))
 5954                .await;
 5955
 5956                Ok(Some(
 5957                    actions
 5958                        .into_iter()
 5959                        .collect::<Result<Vec<Vec<_>>>>()?
 5960                        .into_iter()
 5961                        .flatten()
 5962                        .collect(),
 5963                ))
 5964            })
 5965        } else {
 5966            let all_actions_task = self.request_multiple_lsp_locally(
 5967                buffer,
 5968                Some(range.start),
 5969                GetCodeActions { range, kinds },
 5970                cx,
 5971            );
 5972            cx.background_spawn(async move {
 5973                Ok(Some(
 5974                    all_actions_task
 5975                        .await
 5976                        .into_iter()
 5977                        .flat_map(|(_, actions)| actions)
 5978                        .collect(),
 5979                ))
 5980            })
 5981        }
 5982    }
 5983
 5984    pub fn code_lens_actions(
 5985        &mut self,
 5986        buffer: &Entity<Buffer>,
 5987        cx: &mut Context<Self>,
 5988    ) -> CodeLensTask {
 5989        let version_queried_for = buffer.read(cx).version();
 5990        let buffer_id = buffer.read(cx).remote_id();
 5991        let existing_servers = self.as_local().map(|local| {
 5992            local
 5993                .buffers_opened_in_servers
 5994                .get(&buffer_id)
 5995                .cloned()
 5996                .unwrap_or_default()
 5997        });
 5998
 5999        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 6000            if let Some(cached_lens) = &lsp_data.code_lens {
 6001                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 6002                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 6003                        existing_servers != cached_lens.lens.keys().copied().collect()
 6004                    });
 6005                    if !has_different_servers {
 6006                        return Task::ready(Ok(Some(
 6007                            cached_lens.lens.values().flatten().cloned().collect(),
 6008                        )))
 6009                        .shared();
 6010                    }
 6011                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 6012                    if !version_queried_for.changed_since(updating_for) {
 6013                        return running_update.clone();
 6014                    }
 6015                }
 6016            }
 6017        }
 6018
 6019        let lens_lsp_data = self
 6020            .latest_lsp_data(buffer, cx)
 6021            .code_lens
 6022            .get_or_insert_default();
 6023        let buffer = buffer.clone();
 6024        let query_version_queried_for = version_queried_for.clone();
 6025        let new_task = cx
 6026            .spawn(async move |lsp_store, cx| {
 6027                cx.background_executor()
 6028                    .timer(Duration::from_millis(30))
 6029                    .await;
 6030                let fetched_lens = lsp_store
 6031                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 6032                    .map_err(Arc::new)?
 6033                    .await
 6034                    .context("fetching code lens")
 6035                    .map_err(Arc::new);
 6036                let fetched_lens = match fetched_lens {
 6037                    Ok(fetched_lens) => fetched_lens,
 6038                    Err(e) => {
 6039                        lsp_store
 6040                            .update(cx, |lsp_store, _| {
 6041                                if let Some(lens_lsp_data) = lsp_store
 6042                                    .lsp_data
 6043                                    .get_mut(&buffer_id)
 6044                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 6045                                {
 6046                                    lens_lsp_data.update = None;
 6047                                }
 6048                            })
 6049                            .ok();
 6050                        return Err(e);
 6051                    }
 6052                };
 6053
 6054                lsp_store
 6055                    .update(cx, |lsp_store, _| {
 6056                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 6057                        let code_lens = lsp_data.code_lens.as_mut()?;
 6058                        if let Some(fetched_lens) = fetched_lens {
 6059                            if lsp_data.buffer_version == query_version_queried_for {
 6060                                code_lens.lens.extend(fetched_lens);
 6061                            } else if !lsp_data
 6062                                .buffer_version
 6063                                .changed_since(&query_version_queried_for)
 6064                            {
 6065                                lsp_data.buffer_version = query_version_queried_for;
 6066                                code_lens.lens = fetched_lens;
 6067                            }
 6068                        }
 6069                        code_lens.update = None;
 6070                        Some(code_lens.lens.values().flatten().cloned().collect())
 6071                    })
 6072                    .map_err(Arc::new)
 6073            })
 6074            .shared();
 6075        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 6076        new_task
 6077    }
 6078
 6079    fn fetch_code_lens(
 6080        &mut self,
 6081        buffer: &Entity<Buffer>,
 6082        cx: &mut Context<Self>,
 6083    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 6084        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6085            let request = GetCodeLens;
 6086            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6087                return Task::ready(Ok(None));
 6088            }
 6089            let request_task = upstream_client.request_lsp(
 6090                project_id,
 6091                None,
 6092                LSP_REQUEST_TIMEOUT,
 6093                cx.background_executor().clone(),
 6094                request.to_proto(project_id, buffer.read(cx)),
 6095            );
 6096            let buffer = buffer.clone();
 6097            cx.spawn(async move |weak_lsp_store, cx| {
 6098                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6099                    return Ok(None);
 6100                };
 6101                let Some(responses) = request_task.await? else {
 6102                    return Ok(None);
 6103                };
 6104
 6105                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 6106                    let lsp_store = lsp_store.clone();
 6107                    let buffer = buffer.clone();
 6108                    let cx = cx.clone();
 6109                    async move {
 6110                        (
 6111                            LanguageServerId::from_proto(response.server_id),
 6112                            GetCodeLens
 6113                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6114                                .await,
 6115                        )
 6116                    }
 6117                }))
 6118                .await;
 6119
 6120                let mut has_errors = false;
 6121                let code_lens_actions = code_lens_actions
 6122                    .into_iter()
 6123                    .filter_map(|(server_id, code_lens)| match code_lens {
 6124                        Ok(code_lens) => Some((server_id, code_lens)),
 6125                        Err(e) => {
 6126                            has_errors = true;
 6127                            log::error!("{e:#}");
 6128                            None
 6129                        }
 6130                    })
 6131                    .collect::<HashMap<_, _>>();
 6132                anyhow::ensure!(
 6133                    !has_errors || !code_lens_actions.is_empty(),
 6134                    "Failed to fetch code lens"
 6135                );
 6136                Ok(Some(code_lens_actions))
 6137            })
 6138        } else {
 6139            let code_lens_actions_task =
 6140                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 6141            cx.background_spawn(async move {
 6142                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 6143            })
 6144        }
 6145    }
 6146
 6147    #[inline(never)]
 6148    pub fn completions(
 6149        &self,
 6150        buffer: &Entity<Buffer>,
 6151        position: PointUtf16,
 6152        context: CompletionContext,
 6153        cx: &mut Context<Self>,
 6154    ) -> Task<Result<Vec<CompletionResponse>>> {
 6155        let language_registry = self.languages.clone();
 6156
 6157        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6158            let snapshot = buffer.read(cx).snapshot();
 6159            let offset = position.to_offset(&snapshot);
 6160            let scope = snapshot.language_scope_at(offset);
 6161            let capable_lsps = self.all_capable_for_proto_request(
 6162                buffer,
 6163                |server_name, capabilities| {
 6164                    capabilities.completion_provider.is_some()
 6165                        && scope
 6166                            .as_ref()
 6167                            .map(|scope| scope.language_allowed(server_name))
 6168                            .unwrap_or(true)
 6169                },
 6170                cx,
 6171            );
 6172            if capable_lsps.is_empty() {
 6173                return Task::ready(Ok(Vec::new()));
 6174            }
 6175
 6176            let language = buffer.read(cx).language().cloned();
 6177
 6178            // In the future, we should provide project guests with the names of LSP adapters,
 6179            // so that they can use the correct LSP adapter when computing labels. For now,
 6180            // guests just use the first LSP adapter associated with the buffer's language.
 6181            let lsp_adapter = language.as_ref().and_then(|language| {
 6182                language_registry
 6183                    .lsp_adapters(&language.name())
 6184                    .first()
 6185                    .cloned()
 6186            });
 6187
 6188            let buffer = buffer.clone();
 6189
 6190            cx.spawn(async move |this, cx| {
 6191                let requests = join_all(
 6192                    capable_lsps
 6193                        .into_iter()
 6194                        .map(|id| {
 6195                            let request = GetCompletions {
 6196                                position,
 6197                                context: context.clone(),
 6198                                server_id: Some(id),
 6199                            };
 6200                            let buffer = buffer.clone();
 6201                            let language = language.clone();
 6202                            let lsp_adapter = lsp_adapter.clone();
 6203                            let upstream_client = upstream_client.clone();
 6204                            let response = this
 6205                                .update(cx, |this, cx| {
 6206                                    this.send_lsp_proto_request(
 6207                                        buffer,
 6208                                        upstream_client,
 6209                                        project_id,
 6210                                        request,
 6211                                        cx,
 6212                                    )
 6213                                })
 6214                                .log_err();
 6215                            async move {
 6216                                let response = response?.await.log_err()?;
 6217
 6218                                let completions = populate_labels_for_completions(
 6219                                    response.completions,
 6220                                    language,
 6221                                    lsp_adapter,
 6222                                )
 6223                                .await;
 6224
 6225                                Some(CompletionResponse {
 6226                                    completions,
 6227                                    display_options: CompletionDisplayOptions::default(),
 6228                                    is_incomplete: response.is_incomplete,
 6229                                })
 6230                            }
 6231                        })
 6232                        .collect::<Vec<_>>(),
 6233                );
 6234                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6235            })
 6236        } else if let Some(local) = self.as_local() {
 6237            let snapshot = buffer.read(cx).snapshot();
 6238            let offset = position.to_offset(&snapshot);
 6239            let scope = snapshot.language_scope_at(offset);
 6240            let language = snapshot.language().cloned();
 6241            let completion_settings = language_settings(
 6242                language.as_ref().map(|language| language.name()),
 6243                buffer.read(cx).file(),
 6244                cx,
 6245            )
 6246            .completions
 6247            .clone();
 6248            if !completion_settings.lsp {
 6249                return Task::ready(Ok(Vec::new()));
 6250            }
 6251
 6252            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6253                local
 6254                    .language_servers_for_buffer(buffer, cx)
 6255                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6256                    .filter(|(adapter, _)| {
 6257                        scope
 6258                            .as_ref()
 6259                            .map(|scope| scope.language_allowed(&adapter.name))
 6260                            .unwrap_or(true)
 6261                    })
 6262                    .map(|(_, server)| server.server_id())
 6263                    .collect()
 6264            });
 6265
 6266            let buffer = buffer.clone();
 6267            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6268            let lsp_timeout = if lsp_timeout > 0 {
 6269                Some(Duration::from_millis(lsp_timeout))
 6270            } else {
 6271                None
 6272            };
 6273            cx.spawn(async move |this,  cx| {
 6274                let mut tasks = Vec::with_capacity(server_ids.len());
 6275                this.update(cx, |lsp_store, cx| {
 6276                    for server_id in server_ids {
 6277                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6278                        let lsp_timeout = lsp_timeout
 6279                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6280                        let mut timeout = cx.background_spawn(async move {
 6281                            match lsp_timeout {
 6282                                Some(lsp_timeout) => {
 6283                                    lsp_timeout.await;
 6284                                    true
 6285                                },
 6286                                None => false,
 6287                            }
 6288                        }).fuse();
 6289                        let mut lsp_request = lsp_store.request_lsp(
 6290                            buffer.clone(),
 6291                            LanguageServerToQuery::Other(server_id),
 6292                            GetCompletions {
 6293                                position,
 6294                                context: context.clone(),
 6295                                server_id: Some(server_id),
 6296                            },
 6297                            cx,
 6298                        ).fuse();
 6299                        let new_task = cx.background_spawn(async move {
 6300                            select_biased! {
 6301                                response = lsp_request => anyhow::Ok(Some(response?)),
 6302                                timeout_happened = timeout => {
 6303                                    if timeout_happened {
 6304                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6305                                        Ok(None)
 6306                                    } else {
 6307                                        let completions = lsp_request.await?;
 6308                                        Ok(Some(completions))
 6309                                    }
 6310                                },
 6311                            }
 6312                        });
 6313                        tasks.push((lsp_adapter, new_task));
 6314                    }
 6315                })?;
 6316
 6317                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6318                    let completion_response = task.await.ok()??;
 6319                    let completions = populate_labels_for_completions(
 6320                            completion_response.completions,
 6321                            language.clone(),
 6322                            lsp_adapter,
 6323                        )
 6324                        .await;
 6325                    Some(CompletionResponse {
 6326                        completions,
 6327                        display_options: CompletionDisplayOptions::default(),
 6328                        is_incomplete: completion_response.is_incomplete,
 6329                    })
 6330                });
 6331
 6332                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6333
 6334                Ok(responses.into_iter().flatten().collect())
 6335            })
 6336        } else {
 6337            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6338        }
 6339    }
 6340
 6341    pub fn resolve_completions(
 6342        &self,
 6343        buffer: Entity<Buffer>,
 6344        completion_indices: Vec<usize>,
 6345        completions: Rc<RefCell<Box<[Completion]>>>,
 6346        cx: &mut Context<Self>,
 6347    ) -> Task<Result<bool>> {
 6348        let client = self.upstream_client();
 6349        let buffer_id = buffer.read(cx).remote_id();
 6350        let buffer_snapshot = buffer.read(cx).snapshot();
 6351
 6352        if !self.check_if_capable_for_proto_request(
 6353            &buffer,
 6354            GetCompletions::can_resolve_completions,
 6355            cx,
 6356        ) {
 6357            return Task::ready(Ok(false));
 6358        }
 6359        cx.spawn(async move |lsp_store, cx| {
 6360            let mut did_resolve = false;
 6361            if let Some((client, project_id)) = client {
 6362                for completion_index in completion_indices {
 6363                    let server_id = {
 6364                        let completion = &completions.borrow()[completion_index];
 6365                        completion.source.server_id()
 6366                    };
 6367                    if let Some(server_id) = server_id {
 6368                        if Self::resolve_completion_remote(
 6369                            project_id,
 6370                            server_id,
 6371                            buffer_id,
 6372                            completions.clone(),
 6373                            completion_index,
 6374                            client.clone(),
 6375                        )
 6376                        .await
 6377                        .log_err()
 6378                        .is_some()
 6379                        {
 6380                            did_resolve = true;
 6381                        }
 6382                    } else {
 6383                        resolve_word_completion(
 6384                            &buffer_snapshot,
 6385                            &mut completions.borrow_mut()[completion_index],
 6386                        );
 6387                    }
 6388                }
 6389            } else {
 6390                for completion_index in completion_indices {
 6391                    let server_id = {
 6392                        let completion = &completions.borrow()[completion_index];
 6393                        completion.source.server_id()
 6394                    };
 6395                    if let Some(server_id) = server_id {
 6396                        let server_and_adapter = lsp_store
 6397                            .read_with(cx, |lsp_store, _| {
 6398                                let server = lsp_store.language_server_for_id(server_id)?;
 6399                                let adapter =
 6400                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6401                                Some((server, adapter))
 6402                            })
 6403                            .ok()
 6404                            .flatten();
 6405                        let Some((server, adapter)) = server_and_adapter else {
 6406                            continue;
 6407                        };
 6408
 6409                        let resolved = Self::resolve_completion_local(
 6410                            server,
 6411                            completions.clone(),
 6412                            completion_index,
 6413                        )
 6414                        .await
 6415                        .log_err()
 6416                        .is_some();
 6417                        if resolved {
 6418                            Self::regenerate_completion_labels(
 6419                                adapter,
 6420                                &buffer_snapshot,
 6421                                completions.clone(),
 6422                                completion_index,
 6423                            )
 6424                            .await
 6425                            .log_err();
 6426                            did_resolve = true;
 6427                        }
 6428                    } else {
 6429                        resolve_word_completion(
 6430                            &buffer_snapshot,
 6431                            &mut completions.borrow_mut()[completion_index],
 6432                        );
 6433                    }
 6434                }
 6435            }
 6436
 6437            Ok(did_resolve)
 6438        })
 6439    }
 6440
 6441    async fn resolve_completion_local(
 6442        server: Arc<lsp::LanguageServer>,
 6443        completions: Rc<RefCell<Box<[Completion]>>>,
 6444        completion_index: usize,
 6445    ) -> Result<()> {
 6446        let server_id = server.server_id();
 6447        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6448            return Ok(());
 6449        }
 6450
 6451        let request = {
 6452            let completion = &completions.borrow()[completion_index];
 6453            match &completion.source {
 6454                CompletionSource::Lsp {
 6455                    lsp_completion,
 6456                    resolved,
 6457                    server_id: completion_server_id,
 6458                    ..
 6459                } => {
 6460                    if *resolved {
 6461                        return Ok(());
 6462                    }
 6463                    anyhow::ensure!(
 6464                        server_id == *completion_server_id,
 6465                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6466                    );
 6467                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6468                }
 6469                CompletionSource::BufferWord { .. }
 6470                | CompletionSource::Dap { .. }
 6471                | CompletionSource::Custom => {
 6472                    return Ok(());
 6473                }
 6474            }
 6475        };
 6476        let resolved_completion = request
 6477            .await
 6478            .into_response()
 6479            .context("resolve completion")?;
 6480
 6481        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6482        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6483
 6484        let mut completions = completions.borrow_mut();
 6485        let completion = &mut completions[completion_index];
 6486        if let CompletionSource::Lsp {
 6487            lsp_completion,
 6488            resolved,
 6489            server_id: completion_server_id,
 6490            ..
 6491        } = &mut completion.source
 6492        {
 6493            if *resolved {
 6494                return Ok(());
 6495            }
 6496            anyhow::ensure!(
 6497                server_id == *completion_server_id,
 6498                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6499            );
 6500            **lsp_completion = resolved_completion;
 6501            *resolved = true;
 6502        }
 6503        Ok(())
 6504    }
 6505
 6506    async fn regenerate_completion_labels(
 6507        adapter: Arc<CachedLspAdapter>,
 6508        snapshot: &BufferSnapshot,
 6509        completions: Rc<RefCell<Box<[Completion]>>>,
 6510        completion_index: usize,
 6511    ) -> Result<()> {
 6512        let completion_item = completions.borrow()[completion_index]
 6513            .source
 6514            .lsp_completion(true)
 6515            .map(Cow::into_owned);
 6516        if let Some(lsp_documentation) = completion_item
 6517            .as_ref()
 6518            .and_then(|completion_item| completion_item.documentation.clone())
 6519        {
 6520            let mut completions = completions.borrow_mut();
 6521            let completion = &mut completions[completion_index];
 6522            completion.documentation = Some(lsp_documentation.into());
 6523        } else {
 6524            let mut completions = completions.borrow_mut();
 6525            let completion = &mut completions[completion_index];
 6526            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6527        }
 6528
 6529        let mut new_label = match completion_item {
 6530            Some(completion_item) => {
 6531                // 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
 6532                // So we have to update the label here anyway...
 6533                let language = snapshot.language();
 6534                match language {
 6535                    Some(language) => {
 6536                        adapter
 6537                            .labels_for_completions(
 6538                                std::slice::from_ref(&completion_item),
 6539                                language,
 6540                            )
 6541                            .await?
 6542                    }
 6543                    None => Vec::new(),
 6544                }
 6545                .pop()
 6546                .flatten()
 6547                .unwrap_or_else(|| {
 6548                    CodeLabel::fallback_for_completion(
 6549                        &completion_item,
 6550                        language.map(|language| language.as_ref()),
 6551                    )
 6552                })
 6553            }
 6554            None => CodeLabel::plain(
 6555                completions.borrow()[completion_index].new_text.clone(),
 6556                None,
 6557            ),
 6558        };
 6559        ensure_uniform_list_compatible_label(&mut new_label);
 6560
 6561        let mut completions = completions.borrow_mut();
 6562        let completion = &mut completions[completion_index];
 6563        if completion.label.filter_text() == new_label.filter_text() {
 6564            completion.label = new_label;
 6565        } else {
 6566            log::error!(
 6567                "Resolved completion changed display label from {} to {}. \
 6568                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6569                completion.label.text(),
 6570                new_label.text(),
 6571                completion.label.filter_text(),
 6572                new_label.filter_text()
 6573            );
 6574        }
 6575
 6576        Ok(())
 6577    }
 6578
 6579    async fn resolve_completion_remote(
 6580        project_id: u64,
 6581        server_id: LanguageServerId,
 6582        buffer_id: BufferId,
 6583        completions: Rc<RefCell<Box<[Completion]>>>,
 6584        completion_index: usize,
 6585        client: AnyProtoClient,
 6586    ) -> Result<()> {
 6587        let lsp_completion = {
 6588            let completion = &completions.borrow()[completion_index];
 6589            match &completion.source {
 6590                CompletionSource::Lsp {
 6591                    lsp_completion,
 6592                    resolved,
 6593                    server_id: completion_server_id,
 6594                    ..
 6595                } => {
 6596                    anyhow::ensure!(
 6597                        server_id == *completion_server_id,
 6598                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6599                    );
 6600                    if *resolved {
 6601                        return Ok(());
 6602                    }
 6603                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6604                }
 6605                CompletionSource::Custom
 6606                | CompletionSource::Dap { .. }
 6607                | CompletionSource::BufferWord { .. } => {
 6608                    return Ok(());
 6609                }
 6610            }
 6611        };
 6612        let request = proto::ResolveCompletionDocumentation {
 6613            project_id,
 6614            language_server_id: server_id.0 as u64,
 6615            lsp_completion,
 6616            buffer_id: buffer_id.into(),
 6617        };
 6618
 6619        let response = client
 6620            .request(request)
 6621            .await
 6622            .context("completion documentation resolve proto request")?;
 6623        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6624
 6625        let documentation = if response.documentation.is_empty() {
 6626            CompletionDocumentation::Undocumented
 6627        } else if response.documentation_is_markdown {
 6628            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6629        } else if response.documentation.lines().count() <= 1 {
 6630            CompletionDocumentation::SingleLine(response.documentation.into())
 6631        } else {
 6632            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6633        };
 6634
 6635        let mut completions = completions.borrow_mut();
 6636        let completion = &mut completions[completion_index];
 6637        completion.documentation = Some(documentation);
 6638        if let CompletionSource::Lsp {
 6639            insert_range,
 6640            lsp_completion,
 6641            resolved,
 6642            server_id: completion_server_id,
 6643            lsp_defaults: _,
 6644        } = &mut completion.source
 6645        {
 6646            let completion_insert_range = response
 6647                .old_insert_start
 6648                .and_then(deserialize_anchor)
 6649                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6650            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6651
 6652            if *resolved {
 6653                return Ok(());
 6654            }
 6655            anyhow::ensure!(
 6656                server_id == *completion_server_id,
 6657                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6658            );
 6659            **lsp_completion = resolved_lsp_completion;
 6660            *resolved = true;
 6661        }
 6662
 6663        let replace_range = response
 6664            .old_replace_start
 6665            .and_then(deserialize_anchor)
 6666            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6667        if let Some((old_replace_start, old_replace_end)) = replace_range
 6668            && !response.new_text.is_empty()
 6669        {
 6670            completion.new_text = response.new_text;
 6671            completion.replace_range = old_replace_start..old_replace_end;
 6672        }
 6673
 6674        Ok(())
 6675    }
 6676
 6677    pub fn apply_additional_edits_for_completion(
 6678        &self,
 6679        buffer_handle: Entity<Buffer>,
 6680        completions: Rc<RefCell<Box<[Completion]>>>,
 6681        completion_index: usize,
 6682        push_to_history: bool,
 6683        cx: &mut Context<Self>,
 6684    ) -> Task<Result<Option<Transaction>>> {
 6685        if let Some((client, project_id)) = self.upstream_client() {
 6686            let buffer = buffer_handle.read(cx);
 6687            let buffer_id = buffer.remote_id();
 6688            cx.spawn(async move |_, cx| {
 6689                let request = {
 6690                    let completion = completions.borrow()[completion_index].clone();
 6691                    proto::ApplyCompletionAdditionalEdits {
 6692                        project_id,
 6693                        buffer_id: buffer_id.into(),
 6694                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6695                            replace_range: completion.replace_range,
 6696                            new_text: completion.new_text,
 6697                            source: completion.source,
 6698                        })),
 6699                    }
 6700                };
 6701
 6702                if let Some(transaction) = client.request(request).await?.transaction {
 6703                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6704                    buffer_handle
 6705                        .update(cx, |buffer, _| {
 6706                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6707                        })?
 6708                        .await?;
 6709                    if push_to_history {
 6710                        buffer_handle.update(cx, |buffer, _| {
 6711                            buffer.push_transaction(transaction.clone(), Instant::now());
 6712                            buffer.finalize_last_transaction();
 6713                        })?;
 6714                    }
 6715                    Ok(Some(transaction))
 6716                } else {
 6717                    Ok(None)
 6718                }
 6719            })
 6720        } else {
 6721            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6722                let completion = &completions.borrow()[completion_index];
 6723                let server_id = completion.source.server_id()?;
 6724                Some(
 6725                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6726                        .1
 6727                        .clone(),
 6728                )
 6729            }) else {
 6730                return Task::ready(Ok(None));
 6731            };
 6732
 6733            cx.spawn(async move |this, cx| {
 6734                Self::resolve_completion_local(
 6735                    server.clone(),
 6736                    completions.clone(),
 6737                    completion_index,
 6738                )
 6739                .await
 6740                .context("resolving completion")?;
 6741                let completion = completions.borrow()[completion_index].clone();
 6742                let additional_text_edits = completion
 6743                    .source
 6744                    .lsp_completion(true)
 6745                    .as_ref()
 6746                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6747                if let Some(edits) = additional_text_edits {
 6748                    let edits = this
 6749                        .update(cx, |this, cx| {
 6750                            this.as_local_mut().unwrap().edits_from_lsp(
 6751                                &buffer_handle,
 6752                                edits,
 6753                                server.server_id(),
 6754                                None,
 6755                                cx,
 6756                            )
 6757                        })?
 6758                        .await?;
 6759
 6760                    buffer_handle.update(cx, |buffer, cx| {
 6761                        buffer.finalize_last_transaction();
 6762                        buffer.start_transaction();
 6763
 6764                        for (range, text) in edits {
 6765                            let primary = &completion.replace_range;
 6766
 6767                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6768                            // and the primary completion is just an insertion (empty range), then this is likely
 6769                            // an auto-import scenario and should not be considered overlapping
 6770                            // https://github.com/zed-industries/zed/issues/26136
 6771                            let is_file_start_auto_import = {
 6772                                let snapshot = buffer.snapshot();
 6773                                let primary_start_point = primary.start.to_point(&snapshot);
 6774                                let range_start_point = range.start.to_point(&snapshot);
 6775
 6776                                let result = primary_start_point.row == 0
 6777                                    && primary_start_point.column == 0
 6778                                    && range_start_point.row == 0
 6779                                    && range_start_point.column == 0;
 6780
 6781                                result
 6782                            };
 6783
 6784                            let has_overlap = if is_file_start_auto_import {
 6785                                false
 6786                            } else {
 6787                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6788                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6789                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6790                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6791                                let result = start_within || end_within;
 6792                                result
 6793                            };
 6794
 6795                            //Skip additional edits which overlap with the primary completion edit
 6796                            //https://github.com/zed-industries/zed/pull/1871
 6797                            if !has_overlap {
 6798                                buffer.edit([(range, text)], None, cx);
 6799                            }
 6800                        }
 6801
 6802                        let transaction = if buffer.end_transaction(cx).is_some() {
 6803                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6804                            if !push_to_history {
 6805                                buffer.forget_transaction(transaction.id);
 6806                            }
 6807                            Some(transaction)
 6808                        } else {
 6809                            None
 6810                        };
 6811                        Ok(transaction)
 6812                    })?
 6813                } else {
 6814                    Ok(None)
 6815                }
 6816            })
 6817        }
 6818    }
 6819
 6820    pub fn pull_diagnostics(
 6821        &mut self,
 6822        buffer: Entity<Buffer>,
 6823        cx: &mut Context<Self>,
 6824    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6825        let buffer_id = buffer.read(cx).remote_id();
 6826
 6827        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6828            let mut suitable_capabilities = None;
 6829            // Are we capable for proto request?
 6830            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6831                &buffer,
 6832                |capabilities| {
 6833                    if let Some(caps) = &capabilities.diagnostic_provider {
 6834                        suitable_capabilities = Some(caps.clone());
 6835                        true
 6836                    } else {
 6837                        false
 6838                    }
 6839                },
 6840                cx,
 6841            );
 6842            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6843            let Some(dynamic_caps) = suitable_capabilities else {
 6844                return Task::ready(Ok(None));
 6845            };
 6846            assert!(any_server_has_diagnostics_provider);
 6847
 6848            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6849            let request = GetDocumentDiagnostics {
 6850                previous_result_id: None,
 6851                identifier,
 6852                registration_id: None,
 6853            };
 6854            let request_task = client.request_lsp(
 6855                upstream_project_id,
 6856                None,
 6857                LSP_REQUEST_TIMEOUT,
 6858                cx.background_executor().clone(),
 6859                request.to_proto(upstream_project_id, buffer.read(cx)),
 6860            );
 6861            cx.background_spawn(async move {
 6862                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6863                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6864                // Do not attempt to further process the dummy responses here.
 6865                let _response = request_task.await?;
 6866                Ok(None)
 6867            })
 6868        } else {
 6869            let servers = buffer.update(cx, |buffer, cx| {
 6870                self.running_language_servers_for_local_buffer(buffer, cx)
 6871                    .map(|(_, server)| server.clone())
 6872                    .collect::<Vec<_>>()
 6873            });
 6874
 6875            let pull_diagnostics = servers
 6876                .into_iter()
 6877                .flat_map(|server| {
 6878                    let result = maybe!({
 6879                        let local = self.as_local()?;
 6880                        let server_id = server.server_id();
 6881                        let providers_with_identifiers = local
 6882                            .language_server_dynamic_registrations
 6883                            .get(&server_id)
 6884                            .into_iter()
 6885                            .flat_map(|registrations| registrations.diagnostics.clone())
 6886                            .collect::<Vec<_>>();
 6887                        Some(
 6888                            providers_with_identifiers
 6889                                .into_iter()
 6890                                .map(|(registration_id, dynamic_caps)| {
 6891                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6892                                    let registration_id = registration_id.map(SharedString::from);
 6893                                    let result_id = self.result_id_for_buffer_pull(
 6894                                        server_id,
 6895                                        buffer_id,
 6896                                        &registration_id,
 6897                                        cx,
 6898                                    );
 6899                                    self.request_lsp(
 6900                                        buffer.clone(),
 6901                                        LanguageServerToQuery::Other(server_id),
 6902                                        GetDocumentDiagnostics {
 6903                                            previous_result_id: result_id,
 6904                                            registration_id,
 6905                                            identifier,
 6906                                        },
 6907                                        cx,
 6908                                    )
 6909                                })
 6910                                .collect::<Vec<_>>(),
 6911                        )
 6912                    });
 6913
 6914                    result.unwrap_or_default()
 6915                })
 6916                .collect::<Vec<_>>();
 6917
 6918            cx.background_spawn(async move {
 6919                let mut responses = Vec::new();
 6920                for diagnostics in join_all(pull_diagnostics).await {
 6921                    responses.extend(diagnostics?);
 6922                }
 6923                Ok(Some(responses))
 6924            })
 6925        }
 6926    }
 6927
 6928    pub fn applicable_inlay_chunks(
 6929        &mut self,
 6930        buffer: &Entity<Buffer>,
 6931        ranges: &[Range<text::Anchor>],
 6932        cx: &mut Context<Self>,
 6933    ) -> Vec<Range<BufferRow>> {
 6934        let buffer_snapshot = buffer.read(cx).snapshot();
 6935        let ranges = ranges
 6936            .iter()
 6937            .map(|range| range.to_point(&buffer_snapshot))
 6938            .collect::<Vec<_>>();
 6939
 6940        self.latest_lsp_data(buffer, cx)
 6941            .inlay_hints
 6942            .applicable_chunks(ranges.as_slice())
 6943            .map(|chunk| chunk.row_range())
 6944            .collect()
 6945    }
 6946
 6947    pub fn invalidate_inlay_hints<'a>(
 6948        &'a mut self,
 6949        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6950    ) {
 6951        for buffer_id in for_buffers {
 6952            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6953                lsp_data.inlay_hints.clear();
 6954            }
 6955        }
 6956    }
 6957
 6958    pub fn inlay_hints(
 6959        &mut self,
 6960        invalidate: InvalidationStrategy,
 6961        buffer: Entity<Buffer>,
 6962        ranges: Vec<Range<text::Anchor>>,
 6963        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6964        cx: &mut Context<Self>,
 6965    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6966        let next_hint_id = self.next_hint_id.clone();
 6967        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6968        let query_version = lsp_data.buffer_version.clone();
 6969        let mut lsp_refresh_requested = false;
 6970        let for_server = if let InvalidationStrategy::RefreshRequested {
 6971            server_id,
 6972            request_id,
 6973        } = invalidate
 6974        {
 6975            let invalidated = lsp_data
 6976                .inlay_hints
 6977                .invalidate_for_server_refresh(server_id, request_id);
 6978            lsp_refresh_requested = invalidated;
 6979            Some(server_id)
 6980        } else {
 6981            None
 6982        };
 6983        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6984        let known_chunks = known_chunks
 6985            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6986            .map(|(_, known_chunks)| known_chunks)
 6987            .unwrap_or_default();
 6988
 6989        let buffer_snapshot = buffer.read(cx).snapshot();
 6990        let ranges = ranges
 6991            .iter()
 6992            .map(|range| range.to_point(&buffer_snapshot))
 6993            .collect::<Vec<_>>();
 6994
 6995        let mut hint_fetch_tasks = Vec::new();
 6996        let mut cached_inlay_hints = None;
 6997        let mut ranges_to_query = None;
 6998        let applicable_chunks = existing_inlay_hints
 6999            .applicable_chunks(ranges.as_slice())
 7000            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7001            .collect::<Vec<_>>();
 7002        if applicable_chunks.is_empty() {
 7003            return HashMap::default();
 7004        }
 7005
 7006        for row_chunk in applicable_chunks {
 7007            match (
 7008                existing_inlay_hints
 7009                    .cached_hints(&row_chunk)
 7010                    .filter(|_| !lsp_refresh_requested)
 7011                    .cloned(),
 7012                existing_inlay_hints
 7013                    .fetched_hints(&row_chunk)
 7014                    .as_ref()
 7015                    .filter(|_| !lsp_refresh_requested)
 7016                    .cloned(),
 7017            ) {
 7018                (None, None) => {
 7019                    let chunk_range = row_chunk.anchor_range();
 7020                    ranges_to_query
 7021                        .get_or_insert_with(Vec::new)
 7022                        .push((row_chunk, chunk_range));
 7023                }
 7024                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7025                (Some(cached_hints), None) => {
 7026                    for (server_id, cached_hints) in cached_hints {
 7027                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7028                            cached_inlay_hints
 7029                                .get_or_insert_with(HashMap::default)
 7030                                .entry(row_chunk.row_range())
 7031                                .or_insert_with(HashMap::default)
 7032                                .entry(server_id)
 7033                                .or_insert_with(Vec::new)
 7034                                .extend(cached_hints);
 7035                        }
 7036                    }
 7037                }
 7038                (Some(cached_hints), Some(fetched_hints)) => {
 7039                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7040                    for (server_id, cached_hints) in cached_hints {
 7041                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7042                            cached_inlay_hints
 7043                                .get_or_insert_with(HashMap::default)
 7044                                .entry(row_chunk.row_range())
 7045                                .or_insert_with(HashMap::default)
 7046                                .entry(server_id)
 7047                                .or_insert_with(Vec::new)
 7048                                .extend(cached_hints);
 7049                        }
 7050                    }
 7051                }
 7052            }
 7053        }
 7054
 7055        if hint_fetch_tasks.is_empty()
 7056            && ranges_to_query
 7057                .as_ref()
 7058                .is_none_or(|ranges| ranges.is_empty())
 7059            && let Some(cached_inlay_hints) = cached_inlay_hints
 7060        {
 7061            cached_inlay_hints
 7062                .into_iter()
 7063                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7064                .collect()
 7065        } else {
 7066            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7067                let next_hint_id = next_hint_id.clone();
 7068                let buffer = buffer.clone();
 7069                let query_version = query_version.clone();
 7070                let new_inlay_hints = cx
 7071                    .spawn(async move |lsp_store, cx| {
 7072                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7073                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7074                        })?;
 7075                        new_fetch_task
 7076                            .await
 7077                            .and_then(|new_hints_by_server| {
 7078                                lsp_store.update(cx, |lsp_store, cx| {
 7079                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7080                                    let update_cache = lsp_data.buffer_version == query_version;
 7081                                    if new_hints_by_server.is_empty() {
 7082                                        if update_cache {
 7083                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7084                                        }
 7085                                        HashMap::default()
 7086                                    } else {
 7087                                        new_hints_by_server
 7088                                            .into_iter()
 7089                                            .map(|(server_id, new_hints)| {
 7090                                                let new_hints = new_hints
 7091                                                    .into_iter()
 7092                                                    .map(|new_hint| {
 7093                                                        (
 7094                                                            InlayId::Hint(next_hint_id.fetch_add(
 7095                                                                1,
 7096                                                                atomic::Ordering::AcqRel,
 7097                                                            )),
 7098                                                            new_hint,
 7099                                                        )
 7100                                                    })
 7101                                                    .collect::<Vec<_>>();
 7102                                                if update_cache {
 7103                                                    lsp_data.inlay_hints.insert_new_hints(
 7104                                                        chunk,
 7105                                                        server_id,
 7106                                                        new_hints.clone(),
 7107                                                    );
 7108                                                }
 7109                                                (server_id, new_hints)
 7110                                            })
 7111                                            .collect()
 7112                                    }
 7113                                })
 7114                            })
 7115                            .map_err(Arc::new)
 7116                    })
 7117                    .shared();
 7118
 7119                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7120                *fetch_task = Some(new_inlay_hints.clone());
 7121                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7122            }
 7123
 7124            cached_inlay_hints
 7125                .unwrap_or_default()
 7126                .into_iter()
 7127                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7128                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7129                    (
 7130                        chunk.row_range(),
 7131                        cx.spawn(async move |_, _| {
 7132                            hints_fetch.await.map_err(|e| {
 7133                                if e.error_code() != ErrorCode::Internal {
 7134                                    anyhow!(e.error_code())
 7135                                } else {
 7136                                    anyhow!("{e:#}")
 7137                                }
 7138                            })
 7139                        }),
 7140                    )
 7141                }))
 7142                .collect()
 7143        }
 7144    }
 7145
 7146    fn fetch_inlay_hints(
 7147        &mut self,
 7148        for_server: Option<LanguageServerId>,
 7149        buffer: &Entity<Buffer>,
 7150        range: Range<Anchor>,
 7151        cx: &mut Context<Self>,
 7152    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7153        let request = InlayHints {
 7154            range: range.clone(),
 7155        };
 7156        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7157            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7158                return Task::ready(Ok(HashMap::default()));
 7159            }
 7160            let request_task = upstream_client.request_lsp(
 7161                project_id,
 7162                for_server.map(|id| id.to_proto()),
 7163                LSP_REQUEST_TIMEOUT,
 7164                cx.background_executor().clone(),
 7165                request.to_proto(project_id, buffer.read(cx)),
 7166            );
 7167            let buffer = buffer.clone();
 7168            cx.spawn(async move |weak_lsp_store, cx| {
 7169                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7170                    return Ok(HashMap::default());
 7171                };
 7172                let Some(responses) = request_task.await? else {
 7173                    return Ok(HashMap::default());
 7174                };
 7175
 7176                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7177                    let lsp_store = lsp_store.clone();
 7178                    let buffer = buffer.clone();
 7179                    let cx = cx.clone();
 7180                    let request = request.clone();
 7181                    async move {
 7182                        (
 7183                            LanguageServerId::from_proto(response.server_id),
 7184                            request
 7185                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7186                                .await,
 7187                        )
 7188                    }
 7189                }))
 7190                .await;
 7191
 7192                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot())?;
 7193                let mut has_errors = false;
 7194                let inlay_hints = inlay_hints
 7195                    .into_iter()
 7196                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7197                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7198                        Err(e) => {
 7199                            has_errors = true;
 7200                            log::error!("{e:#}");
 7201                            None
 7202                        }
 7203                    })
 7204                    .map(|(server_id, mut new_hints)| {
 7205                        new_hints.retain(|hint| {
 7206                            hint.position.is_valid(&buffer_snapshot)
 7207                                && range.start.is_valid(&buffer_snapshot)
 7208                                && range.end.is_valid(&buffer_snapshot)
 7209                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7210                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7211                        });
 7212                        (server_id, new_hints)
 7213                    })
 7214                    .collect::<HashMap<_, _>>();
 7215                anyhow::ensure!(
 7216                    !has_errors || !inlay_hints.is_empty(),
 7217                    "Failed to fetch inlay hints"
 7218                );
 7219                Ok(inlay_hints)
 7220            })
 7221        } else {
 7222            let inlay_hints_task = match for_server {
 7223                Some(server_id) => {
 7224                    let server_task = self.request_lsp(
 7225                        buffer.clone(),
 7226                        LanguageServerToQuery::Other(server_id),
 7227                        request,
 7228                        cx,
 7229                    );
 7230                    cx.background_spawn(async move {
 7231                        let mut responses = Vec::new();
 7232                        match server_task.await {
 7233                            Ok(response) => responses.push((server_id, response)),
 7234                            // rust-analyzer likes to error with this when its still loading up
 7235                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7236                            Err(e) => log::error!(
 7237                                "Error handling response for inlay hints request: {e:#}"
 7238                            ),
 7239                        }
 7240                        responses
 7241                    })
 7242                }
 7243                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7244            };
 7245            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7246            cx.background_spawn(async move {
 7247                Ok(inlay_hints_task
 7248                    .await
 7249                    .into_iter()
 7250                    .map(|(server_id, mut new_hints)| {
 7251                        new_hints.retain(|hint| {
 7252                            hint.position.is_valid(&buffer_snapshot)
 7253                                && range.start.is_valid(&buffer_snapshot)
 7254                                && range.end.is_valid(&buffer_snapshot)
 7255                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7256                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7257                        });
 7258                        (server_id, new_hints)
 7259                    })
 7260                    .collect())
 7261            })
 7262        }
 7263    }
 7264
 7265    pub fn pull_diagnostics_for_buffer(
 7266        &mut self,
 7267        buffer: Entity<Buffer>,
 7268        cx: &mut Context<Self>,
 7269    ) -> Task<anyhow::Result<()>> {
 7270        let diagnostics = self.pull_diagnostics(buffer, cx);
 7271        cx.spawn(async move |lsp_store, cx| {
 7272            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7273                return Ok(());
 7274            };
 7275            lsp_store.update(cx, |lsp_store, cx| {
 7276                if lsp_store.as_local().is_none() {
 7277                    return;
 7278                }
 7279
 7280                let mut unchanged_buffers = HashMap::default();
 7281                let server_diagnostics_updates = diagnostics
 7282                    .into_iter()
 7283                    .filter_map(|diagnostics_set| match diagnostics_set {
 7284                        LspPullDiagnostics::Response {
 7285                            server_id,
 7286                            uri,
 7287                            diagnostics,
 7288                            registration_id,
 7289                        } => Some((server_id, uri, diagnostics, registration_id)),
 7290                        LspPullDiagnostics::Default => None,
 7291                    })
 7292                    .fold(
 7293                        HashMap::default(),
 7294                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7295                            let (result_id, diagnostics) = match diagnostics {
 7296                                PulledDiagnostics::Unchanged { result_id } => {
 7297                                    unchanged_buffers
 7298                                        .entry(new_registration_id.clone())
 7299                                        .or_insert_with(HashSet::default)
 7300                                        .insert(uri.clone());
 7301                                    (Some(result_id), Vec::new())
 7302                                }
 7303                                PulledDiagnostics::Changed {
 7304                                    result_id,
 7305                                    diagnostics,
 7306                                } => (result_id, diagnostics),
 7307                            };
 7308                            let disk_based_sources = Cow::Owned(
 7309                                lsp_store
 7310                                    .language_server_adapter_for_id(server_id)
 7311                                    .as_ref()
 7312                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7313                                    .unwrap_or(&[])
 7314                                    .to_vec(),
 7315                            );
 7316                            acc.entry(server_id)
 7317                                .or_insert_with(HashMap::default)
 7318                                .entry(new_registration_id.clone())
 7319                                .or_insert_with(Vec::new)
 7320                                .push(DocumentDiagnosticsUpdate {
 7321                                    server_id,
 7322                                    diagnostics: lsp::PublishDiagnosticsParams {
 7323                                        uri,
 7324                                        diagnostics,
 7325                                        version: None,
 7326                                    },
 7327                                    result_id,
 7328                                    disk_based_sources,
 7329                                    registration_id: new_registration_id,
 7330                                });
 7331                            acc
 7332                        },
 7333                    );
 7334
 7335                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7336                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7337                        lsp_store
 7338                            .merge_lsp_diagnostics(
 7339                                DiagnosticSourceKind::Pulled,
 7340                                diagnostic_updates,
 7341                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7342                                    DiagnosticSourceKind::Pulled => {
 7343                                        old_diagnostic.registration_id != registration_id
 7344                                            || unchanged_buffers
 7345                                                .get(&old_diagnostic.registration_id)
 7346                                                .is_some_and(|unchanged_buffers| {
 7347                                                    unchanged_buffers.contains(&document_uri)
 7348                                                })
 7349                                    }
 7350                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7351                                        true
 7352                                    }
 7353                                },
 7354                                cx,
 7355                            )
 7356                            .log_err();
 7357                    }
 7358                }
 7359            })
 7360        })
 7361    }
 7362
 7363    pub fn document_colors(
 7364        &mut self,
 7365        known_cache_version: Option<usize>,
 7366        buffer: Entity<Buffer>,
 7367        cx: &mut Context<Self>,
 7368    ) -> Option<DocumentColorTask> {
 7369        let version_queried_for = buffer.read(cx).version();
 7370        let buffer_id = buffer.read(cx).remote_id();
 7371
 7372        let current_language_servers = self.as_local().map(|local| {
 7373            local
 7374                .buffers_opened_in_servers
 7375                .get(&buffer_id)
 7376                .cloned()
 7377                .unwrap_or_default()
 7378        });
 7379
 7380        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7381            if let Some(cached_colors) = &lsp_data.document_colors {
 7382                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7383                    let has_different_servers =
 7384                        current_language_servers.is_some_and(|current_language_servers| {
 7385                            current_language_servers
 7386                                != cached_colors.colors.keys().copied().collect()
 7387                        });
 7388                    if !has_different_servers {
 7389                        let cache_version = cached_colors.cache_version;
 7390                        if Some(cache_version) == known_cache_version {
 7391                            return None;
 7392                        } else {
 7393                            return Some(
 7394                                Task::ready(Ok(DocumentColors {
 7395                                    colors: cached_colors
 7396                                        .colors
 7397                                        .values()
 7398                                        .flatten()
 7399                                        .cloned()
 7400                                        .collect(),
 7401                                    cache_version: Some(cache_version),
 7402                                }))
 7403                                .shared(),
 7404                            );
 7405                        }
 7406                    }
 7407                }
 7408            }
 7409        }
 7410
 7411        let color_lsp_data = self
 7412            .latest_lsp_data(&buffer, cx)
 7413            .document_colors
 7414            .get_or_insert_default();
 7415        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7416            && !version_queried_for.changed_since(updating_for)
 7417        {
 7418            return Some(running_update.clone());
 7419        }
 7420        let buffer_version_queried_for = version_queried_for.clone();
 7421        let new_task = cx
 7422            .spawn(async move |lsp_store, cx| {
 7423                cx.background_executor()
 7424                    .timer(Duration::from_millis(30))
 7425                    .await;
 7426                let fetched_colors = lsp_store
 7427                    .update(cx, |lsp_store, cx| {
 7428                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7429                    })?
 7430                    .await
 7431                    .context("fetching document colors")
 7432                    .map_err(Arc::new);
 7433                let fetched_colors = match fetched_colors {
 7434                    Ok(fetched_colors) => {
 7435                        if Some(true)
 7436                            == buffer
 7437                                .update(cx, |buffer, _| {
 7438                                    buffer.version() != buffer_version_queried_for
 7439                                })
 7440                                .ok()
 7441                        {
 7442                            return Ok(DocumentColors::default());
 7443                        }
 7444                        fetched_colors
 7445                    }
 7446                    Err(e) => {
 7447                        lsp_store
 7448                            .update(cx, |lsp_store, _| {
 7449                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7450                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7451                                        document_colors.colors_update = None;
 7452                                    }
 7453                                }
 7454                            })
 7455                            .ok();
 7456                        return Err(e);
 7457                    }
 7458                };
 7459
 7460                lsp_store
 7461                    .update(cx, |lsp_store, cx| {
 7462                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7463                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7464
 7465                        if let Some(fetched_colors) = fetched_colors {
 7466                            if lsp_data.buffer_version == buffer_version_queried_for {
 7467                                lsp_colors.colors.extend(fetched_colors);
 7468                                lsp_colors.cache_version += 1;
 7469                            } else if !lsp_data
 7470                                .buffer_version
 7471                                .changed_since(&buffer_version_queried_for)
 7472                            {
 7473                                lsp_data.buffer_version = buffer_version_queried_for;
 7474                                lsp_colors.colors = fetched_colors;
 7475                                lsp_colors.cache_version += 1;
 7476                            }
 7477                        }
 7478                        lsp_colors.colors_update = None;
 7479                        let colors = lsp_colors
 7480                            .colors
 7481                            .values()
 7482                            .flatten()
 7483                            .cloned()
 7484                            .collect::<HashSet<_>>();
 7485                        DocumentColors {
 7486                            colors,
 7487                            cache_version: Some(lsp_colors.cache_version),
 7488                        }
 7489                    })
 7490                    .map_err(Arc::new)
 7491            })
 7492            .shared();
 7493        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7494        Some(new_task)
 7495    }
 7496
 7497    fn fetch_document_colors_for_buffer(
 7498        &mut self,
 7499        buffer: &Entity<Buffer>,
 7500        cx: &mut Context<Self>,
 7501    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7502        if let Some((client, project_id)) = self.upstream_client() {
 7503            let request = GetDocumentColor {};
 7504            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7505                return Task::ready(Ok(None));
 7506            }
 7507
 7508            let request_task = client.request_lsp(
 7509                project_id,
 7510                None,
 7511                LSP_REQUEST_TIMEOUT,
 7512                cx.background_executor().clone(),
 7513                request.to_proto(project_id, buffer.read(cx)),
 7514            );
 7515            let buffer = buffer.clone();
 7516            cx.spawn(async move |lsp_store, cx| {
 7517                let Some(lsp_store) = lsp_store.upgrade() else {
 7518                    return Ok(None);
 7519                };
 7520                let colors = join_all(
 7521                    request_task
 7522                        .await
 7523                        .log_err()
 7524                        .flatten()
 7525                        .map(|response| response.payload)
 7526                        .unwrap_or_default()
 7527                        .into_iter()
 7528                        .map(|color_response| {
 7529                            let response = request.response_from_proto(
 7530                                color_response.response,
 7531                                lsp_store.clone(),
 7532                                buffer.clone(),
 7533                                cx.clone(),
 7534                            );
 7535                            async move {
 7536                                (
 7537                                    LanguageServerId::from_proto(color_response.server_id),
 7538                                    response.await.log_err().unwrap_or_default(),
 7539                                )
 7540                            }
 7541                        }),
 7542                )
 7543                .await
 7544                .into_iter()
 7545                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7546                    acc.entry(server_id)
 7547                        .or_insert_with(HashSet::default)
 7548                        .extend(colors);
 7549                    acc
 7550                });
 7551                Ok(Some(colors))
 7552            })
 7553        } else {
 7554            let document_colors_task =
 7555                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7556            cx.background_spawn(async move {
 7557                Ok(Some(
 7558                    document_colors_task
 7559                        .await
 7560                        .into_iter()
 7561                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7562                            acc.entry(server_id)
 7563                                .or_insert_with(HashSet::default)
 7564                                .extend(colors);
 7565                            acc
 7566                        })
 7567                        .into_iter()
 7568                        .collect(),
 7569                ))
 7570            })
 7571        }
 7572    }
 7573
 7574    pub fn signature_help<T: ToPointUtf16>(
 7575        &mut self,
 7576        buffer: &Entity<Buffer>,
 7577        position: T,
 7578        cx: &mut Context<Self>,
 7579    ) -> Task<Option<Vec<SignatureHelp>>> {
 7580        let position = position.to_point_utf16(buffer.read(cx));
 7581
 7582        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7583            let request = GetSignatureHelp { position };
 7584            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7585                return Task::ready(None);
 7586            }
 7587            let request_task = client.request_lsp(
 7588                upstream_project_id,
 7589                None,
 7590                LSP_REQUEST_TIMEOUT,
 7591                cx.background_executor().clone(),
 7592                request.to_proto(upstream_project_id, buffer.read(cx)),
 7593            );
 7594            let buffer = buffer.clone();
 7595            cx.spawn(async move |weak_lsp_store, cx| {
 7596                let lsp_store = weak_lsp_store.upgrade()?;
 7597                let signatures = join_all(
 7598                    request_task
 7599                        .await
 7600                        .log_err()
 7601                        .flatten()
 7602                        .map(|response| response.payload)
 7603                        .unwrap_or_default()
 7604                        .into_iter()
 7605                        .map(|response| {
 7606                            let response = GetSignatureHelp { position }.response_from_proto(
 7607                                response.response,
 7608                                lsp_store.clone(),
 7609                                buffer.clone(),
 7610                                cx.clone(),
 7611                            );
 7612                            async move { response.await.log_err().flatten() }
 7613                        }),
 7614                )
 7615                .await
 7616                .into_iter()
 7617                .flatten()
 7618                .collect();
 7619                Some(signatures)
 7620            })
 7621        } else {
 7622            let all_actions_task = self.request_multiple_lsp_locally(
 7623                buffer,
 7624                Some(position),
 7625                GetSignatureHelp { position },
 7626                cx,
 7627            );
 7628            cx.background_spawn(async move {
 7629                Some(
 7630                    all_actions_task
 7631                        .await
 7632                        .into_iter()
 7633                        .flat_map(|(_, actions)| actions)
 7634                        .collect::<Vec<_>>(),
 7635                )
 7636            })
 7637        }
 7638    }
 7639
 7640    pub fn hover(
 7641        &mut self,
 7642        buffer: &Entity<Buffer>,
 7643        position: PointUtf16,
 7644        cx: &mut Context<Self>,
 7645    ) -> Task<Option<Vec<Hover>>> {
 7646        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7647            let request = GetHover { position };
 7648            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7649                return Task::ready(None);
 7650            }
 7651            let request_task = client.request_lsp(
 7652                upstream_project_id,
 7653                None,
 7654                LSP_REQUEST_TIMEOUT,
 7655                cx.background_executor().clone(),
 7656                request.to_proto(upstream_project_id, buffer.read(cx)),
 7657            );
 7658            let buffer = buffer.clone();
 7659            cx.spawn(async move |weak_lsp_store, cx| {
 7660                let lsp_store = weak_lsp_store.upgrade()?;
 7661                let hovers = join_all(
 7662                    request_task
 7663                        .await
 7664                        .log_err()
 7665                        .flatten()
 7666                        .map(|response| response.payload)
 7667                        .unwrap_or_default()
 7668                        .into_iter()
 7669                        .map(|response| {
 7670                            let response = GetHover { position }.response_from_proto(
 7671                                response.response,
 7672                                lsp_store.clone(),
 7673                                buffer.clone(),
 7674                                cx.clone(),
 7675                            );
 7676                            async move {
 7677                                response
 7678                                    .await
 7679                                    .log_err()
 7680                                    .flatten()
 7681                                    .and_then(remove_empty_hover_blocks)
 7682                            }
 7683                        }),
 7684                )
 7685                .await
 7686                .into_iter()
 7687                .flatten()
 7688                .collect();
 7689                Some(hovers)
 7690            })
 7691        } else {
 7692            let all_actions_task = self.request_multiple_lsp_locally(
 7693                buffer,
 7694                Some(position),
 7695                GetHover { position },
 7696                cx,
 7697            );
 7698            cx.background_spawn(async move {
 7699                Some(
 7700                    all_actions_task
 7701                        .await
 7702                        .into_iter()
 7703                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7704                        .collect::<Vec<Hover>>(),
 7705                )
 7706            })
 7707        }
 7708    }
 7709
 7710    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7711        let language_registry = self.languages.clone();
 7712
 7713        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7714            let request = upstream_client.request(proto::GetProjectSymbols {
 7715                project_id: *project_id,
 7716                query: query.to_string(),
 7717            });
 7718            cx.foreground_executor().spawn(async move {
 7719                let response = request.await?;
 7720                let mut symbols = Vec::new();
 7721                let core_symbols = response
 7722                    .symbols
 7723                    .into_iter()
 7724                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7725                    .collect::<Vec<_>>();
 7726                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7727                    .await;
 7728                Ok(symbols)
 7729            })
 7730        } else if let Some(local) = self.as_local() {
 7731            struct WorkspaceSymbolsResult {
 7732                server_id: LanguageServerId,
 7733                lsp_adapter: Arc<CachedLspAdapter>,
 7734                worktree: WeakEntity<Worktree>,
 7735                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7736            }
 7737
 7738            let mut requests = Vec::new();
 7739            let mut requested_servers = BTreeSet::new();
 7740            for (seed, state) in local.language_server_ids.iter() {
 7741                let Some(worktree_handle) = self
 7742                    .worktree_store
 7743                    .read(cx)
 7744                    .worktree_for_id(seed.worktree_id, cx)
 7745                else {
 7746                    continue;
 7747                };
 7748                let worktree = worktree_handle.read(cx);
 7749                if !worktree.is_visible() {
 7750                    continue;
 7751                }
 7752
 7753                if !requested_servers.insert(state.id) {
 7754                    continue;
 7755                }
 7756
 7757                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7758                    Some(LanguageServerState::Running {
 7759                        adapter, server, ..
 7760                    }) => (adapter.clone(), server),
 7761
 7762                    _ => continue,
 7763                };
 7764                let supports_workspace_symbol_request =
 7765                    match server.capabilities().workspace_symbol_provider {
 7766                        Some(OneOf::Left(supported)) => supported,
 7767                        Some(OneOf::Right(_)) => true,
 7768                        None => false,
 7769                    };
 7770                if !supports_workspace_symbol_request {
 7771                    continue;
 7772                }
 7773                let worktree_handle = worktree_handle.clone();
 7774                let server_id = server.server_id();
 7775                requests.push(
 7776                        server
 7777                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7778                                lsp::WorkspaceSymbolParams {
 7779                                    query: query.to_string(),
 7780                                    ..Default::default()
 7781                                },
 7782                            )
 7783                            .map(move |response| {
 7784                                let lsp_symbols = response.into_response()
 7785                                    .context("workspace symbols request")
 7786                                    .log_err()
 7787                                    .flatten()
 7788                                    .map(|symbol_response| match symbol_response {
 7789                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7790                                            flat_responses.into_iter().map(|lsp_symbol| {
 7791                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7792                                            }).collect::<Vec<_>>()
 7793                                        }
 7794                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7795                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7796                                                let location = match lsp_symbol.location {
 7797                                                    OneOf::Left(location) => location,
 7798                                                    OneOf::Right(_) => {
 7799                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7800                                                        return None
 7801                                                    }
 7802                                                };
 7803                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7804                                            }).collect::<Vec<_>>()
 7805                                        }
 7806                                    }).unwrap_or_default();
 7807
 7808                                WorkspaceSymbolsResult {
 7809                                    server_id,
 7810                                    lsp_adapter,
 7811                                    worktree: worktree_handle.downgrade(),
 7812                                    lsp_symbols,
 7813                                }
 7814                            }),
 7815                    );
 7816            }
 7817
 7818            cx.spawn(async move |this, cx| {
 7819                let responses = futures::future::join_all(requests).await;
 7820                let this = match this.upgrade() {
 7821                    Some(this) => this,
 7822                    None => return Ok(Vec::new()),
 7823                };
 7824
 7825                let mut symbols = Vec::new();
 7826                for result in responses {
 7827                    let core_symbols = this.update(cx, |this, cx| {
 7828                        result
 7829                            .lsp_symbols
 7830                            .into_iter()
 7831                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7832                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7833                                let source_worktree = result.worktree.upgrade()?;
 7834                                let source_worktree_id = source_worktree.read(cx).id();
 7835
 7836                                let path = if let Some((tree, rel_path)) =
 7837                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7838                                {
 7839                                    let worktree_id = tree.read(cx).id();
 7840                                    SymbolLocation::InProject(ProjectPath {
 7841                                        worktree_id,
 7842                                        path: rel_path,
 7843                                    })
 7844                                } else {
 7845                                    SymbolLocation::OutsideProject {
 7846                                        signature: this.symbol_signature(&abs_path),
 7847                                        abs_path: abs_path.into(),
 7848                                    }
 7849                                };
 7850
 7851                                Some(CoreSymbol {
 7852                                    source_language_server_id: result.server_id,
 7853                                    language_server_name: result.lsp_adapter.name.clone(),
 7854                                    source_worktree_id,
 7855                                    path,
 7856                                    kind: symbol_kind,
 7857                                    name: symbol_name,
 7858                                    range: range_from_lsp(symbol_location.range),
 7859                                })
 7860                            })
 7861                            .collect()
 7862                    })?;
 7863
 7864                    populate_labels_for_symbols(
 7865                        core_symbols,
 7866                        &language_registry,
 7867                        Some(result.lsp_adapter),
 7868                        &mut symbols,
 7869                    )
 7870                    .await;
 7871                }
 7872
 7873                Ok(symbols)
 7874            })
 7875        } else {
 7876            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7877        }
 7878    }
 7879
 7880    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7881        let mut summary = DiagnosticSummary::default();
 7882        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7883            summary.error_count += path_summary.error_count;
 7884            summary.warning_count += path_summary.warning_count;
 7885        }
 7886        summary
 7887    }
 7888
 7889    /// Returns the diagnostic summary for a specific project path.
 7890    pub fn diagnostic_summary_for_path(
 7891        &self,
 7892        project_path: &ProjectPath,
 7893        _: &App,
 7894    ) -> DiagnosticSummary {
 7895        if let Some(summaries) = self
 7896            .diagnostic_summaries
 7897            .get(&project_path.worktree_id)
 7898            .and_then(|map| map.get(&project_path.path))
 7899        {
 7900            let (error_count, warning_count) = summaries.iter().fold(
 7901                (0, 0),
 7902                |(error_count, warning_count), (_language_server_id, summary)| {
 7903                    (
 7904                        error_count + summary.error_count,
 7905                        warning_count + summary.warning_count,
 7906                    )
 7907                },
 7908            );
 7909
 7910            DiagnosticSummary {
 7911                error_count,
 7912                warning_count,
 7913            }
 7914        } else {
 7915            DiagnosticSummary::default()
 7916        }
 7917    }
 7918
 7919    pub fn diagnostic_summaries<'a>(
 7920        &'a self,
 7921        include_ignored: bool,
 7922        cx: &'a App,
 7923    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7924        self.worktree_store
 7925            .read(cx)
 7926            .visible_worktrees(cx)
 7927            .filter_map(|worktree| {
 7928                let worktree = worktree.read(cx);
 7929                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7930            })
 7931            .flat_map(move |(worktree, summaries)| {
 7932                let worktree_id = worktree.id();
 7933                summaries
 7934                    .iter()
 7935                    .filter(move |(path, _)| {
 7936                        include_ignored
 7937                            || worktree
 7938                                .entry_for_path(path.as_ref())
 7939                                .is_some_and(|entry| !entry.is_ignored)
 7940                    })
 7941                    .flat_map(move |(path, summaries)| {
 7942                        summaries.iter().map(move |(server_id, summary)| {
 7943                            (
 7944                                ProjectPath {
 7945                                    worktree_id,
 7946                                    path: path.clone(),
 7947                                },
 7948                                *server_id,
 7949                                *summary,
 7950                            )
 7951                        })
 7952                    })
 7953            })
 7954    }
 7955
 7956    pub fn on_buffer_edited(
 7957        &mut self,
 7958        buffer: Entity<Buffer>,
 7959        cx: &mut Context<Self>,
 7960    ) -> Option<()> {
 7961        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7962            Some(
 7963                self.as_local()?
 7964                    .language_servers_for_buffer(buffer, cx)
 7965                    .map(|i| i.1.clone())
 7966                    .collect(),
 7967            )
 7968        })?;
 7969
 7970        let buffer = buffer.read(cx);
 7971        let file = File::from_dyn(buffer.file())?;
 7972        let abs_path = file.as_local()?.abs_path(cx);
 7973        let uri = lsp::Uri::from_file_path(&abs_path)
 7974            .ok()
 7975            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7976            .log_err()?;
 7977        let next_snapshot = buffer.text_snapshot();
 7978        for language_server in language_servers {
 7979            let language_server = language_server.clone();
 7980
 7981            let buffer_snapshots = self
 7982                .as_local_mut()?
 7983                .buffer_snapshots
 7984                .get_mut(&buffer.remote_id())
 7985                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7986            let previous_snapshot = buffer_snapshots.last()?;
 7987
 7988            let build_incremental_change = || {
 7989                buffer
 7990                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7991                        previous_snapshot.snapshot.version(),
 7992                    )
 7993                    .map(|edit| {
 7994                        let edit_start = edit.new.start.0;
 7995                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7996                        let new_text = next_snapshot
 7997                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7998                            .collect();
 7999                        lsp::TextDocumentContentChangeEvent {
 8000                            range: Some(lsp::Range::new(
 8001                                point_to_lsp(edit_start),
 8002                                point_to_lsp(edit_end),
 8003                            )),
 8004                            range_length: None,
 8005                            text: new_text,
 8006                        }
 8007                    })
 8008                    .collect()
 8009            };
 8010
 8011            let document_sync_kind = language_server
 8012                .capabilities()
 8013                .text_document_sync
 8014                .as_ref()
 8015                .and_then(|sync| match sync {
 8016                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 8017                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 8018                });
 8019
 8020            let content_changes: Vec<_> = match document_sync_kind {
 8021                Some(lsp::TextDocumentSyncKind::FULL) => {
 8022                    vec![lsp::TextDocumentContentChangeEvent {
 8023                        range: None,
 8024                        range_length: None,
 8025                        text: next_snapshot.text(),
 8026                    }]
 8027                }
 8028                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8029                _ => {
 8030                    #[cfg(any(test, feature = "test-support"))]
 8031                    {
 8032                        build_incremental_change()
 8033                    }
 8034
 8035                    #[cfg(not(any(test, feature = "test-support")))]
 8036                    {
 8037                        continue;
 8038                    }
 8039                }
 8040            };
 8041
 8042            let next_version = previous_snapshot.version + 1;
 8043            buffer_snapshots.push(LspBufferSnapshot {
 8044                version: next_version,
 8045                snapshot: next_snapshot.clone(),
 8046            });
 8047
 8048            language_server
 8049                .notify::<lsp::notification::DidChangeTextDocument>(
 8050                    lsp::DidChangeTextDocumentParams {
 8051                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8052                            uri.clone(),
 8053                            next_version,
 8054                        ),
 8055                        content_changes,
 8056                    },
 8057                )
 8058                .ok();
 8059            self.pull_workspace_diagnostics(language_server.server_id());
 8060        }
 8061
 8062        None
 8063    }
 8064
 8065    pub fn on_buffer_saved(
 8066        &mut self,
 8067        buffer: Entity<Buffer>,
 8068        cx: &mut Context<Self>,
 8069    ) -> Option<()> {
 8070        let file = File::from_dyn(buffer.read(cx).file())?;
 8071        let worktree_id = file.worktree_id(cx);
 8072        let abs_path = file.as_local()?.abs_path(cx);
 8073        let text_document = lsp::TextDocumentIdentifier {
 8074            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8075        };
 8076        let local = self.as_local()?;
 8077
 8078        for server in local.language_servers_for_worktree(worktree_id) {
 8079            if let Some(include_text) = include_text(server.as_ref()) {
 8080                let text = if include_text {
 8081                    Some(buffer.read(cx).text())
 8082                } else {
 8083                    None
 8084                };
 8085                server
 8086                    .notify::<lsp::notification::DidSaveTextDocument>(
 8087                        lsp::DidSaveTextDocumentParams {
 8088                            text_document: text_document.clone(),
 8089                            text,
 8090                        },
 8091                    )
 8092                    .ok();
 8093            }
 8094        }
 8095
 8096        let language_servers = buffer.update(cx, |buffer, cx| {
 8097            local.language_server_ids_for_buffer(buffer, cx)
 8098        });
 8099        for language_server_id in language_servers {
 8100            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8101        }
 8102
 8103        None
 8104    }
 8105
 8106    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8107        maybe!(async move {
 8108            let mut refreshed_servers = HashSet::default();
 8109            let servers = lsp_store
 8110                .update(cx, |lsp_store, cx| {
 8111                    let local = lsp_store.as_local()?;
 8112
 8113                    let servers = local
 8114                        .language_server_ids
 8115                        .iter()
 8116                        .filter_map(|(seed, state)| {
 8117                            let worktree = lsp_store
 8118                                .worktree_store
 8119                                .read(cx)
 8120                                .worktree_for_id(seed.worktree_id, cx);
 8121                            let delegate: Arc<dyn LspAdapterDelegate> =
 8122                                worktree.map(|worktree| {
 8123                                    LocalLspAdapterDelegate::new(
 8124                                        local.languages.clone(),
 8125                                        &local.environment,
 8126                                        cx.weak_entity(),
 8127                                        &worktree,
 8128                                        local.http_client.clone(),
 8129                                        local.fs.clone(),
 8130                                        cx,
 8131                                    )
 8132                                })?;
 8133                            let server_id = state.id;
 8134
 8135                            let states = local.language_servers.get(&server_id)?;
 8136
 8137                            match states {
 8138                                LanguageServerState::Starting { .. } => None,
 8139                                LanguageServerState::Running {
 8140                                    adapter, server, ..
 8141                                } => {
 8142                                    let adapter = adapter.clone();
 8143                                    let server = server.clone();
 8144                                    refreshed_servers.insert(server.name());
 8145                                    let toolchain = seed.toolchain.clone();
 8146                                    Some(cx.spawn(async move |_, cx| {
 8147                                        let settings =
 8148                                            LocalLspStore::workspace_configuration_for_adapter(
 8149                                                adapter.adapter.clone(),
 8150                                                &delegate,
 8151                                                toolchain,
 8152                                                None,
 8153                                                cx,
 8154                                            )
 8155                                            .await
 8156                                            .ok()?;
 8157                                        server
 8158                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8159                                                lsp::DidChangeConfigurationParams { settings },
 8160                                            )
 8161                                            .ok()?;
 8162                                        Some(())
 8163                                    }))
 8164                                }
 8165                            }
 8166                        })
 8167                        .collect::<Vec<_>>();
 8168
 8169                    Some(servers)
 8170                })
 8171                .ok()
 8172                .flatten()?;
 8173
 8174            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8175            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8176            // to stop and unregister its language server wrapper.
 8177            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8178            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8179            let _: Vec<Option<()>> = join_all(servers).await;
 8180
 8181            Some(())
 8182        })
 8183        .await;
 8184    }
 8185
 8186    fn maintain_workspace_config(
 8187        external_refresh_requests: watch::Receiver<()>,
 8188        cx: &mut Context<Self>,
 8189    ) -> Task<Result<()>> {
 8190        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8191        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8192
 8193        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8194            *settings_changed_tx.borrow_mut() = ();
 8195        });
 8196
 8197        let mut joint_future =
 8198            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8199        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8200        // - 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).
 8201        // - 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.
 8202        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8203        // - 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,
 8204        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8205        cx.spawn(async move |this, cx| {
 8206            while let Some(()) = joint_future.next().await {
 8207                this.update(cx, |this, cx| {
 8208                    this.refresh_server_tree(cx);
 8209                })
 8210                .ok();
 8211
 8212                Self::refresh_workspace_configurations(&this, cx).await;
 8213            }
 8214
 8215            drop(settings_observation);
 8216            anyhow::Ok(())
 8217        })
 8218    }
 8219
 8220    pub fn running_language_servers_for_local_buffer<'a>(
 8221        &'a self,
 8222        buffer: &Buffer,
 8223        cx: &mut App,
 8224    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8225        let local = self.as_local();
 8226        let language_server_ids = local
 8227            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8228            .unwrap_or_default();
 8229
 8230        language_server_ids
 8231            .into_iter()
 8232            .filter_map(
 8233                move |server_id| match local?.language_servers.get(&server_id)? {
 8234                    LanguageServerState::Running {
 8235                        adapter, server, ..
 8236                    } => Some((adapter, server)),
 8237                    _ => None,
 8238                },
 8239            )
 8240    }
 8241
 8242    pub fn language_servers_for_local_buffer(
 8243        &self,
 8244        buffer: &Buffer,
 8245        cx: &mut App,
 8246    ) -> Vec<LanguageServerId> {
 8247        let local = self.as_local();
 8248        local
 8249            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8250            .unwrap_or_default()
 8251    }
 8252
 8253    pub fn language_server_for_local_buffer<'a>(
 8254        &'a self,
 8255        buffer: &'a Buffer,
 8256        server_id: LanguageServerId,
 8257        cx: &'a mut App,
 8258    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8259        self.as_local()?
 8260            .language_servers_for_buffer(buffer, cx)
 8261            .find(|(_, s)| s.server_id() == server_id)
 8262    }
 8263
 8264    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8265        self.diagnostic_summaries.remove(&id_to_remove);
 8266        if let Some(local) = self.as_local_mut() {
 8267            let to_remove = local.remove_worktree(id_to_remove, cx);
 8268            for server in to_remove {
 8269                self.language_server_statuses.remove(&server);
 8270            }
 8271        }
 8272    }
 8273
 8274    pub fn shared(
 8275        &mut self,
 8276        project_id: u64,
 8277        downstream_client: AnyProtoClient,
 8278        _: &mut Context<Self>,
 8279    ) {
 8280        self.downstream_client = Some((downstream_client.clone(), project_id));
 8281
 8282        for (server_id, status) in &self.language_server_statuses {
 8283            if let Some(server) = self.language_server_for_id(*server_id) {
 8284                downstream_client
 8285                    .send(proto::StartLanguageServer {
 8286                        project_id,
 8287                        server: Some(proto::LanguageServer {
 8288                            id: server_id.to_proto(),
 8289                            name: status.name.to_string(),
 8290                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8291                        }),
 8292                        capabilities: serde_json::to_string(&server.capabilities())
 8293                            .expect("serializing server LSP capabilities"),
 8294                    })
 8295                    .log_err();
 8296            }
 8297        }
 8298    }
 8299
 8300    pub fn disconnected_from_host(&mut self) {
 8301        self.downstream_client.take();
 8302    }
 8303
 8304    pub fn disconnected_from_ssh_remote(&mut self) {
 8305        if let LspStoreMode::Remote(RemoteLspStore {
 8306            upstream_client, ..
 8307        }) = &mut self.mode
 8308        {
 8309            upstream_client.take();
 8310        }
 8311    }
 8312
 8313    pub(crate) fn set_language_server_statuses_from_proto(
 8314        &mut self,
 8315        project: WeakEntity<Project>,
 8316        language_servers: Vec<proto::LanguageServer>,
 8317        server_capabilities: Vec<String>,
 8318        cx: &mut Context<Self>,
 8319    ) {
 8320        let lsp_logs = cx
 8321            .try_global::<GlobalLogStore>()
 8322            .map(|lsp_store| lsp_store.0.clone());
 8323
 8324        self.language_server_statuses = language_servers
 8325            .into_iter()
 8326            .zip(server_capabilities)
 8327            .map(|(server, server_capabilities)| {
 8328                let server_id = LanguageServerId(server.id as usize);
 8329                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8330                    self.lsp_server_capabilities
 8331                        .insert(server_id, server_capabilities);
 8332                }
 8333
 8334                let name = LanguageServerName::from_proto(server.name);
 8335                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8336
 8337                if let Some(lsp_logs) = &lsp_logs {
 8338                    lsp_logs.update(cx, |lsp_logs, cx| {
 8339                        lsp_logs.add_language_server(
 8340                            // Only remote clients get their language servers set from proto
 8341                            LanguageServerKind::Remote {
 8342                                project: project.clone(),
 8343                            },
 8344                            server_id,
 8345                            Some(name.clone()),
 8346                            worktree,
 8347                            None,
 8348                            cx,
 8349                        );
 8350                    });
 8351                }
 8352
 8353                (
 8354                    server_id,
 8355                    LanguageServerStatus {
 8356                        name,
 8357                        pending_work: Default::default(),
 8358                        has_pending_diagnostic_updates: false,
 8359                        progress_tokens: Default::default(),
 8360                        worktree,
 8361                        binary: None,
 8362                        configuration: None,
 8363                        workspace_folders: BTreeSet::new(),
 8364                    },
 8365                )
 8366            })
 8367            .collect();
 8368    }
 8369
 8370    #[cfg(test)]
 8371    pub fn update_diagnostic_entries(
 8372        &mut self,
 8373        server_id: LanguageServerId,
 8374        abs_path: PathBuf,
 8375        result_id: Option<SharedString>,
 8376        version: Option<i32>,
 8377        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8378        cx: &mut Context<Self>,
 8379    ) -> anyhow::Result<()> {
 8380        self.merge_diagnostic_entries(
 8381            vec![DocumentDiagnosticsUpdate {
 8382                diagnostics: DocumentDiagnostics {
 8383                    diagnostics,
 8384                    document_abs_path: abs_path,
 8385                    version,
 8386                },
 8387                result_id,
 8388                server_id,
 8389                disk_based_sources: Cow::Borrowed(&[]),
 8390                registration_id: None,
 8391            }],
 8392            |_, _, _| false,
 8393            cx,
 8394        )?;
 8395        Ok(())
 8396    }
 8397
 8398    pub fn merge_diagnostic_entries<'a>(
 8399        &mut self,
 8400        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8401        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8402        cx: &mut Context<Self>,
 8403    ) -> anyhow::Result<()> {
 8404        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8405        let mut updated_diagnostics_paths = HashMap::default();
 8406        for mut update in diagnostic_updates {
 8407            let abs_path = &update.diagnostics.document_abs_path;
 8408            let server_id = update.server_id;
 8409            let Some((worktree, relative_path)) =
 8410                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8411            else {
 8412                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8413                return Ok(());
 8414            };
 8415
 8416            let worktree_id = worktree.read(cx).id();
 8417            let project_path = ProjectPath {
 8418                worktree_id,
 8419                path: relative_path,
 8420            };
 8421
 8422            let document_uri = lsp::Uri::from_file_path(abs_path)
 8423                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8424            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8425                let snapshot = buffer_handle.read(cx).snapshot();
 8426                let buffer = buffer_handle.read(cx);
 8427                let reused_diagnostics = buffer
 8428                    .buffer_diagnostics(Some(server_id))
 8429                    .iter()
 8430                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8431                    .map(|v| {
 8432                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8433                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8434                        DiagnosticEntry {
 8435                            range: start..end,
 8436                            diagnostic: v.diagnostic.clone(),
 8437                        }
 8438                    })
 8439                    .collect::<Vec<_>>();
 8440
 8441                self.as_local_mut()
 8442                    .context("cannot merge diagnostics on a remote LspStore")?
 8443                    .update_buffer_diagnostics(
 8444                        &buffer_handle,
 8445                        server_id,
 8446                        Some(update.registration_id),
 8447                        update.result_id,
 8448                        update.diagnostics.version,
 8449                        update.diagnostics.diagnostics.clone(),
 8450                        reused_diagnostics.clone(),
 8451                        cx,
 8452                    )?;
 8453
 8454                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8455            } else if let Some(local) = self.as_local() {
 8456                let reused_diagnostics = local
 8457                    .diagnostics
 8458                    .get(&worktree_id)
 8459                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8460                    .and_then(|diagnostics_by_server_id| {
 8461                        diagnostics_by_server_id
 8462                            .binary_search_by_key(&server_id, |e| e.0)
 8463                            .ok()
 8464                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8465                    })
 8466                    .into_iter()
 8467                    .flatten()
 8468                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8469
 8470                update
 8471                    .diagnostics
 8472                    .diagnostics
 8473                    .extend(reused_diagnostics.cloned());
 8474            }
 8475
 8476            let updated = worktree.update(cx, |worktree, cx| {
 8477                self.update_worktree_diagnostics(
 8478                    worktree.id(),
 8479                    server_id,
 8480                    project_path.path.clone(),
 8481                    update.diagnostics.diagnostics,
 8482                    cx,
 8483                )
 8484            })?;
 8485            match updated {
 8486                ControlFlow::Continue(new_summary) => {
 8487                    if let Some((project_id, new_summary)) = new_summary {
 8488                        match &mut diagnostics_summary {
 8489                            Some(diagnostics_summary) => {
 8490                                diagnostics_summary
 8491                                    .more_summaries
 8492                                    .push(proto::DiagnosticSummary {
 8493                                        path: project_path.path.as_ref().to_proto(),
 8494                                        language_server_id: server_id.0 as u64,
 8495                                        error_count: new_summary.error_count,
 8496                                        warning_count: new_summary.warning_count,
 8497                                    })
 8498                            }
 8499                            None => {
 8500                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8501                                    project_id,
 8502                                    worktree_id: worktree_id.to_proto(),
 8503                                    summary: Some(proto::DiagnosticSummary {
 8504                                        path: project_path.path.as_ref().to_proto(),
 8505                                        language_server_id: server_id.0 as u64,
 8506                                        error_count: new_summary.error_count,
 8507                                        warning_count: new_summary.warning_count,
 8508                                    }),
 8509                                    more_summaries: Vec::new(),
 8510                                })
 8511                            }
 8512                        }
 8513                    }
 8514                    updated_diagnostics_paths
 8515                        .entry(server_id)
 8516                        .or_insert_with(Vec::new)
 8517                        .push(project_path);
 8518                }
 8519                ControlFlow::Break(()) => {}
 8520            }
 8521        }
 8522
 8523        if let Some((diagnostics_summary, (downstream_client, _))) =
 8524            diagnostics_summary.zip(self.downstream_client.as_ref())
 8525        {
 8526            downstream_client.send(diagnostics_summary).log_err();
 8527        }
 8528        for (server_id, paths) in updated_diagnostics_paths {
 8529            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8530        }
 8531        Ok(())
 8532    }
 8533
 8534    fn update_worktree_diagnostics(
 8535        &mut self,
 8536        worktree_id: WorktreeId,
 8537        server_id: LanguageServerId,
 8538        path_in_worktree: Arc<RelPath>,
 8539        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8540        _: &mut Context<Worktree>,
 8541    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8542        let local = match &mut self.mode {
 8543            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8544            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8545        };
 8546
 8547        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8548        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8549        let summaries_by_server_id = summaries_for_tree
 8550            .entry(path_in_worktree.clone())
 8551            .or_default();
 8552
 8553        let old_summary = summaries_by_server_id
 8554            .remove(&server_id)
 8555            .unwrap_or_default();
 8556
 8557        let new_summary = DiagnosticSummary::new(&diagnostics);
 8558        if diagnostics.is_empty() {
 8559            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8560            {
 8561                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8562                    diagnostics_by_server_id.remove(ix);
 8563                }
 8564                if diagnostics_by_server_id.is_empty() {
 8565                    diagnostics_for_tree.remove(&path_in_worktree);
 8566                }
 8567            }
 8568        } else {
 8569            summaries_by_server_id.insert(server_id, new_summary);
 8570            let diagnostics_by_server_id = diagnostics_for_tree
 8571                .entry(path_in_worktree.clone())
 8572                .or_default();
 8573            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8574                Ok(ix) => {
 8575                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8576                }
 8577                Err(ix) => {
 8578                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8579                }
 8580            }
 8581        }
 8582
 8583        if !old_summary.is_empty() || !new_summary.is_empty() {
 8584            if let Some((_, project_id)) = &self.downstream_client {
 8585                Ok(ControlFlow::Continue(Some((
 8586                    *project_id,
 8587                    proto::DiagnosticSummary {
 8588                        path: path_in_worktree.to_proto(),
 8589                        language_server_id: server_id.0 as u64,
 8590                        error_count: new_summary.error_count as u32,
 8591                        warning_count: new_summary.warning_count as u32,
 8592                    },
 8593                ))))
 8594            } else {
 8595                Ok(ControlFlow::Continue(None))
 8596            }
 8597        } else {
 8598            Ok(ControlFlow::Break(()))
 8599        }
 8600    }
 8601
 8602    pub fn open_buffer_for_symbol(
 8603        &mut self,
 8604        symbol: &Symbol,
 8605        cx: &mut Context<Self>,
 8606    ) -> Task<Result<Entity<Buffer>>> {
 8607        if let Some((client, project_id)) = self.upstream_client() {
 8608            let request = client.request(proto::OpenBufferForSymbol {
 8609                project_id,
 8610                symbol: Some(Self::serialize_symbol(symbol)),
 8611            });
 8612            cx.spawn(async move |this, cx| {
 8613                let response = request.await?;
 8614                let buffer_id = BufferId::new(response.buffer_id)?;
 8615                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8616                    .await
 8617            })
 8618        } else if let Some(local) = self.as_local() {
 8619            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8620                seed.worktree_id == symbol.source_worktree_id
 8621                    && state.id == symbol.source_language_server_id
 8622                    && symbol.language_server_name == seed.name
 8623            });
 8624            if !is_valid {
 8625                return Task::ready(Err(anyhow!(
 8626                    "language server for worktree and language not found"
 8627                )));
 8628            };
 8629
 8630            let symbol_abs_path = match &symbol.path {
 8631                SymbolLocation::InProject(project_path) => self
 8632                    .worktree_store
 8633                    .read(cx)
 8634                    .absolutize(&project_path, cx)
 8635                    .context("no such worktree"),
 8636                SymbolLocation::OutsideProject {
 8637                    abs_path,
 8638                    signature: _,
 8639                } => Ok(abs_path.to_path_buf()),
 8640            };
 8641            let symbol_abs_path = match symbol_abs_path {
 8642                Ok(abs_path) => abs_path,
 8643                Err(err) => return Task::ready(Err(err)),
 8644            };
 8645            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8646                uri
 8647            } else {
 8648                return Task::ready(Err(anyhow!("invalid symbol path")));
 8649            };
 8650
 8651            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8652        } else {
 8653            Task::ready(Err(anyhow!("no upstream client or local store")))
 8654        }
 8655    }
 8656
 8657    pub(crate) fn open_local_buffer_via_lsp(
 8658        &mut self,
 8659        abs_path: lsp::Uri,
 8660        language_server_id: LanguageServerId,
 8661        cx: &mut Context<Self>,
 8662    ) -> Task<Result<Entity<Buffer>>> {
 8663        cx.spawn(async move |lsp_store, cx| {
 8664            // Escape percent-encoded string.
 8665            let current_scheme = abs_path.scheme().to_owned();
 8666            // Uri is immutable, so we can't modify the scheme
 8667
 8668            let abs_path = abs_path
 8669                .to_file_path()
 8670                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8671            let p = abs_path.clone();
 8672            let yarn_worktree = lsp_store
 8673                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8674                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8675                        cx.spawn(async move |this, cx| {
 8676                            let t = this
 8677                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8678                                .ok()?;
 8679                            t.await
 8680                        })
 8681                    }),
 8682                    None => Task::ready(None),
 8683                })?
 8684                .await;
 8685            let (worktree_root_target, known_relative_path) =
 8686                if let Some((zip_root, relative_path)) = yarn_worktree {
 8687                    (zip_root, Some(relative_path))
 8688                } else {
 8689                    (Arc::<Path>::from(abs_path.as_path()), None)
 8690                };
 8691            let (worktree, relative_path) = if let Some(result) =
 8692                lsp_store.update(cx, |lsp_store, cx| {
 8693                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8694                        worktree_store.find_worktree(&worktree_root_target, cx)
 8695                    })
 8696                })? {
 8697                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8698                (result.0, relative_path)
 8699            } else {
 8700                let worktree = lsp_store
 8701                    .update(cx, |lsp_store, cx| {
 8702                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8703                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8704                        })
 8705                    })?
 8706                    .await?;
 8707                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8708                    lsp_store
 8709                        .update(cx, |lsp_store, cx| {
 8710                            if let Some(local) = lsp_store.as_local_mut() {
 8711                                local.register_language_server_for_invisible_worktree(
 8712                                    &worktree,
 8713                                    language_server_id,
 8714                                    cx,
 8715                                )
 8716                            }
 8717                        })
 8718                        .ok();
 8719                }
 8720                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8721                let relative_path = if let Some(known_path) = known_relative_path {
 8722                    known_path
 8723                } else {
 8724                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8725                        .into_arc()
 8726                };
 8727                (worktree, relative_path)
 8728            };
 8729            let project_path = ProjectPath {
 8730                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8731                path: relative_path,
 8732            };
 8733            lsp_store
 8734                .update(cx, |lsp_store, cx| {
 8735                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8736                        buffer_store.open_buffer(project_path, cx)
 8737                    })
 8738                })?
 8739                .await
 8740        })
 8741    }
 8742
 8743    fn request_multiple_lsp_locally<P, R>(
 8744        &mut self,
 8745        buffer: &Entity<Buffer>,
 8746        position: Option<P>,
 8747        request: R,
 8748        cx: &mut Context<Self>,
 8749    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8750    where
 8751        P: ToOffset,
 8752        R: LspCommand + Clone,
 8753        <R::LspRequest as lsp::request::Request>::Result: Send,
 8754        <R::LspRequest as lsp::request::Request>::Params: Send,
 8755    {
 8756        let Some(local) = self.as_local() else {
 8757            return Task::ready(Vec::new());
 8758        };
 8759
 8760        let snapshot = buffer.read(cx).snapshot();
 8761        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8762
 8763        let server_ids = buffer.update(cx, |buffer, cx| {
 8764            local
 8765                .language_servers_for_buffer(buffer, cx)
 8766                .filter(|(adapter, _)| {
 8767                    scope
 8768                        .as_ref()
 8769                        .map(|scope| scope.language_allowed(&adapter.name))
 8770                        .unwrap_or(true)
 8771                })
 8772                .map(|(_, server)| server.server_id())
 8773                .filter(|server_id| {
 8774                    self.as_local().is_none_or(|local| {
 8775                        local
 8776                            .buffers_opened_in_servers
 8777                            .get(&snapshot.remote_id())
 8778                            .is_some_and(|servers| servers.contains(server_id))
 8779                    })
 8780                })
 8781                .collect::<Vec<_>>()
 8782        });
 8783
 8784        let mut response_results = server_ids
 8785            .into_iter()
 8786            .map(|server_id| {
 8787                let task = self.request_lsp(
 8788                    buffer.clone(),
 8789                    LanguageServerToQuery::Other(server_id),
 8790                    request.clone(),
 8791                    cx,
 8792                );
 8793                async move { (server_id, task.await) }
 8794            })
 8795            .collect::<FuturesUnordered<_>>();
 8796
 8797        cx.background_spawn(async move {
 8798            let mut responses = Vec::with_capacity(response_results.len());
 8799            while let Some((server_id, response_result)) = response_results.next().await {
 8800                match response_result {
 8801                    Ok(response) => responses.push((server_id, response)),
 8802                    // rust-analyzer likes to error with this when its still loading up
 8803                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8804                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8805                }
 8806            }
 8807            responses
 8808        })
 8809    }
 8810
 8811    async fn handle_lsp_get_completions(
 8812        this: Entity<Self>,
 8813        envelope: TypedEnvelope<proto::GetCompletions>,
 8814        mut cx: AsyncApp,
 8815    ) -> Result<proto::GetCompletionsResponse> {
 8816        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8817
 8818        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8819        let buffer_handle = this.update(&mut cx, |this, cx| {
 8820            this.buffer_store.read(cx).get_existing(buffer_id)
 8821        })??;
 8822        let request = GetCompletions::from_proto(
 8823            envelope.payload,
 8824            this.clone(),
 8825            buffer_handle.clone(),
 8826            cx.clone(),
 8827        )
 8828        .await?;
 8829
 8830        let server_to_query = match request.server_id {
 8831            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8832            None => LanguageServerToQuery::FirstCapable,
 8833        };
 8834
 8835        let response = this
 8836            .update(&mut cx, |this, cx| {
 8837                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8838            })?
 8839            .await?;
 8840        this.update(&mut cx, |this, cx| {
 8841            Ok(GetCompletions::response_to_proto(
 8842                response,
 8843                this,
 8844                sender_id,
 8845                &buffer_handle.read(cx).version(),
 8846                cx,
 8847            ))
 8848        })?
 8849    }
 8850
 8851    async fn handle_lsp_command<T: LspCommand>(
 8852        this: Entity<Self>,
 8853        envelope: TypedEnvelope<T::ProtoRequest>,
 8854        mut cx: AsyncApp,
 8855    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8856    where
 8857        <T::LspRequest as lsp::request::Request>::Params: Send,
 8858        <T::LspRequest as lsp::request::Request>::Result: Send,
 8859    {
 8860        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8861        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8862        let buffer_handle = this.update(&mut cx, |this, cx| {
 8863            this.buffer_store.read(cx).get_existing(buffer_id)
 8864        })??;
 8865        let request = T::from_proto(
 8866            envelope.payload,
 8867            this.clone(),
 8868            buffer_handle.clone(),
 8869            cx.clone(),
 8870        )
 8871        .await?;
 8872        let response = this
 8873            .update(&mut cx, |this, cx| {
 8874                this.request_lsp(
 8875                    buffer_handle.clone(),
 8876                    LanguageServerToQuery::FirstCapable,
 8877                    request,
 8878                    cx,
 8879                )
 8880            })?
 8881            .await?;
 8882        this.update(&mut cx, |this, cx| {
 8883            Ok(T::response_to_proto(
 8884                response,
 8885                this,
 8886                sender_id,
 8887                &buffer_handle.read(cx).version(),
 8888                cx,
 8889            ))
 8890        })?
 8891    }
 8892
 8893    async fn handle_lsp_query(
 8894        lsp_store: Entity<Self>,
 8895        envelope: TypedEnvelope<proto::LspQuery>,
 8896        mut cx: AsyncApp,
 8897    ) -> Result<proto::Ack> {
 8898        use proto::lsp_query::Request;
 8899        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8900        let lsp_query = envelope.payload;
 8901        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8902        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8903        match lsp_query.request.context("invalid LSP query request")? {
 8904            Request::GetReferences(get_references) => {
 8905                let position = get_references.position.clone().and_then(deserialize_anchor);
 8906                Self::query_lsp_locally::<GetReferences>(
 8907                    lsp_store,
 8908                    server_id,
 8909                    sender_id,
 8910                    lsp_request_id,
 8911                    get_references,
 8912                    position,
 8913                    &mut cx,
 8914                )
 8915                .await?;
 8916            }
 8917            Request::GetDocumentColor(get_document_color) => {
 8918                Self::query_lsp_locally::<GetDocumentColor>(
 8919                    lsp_store,
 8920                    server_id,
 8921                    sender_id,
 8922                    lsp_request_id,
 8923                    get_document_color,
 8924                    None,
 8925                    &mut cx,
 8926                )
 8927                .await?;
 8928            }
 8929            Request::GetHover(get_hover) => {
 8930                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8931                Self::query_lsp_locally::<GetHover>(
 8932                    lsp_store,
 8933                    server_id,
 8934                    sender_id,
 8935                    lsp_request_id,
 8936                    get_hover,
 8937                    position,
 8938                    &mut cx,
 8939                )
 8940                .await?;
 8941            }
 8942            Request::GetCodeActions(get_code_actions) => {
 8943                Self::query_lsp_locally::<GetCodeActions>(
 8944                    lsp_store,
 8945                    server_id,
 8946                    sender_id,
 8947                    lsp_request_id,
 8948                    get_code_actions,
 8949                    None,
 8950                    &mut cx,
 8951                )
 8952                .await?;
 8953            }
 8954            Request::GetSignatureHelp(get_signature_help) => {
 8955                let position = get_signature_help
 8956                    .position
 8957                    .clone()
 8958                    .and_then(deserialize_anchor);
 8959                Self::query_lsp_locally::<GetSignatureHelp>(
 8960                    lsp_store,
 8961                    server_id,
 8962                    sender_id,
 8963                    lsp_request_id,
 8964                    get_signature_help,
 8965                    position,
 8966                    &mut cx,
 8967                )
 8968                .await?;
 8969            }
 8970            Request::GetCodeLens(get_code_lens) => {
 8971                Self::query_lsp_locally::<GetCodeLens>(
 8972                    lsp_store,
 8973                    server_id,
 8974                    sender_id,
 8975                    lsp_request_id,
 8976                    get_code_lens,
 8977                    None,
 8978                    &mut cx,
 8979                )
 8980                .await?;
 8981            }
 8982            Request::GetDefinition(get_definition) => {
 8983                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8984                Self::query_lsp_locally::<GetDefinitions>(
 8985                    lsp_store,
 8986                    server_id,
 8987                    sender_id,
 8988                    lsp_request_id,
 8989                    get_definition,
 8990                    position,
 8991                    &mut cx,
 8992                )
 8993                .await?;
 8994            }
 8995            Request::GetDeclaration(get_declaration) => {
 8996                let position = get_declaration
 8997                    .position
 8998                    .clone()
 8999                    .and_then(deserialize_anchor);
 9000                Self::query_lsp_locally::<GetDeclarations>(
 9001                    lsp_store,
 9002                    server_id,
 9003                    sender_id,
 9004                    lsp_request_id,
 9005                    get_declaration,
 9006                    position,
 9007                    &mut cx,
 9008                )
 9009                .await?;
 9010            }
 9011            Request::GetTypeDefinition(get_type_definition) => {
 9012                let position = get_type_definition
 9013                    .position
 9014                    .clone()
 9015                    .and_then(deserialize_anchor);
 9016                Self::query_lsp_locally::<GetTypeDefinitions>(
 9017                    lsp_store,
 9018                    server_id,
 9019                    sender_id,
 9020                    lsp_request_id,
 9021                    get_type_definition,
 9022                    position,
 9023                    &mut cx,
 9024                )
 9025                .await?;
 9026            }
 9027            Request::GetImplementation(get_implementation) => {
 9028                let position = get_implementation
 9029                    .position
 9030                    .clone()
 9031                    .and_then(deserialize_anchor);
 9032                Self::query_lsp_locally::<GetImplementations>(
 9033                    lsp_store,
 9034                    server_id,
 9035                    sender_id,
 9036                    lsp_request_id,
 9037                    get_implementation,
 9038                    position,
 9039                    &mut cx,
 9040                )
 9041                .await?;
 9042            }
 9043            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9044                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 9045                let version = deserialize_version(get_document_diagnostics.buffer_version());
 9046                let buffer = lsp_store.update(&mut cx, |this, cx| {
 9047                    this.buffer_store.read(cx).get_existing(buffer_id)
 9048                })??;
 9049                buffer
 9050                    .update(&mut cx, |buffer, _| {
 9051                        buffer.wait_for_version(version.clone())
 9052                    })?
 9053                    .await?;
 9054                lsp_store.update(&mut cx, |lsp_store, cx| {
 9055                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9056                    let key = LspKey {
 9057                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9058                        server_queried: server_id,
 9059                    };
 9060                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9061                    ) {
 9062                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9063                            lsp_requests.clear();
 9064                        };
 9065                    }
 9066
 9067                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 9068                    existing_queries.insert(
 9069                        lsp_request_id,
 9070                        cx.spawn(async move |lsp_store, cx| {
 9071                            let diagnostics_pull = lsp_store
 9072                                .update(cx, |lsp_store, cx| {
 9073                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9074                                })
 9075                                .ok();
 9076                            if let Some(diagnostics_pull) = diagnostics_pull {
 9077                                match diagnostics_pull.await {
 9078                                    Ok(()) => {}
 9079                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9080                                };
 9081                            }
 9082                        }),
 9083                    );
 9084                })?;
 9085            }
 9086            Request::InlayHints(inlay_hints) => {
 9087                let query_start = inlay_hints
 9088                    .start
 9089                    .clone()
 9090                    .and_then(deserialize_anchor)
 9091                    .context("invalid inlay hints range start")?;
 9092                let query_end = inlay_hints
 9093                    .end
 9094                    .clone()
 9095                    .and_then(deserialize_anchor)
 9096                    .context("invalid inlay hints range end")?;
 9097                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9098                    &lsp_store,
 9099                    server_id,
 9100                    lsp_request_id,
 9101                    &inlay_hints,
 9102                    query_start..query_end,
 9103                    &mut cx,
 9104                )
 9105                .await
 9106                .context("preparing inlay hints request")?;
 9107                Self::query_lsp_locally::<InlayHints>(
 9108                    lsp_store,
 9109                    server_id,
 9110                    sender_id,
 9111                    lsp_request_id,
 9112                    inlay_hints,
 9113                    None,
 9114                    &mut cx,
 9115                )
 9116                .await
 9117                .context("querying for inlay hints")?
 9118            }
 9119        }
 9120        Ok(proto::Ack {})
 9121    }
 9122
 9123    async fn handle_lsp_query_response(
 9124        lsp_store: Entity<Self>,
 9125        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9126        cx: AsyncApp,
 9127    ) -> Result<()> {
 9128        lsp_store.read_with(&cx, |lsp_store, _| {
 9129            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9130                upstream_client.handle_lsp_response(envelope.clone());
 9131            }
 9132        })?;
 9133        Ok(())
 9134    }
 9135
 9136    async fn handle_apply_code_action(
 9137        this: Entity<Self>,
 9138        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9139        mut cx: AsyncApp,
 9140    ) -> Result<proto::ApplyCodeActionResponse> {
 9141        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9142        let action =
 9143            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9144        let apply_code_action = this.update(&mut cx, |this, cx| {
 9145            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9146            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9147            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9148        })??;
 9149
 9150        let project_transaction = apply_code_action.await?;
 9151        let project_transaction = this.update(&mut cx, |this, cx| {
 9152            this.buffer_store.update(cx, |buffer_store, cx| {
 9153                buffer_store.serialize_project_transaction_for_peer(
 9154                    project_transaction,
 9155                    sender_id,
 9156                    cx,
 9157                )
 9158            })
 9159        })?;
 9160        Ok(proto::ApplyCodeActionResponse {
 9161            transaction: Some(project_transaction),
 9162        })
 9163    }
 9164
 9165    async fn handle_register_buffer_with_language_servers(
 9166        this: Entity<Self>,
 9167        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9168        mut cx: AsyncApp,
 9169    ) -> Result<proto::Ack> {
 9170        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9171        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9172        this.update(&mut cx, |this, cx| {
 9173            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9174                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9175                    project_id: upstream_project_id,
 9176                    buffer_id: buffer_id.to_proto(),
 9177                    only_servers: envelope.payload.only_servers,
 9178                });
 9179            }
 9180
 9181            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9182                anyhow::bail!("buffer is not open");
 9183            };
 9184
 9185            let handle = this.register_buffer_with_language_servers(
 9186                &buffer,
 9187                envelope
 9188                    .payload
 9189                    .only_servers
 9190                    .into_iter()
 9191                    .filter_map(|selector| {
 9192                        Some(match selector.selector? {
 9193                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9194                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9195                            }
 9196                            proto::language_server_selector::Selector::Name(name) => {
 9197                                LanguageServerSelector::Name(LanguageServerName(
 9198                                    SharedString::from(name),
 9199                                ))
 9200                            }
 9201                        })
 9202                    })
 9203                    .collect(),
 9204                false,
 9205                cx,
 9206            );
 9207            this.buffer_store().update(cx, |buffer_store, _| {
 9208                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9209            });
 9210
 9211            Ok(())
 9212        })??;
 9213        Ok(proto::Ack {})
 9214    }
 9215
 9216    async fn handle_rename_project_entry(
 9217        this: Entity<Self>,
 9218        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9219        mut cx: AsyncApp,
 9220    ) -> Result<proto::ProjectEntryResponse> {
 9221        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9222        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9223        let new_path =
 9224            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9225
 9226        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9227            .update(&mut cx, |this, cx| {
 9228                let (worktree, entry) = this
 9229                    .worktree_store
 9230                    .read(cx)
 9231                    .worktree_and_entry_for_id(entry_id, cx)?;
 9232                let new_worktree = this
 9233                    .worktree_store
 9234                    .read(cx)
 9235                    .worktree_for_id(new_worktree_id, cx)?;
 9236                Some((
 9237                    this.worktree_store.clone(),
 9238                    worktree,
 9239                    new_worktree,
 9240                    entry.clone(),
 9241                ))
 9242            })?
 9243            .context("worktree not found")?;
 9244        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9245            (worktree.absolutize(&old_entry.path), worktree.id())
 9246        })?;
 9247        let new_abs_path =
 9248            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 9249
 9250        let _transaction = Self::will_rename_entry(
 9251            this.downgrade(),
 9252            old_worktree_id,
 9253            &old_abs_path,
 9254            &new_abs_path,
 9255            old_entry.is_dir(),
 9256            cx.clone(),
 9257        )
 9258        .await;
 9259        let response = WorktreeStore::handle_rename_project_entry(
 9260            worktree_store,
 9261            envelope.payload,
 9262            cx.clone(),
 9263        )
 9264        .await;
 9265        this.read_with(&cx, |this, _| {
 9266            this.did_rename_entry(
 9267                old_worktree_id,
 9268                &old_abs_path,
 9269                &new_abs_path,
 9270                old_entry.is_dir(),
 9271            );
 9272        })
 9273        .ok();
 9274        response
 9275    }
 9276
 9277    async fn handle_update_diagnostic_summary(
 9278        this: Entity<Self>,
 9279        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9280        mut cx: AsyncApp,
 9281    ) -> Result<()> {
 9282        this.update(&mut cx, |lsp_store, cx| {
 9283            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9284            let mut updated_diagnostics_paths = HashMap::default();
 9285            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9286            for message_summary in envelope
 9287                .payload
 9288                .summary
 9289                .into_iter()
 9290                .chain(envelope.payload.more_summaries)
 9291            {
 9292                let project_path = ProjectPath {
 9293                    worktree_id,
 9294                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9295                };
 9296                let path = project_path.path.clone();
 9297                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9298                let summary = DiagnosticSummary {
 9299                    error_count: message_summary.error_count as usize,
 9300                    warning_count: message_summary.warning_count as usize,
 9301                };
 9302
 9303                if summary.is_empty() {
 9304                    if let Some(worktree_summaries) =
 9305                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9306                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9307                    {
 9308                        summaries.remove(&server_id);
 9309                        if summaries.is_empty() {
 9310                            worktree_summaries.remove(&path);
 9311                        }
 9312                    }
 9313                } else {
 9314                    lsp_store
 9315                        .diagnostic_summaries
 9316                        .entry(worktree_id)
 9317                        .or_default()
 9318                        .entry(path)
 9319                        .or_default()
 9320                        .insert(server_id, summary);
 9321                }
 9322
 9323                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9324                    match &mut diagnostics_summary {
 9325                        Some(diagnostics_summary) => {
 9326                            diagnostics_summary
 9327                                .more_summaries
 9328                                .push(proto::DiagnosticSummary {
 9329                                    path: project_path.path.as_ref().to_proto(),
 9330                                    language_server_id: server_id.0 as u64,
 9331                                    error_count: summary.error_count as u32,
 9332                                    warning_count: summary.warning_count as u32,
 9333                                })
 9334                        }
 9335                        None => {
 9336                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9337                                project_id: *project_id,
 9338                                worktree_id: worktree_id.to_proto(),
 9339                                summary: Some(proto::DiagnosticSummary {
 9340                                    path: project_path.path.as_ref().to_proto(),
 9341                                    language_server_id: server_id.0 as u64,
 9342                                    error_count: summary.error_count as u32,
 9343                                    warning_count: summary.warning_count as u32,
 9344                                }),
 9345                                more_summaries: Vec::new(),
 9346                            })
 9347                        }
 9348                    }
 9349                }
 9350                updated_diagnostics_paths
 9351                    .entry(server_id)
 9352                    .or_insert_with(Vec::new)
 9353                    .push(project_path);
 9354            }
 9355
 9356            if let Some((diagnostics_summary, (downstream_client, _))) =
 9357                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9358            {
 9359                downstream_client.send(diagnostics_summary).log_err();
 9360            }
 9361            for (server_id, paths) in updated_diagnostics_paths {
 9362                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9363            }
 9364            Ok(())
 9365        })?
 9366    }
 9367
 9368    async fn handle_start_language_server(
 9369        lsp_store: Entity<Self>,
 9370        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9371        mut cx: AsyncApp,
 9372    ) -> Result<()> {
 9373        let server = envelope.payload.server.context("invalid server")?;
 9374        let server_capabilities =
 9375            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9376                .with_context(|| {
 9377                    format!(
 9378                        "incorrect server capabilities {}",
 9379                        envelope.payload.capabilities
 9380                    )
 9381                })?;
 9382        lsp_store.update(&mut cx, |lsp_store, cx| {
 9383            let server_id = LanguageServerId(server.id as usize);
 9384            let server_name = LanguageServerName::from_proto(server.name.clone());
 9385            lsp_store
 9386                .lsp_server_capabilities
 9387                .insert(server_id, server_capabilities);
 9388            lsp_store.language_server_statuses.insert(
 9389                server_id,
 9390                LanguageServerStatus {
 9391                    name: server_name.clone(),
 9392                    pending_work: Default::default(),
 9393                    has_pending_diagnostic_updates: false,
 9394                    progress_tokens: Default::default(),
 9395                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9396                    binary: None,
 9397                    configuration: None,
 9398                    workspace_folders: BTreeSet::new(),
 9399                },
 9400            );
 9401            cx.emit(LspStoreEvent::LanguageServerAdded(
 9402                server_id,
 9403                server_name,
 9404                server.worktree_id.map(WorktreeId::from_proto),
 9405            ));
 9406            cx.notify();
 9407        })?;
 9408        Ok(())
 9409    }
 9410
 9411    async fn handle_update_language_server(
 9412        lsp_store: Entity<Self>,
 9413        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9414        mut cx: AsyncApp,
 9415    ) -> Result<()> {
 9416        lsp_store.update(&mut cx, |lsp_store, cx| {
 9417            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9418
 9419            match envelope.payload.variant.context("invalid variant")? {
 9420                proto::update_language_server::Variant::WorkStart(payload) => {
 9421                    lsp_store.on_lsp_work_start(
 9422                        language_server_id,
 9423                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9424                            .context("invalid progress token value")?,
 9425                        LanguageServerProgress {
 9426                            title: payload.title,
 9427                            is_disk_based_diagnostics_progress: false,
 9428                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9429                            message: payload.message,
 9430                            percentage: payload.percentage.map(|p| p as usize),
 9431                            last_update_at: cx.background_executor().now(),
 9432                        },
 9433                        cx,
 9434                    );
 9435                }
 9436                proto::update_language_server::Variant::WorkProgress(payload) => {
 9437                    lsp_store.on_lsp_work_progress(
 9438                        language_server_id,
 9439                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9440                            .context("invalid progress token value")?,
 9441                        LanguageServerProgress {
 9442                            title: None,
 9443                            is_disk_based_diagnostics_progress: false,
 9444                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9445                            message: payload.message,
 9446                            percentage: payload.percentage.map(|p| p as usize),
 9447                            last_update_at: cx.background_executor().now(),
 9448                        },
 9449                        cx,
 9450                    );
 9451                }
 9452
 9453                proto::update_language_server::Variant::WorkEnd(payload) => {
 9454                    lsp_store.on_lsp_work_end(
 9455                        language_server_id,
 9456                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9457                            .context("invalid progress token value")?,
 9458                        cx,
 9459                    );
 9460                }
 9461
 9462                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9463                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9464                }
 9465
 9466                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9467                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9468                }
 9469
 9470                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9471                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9472                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9473                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9474                        language_server_id,
 9475                        name: envelope
 9476                            .payload
 9477                            .server_name
 9478                            .map(SharedString::new)
 9479                            .map(LanguageServerName),
 9480                        message: non_lsp,
 9481                    });
 9482                }
 9483            }
 9484
 9485            Ok(())
 9486        })?
 9487    }
 9488
 9489    async fn handle_language_server_log(
 9490        this: Entity<Self>,
 9491        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9492        mut cx: AsyncApp,
 9493    ) -> Result<()> {
 9494        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9495        let log_type = envelope
 9496            .payload
 9497            .log_type
 9498            .map(LanguageServerLogType::from_proto)
 9499            .context("invalid language server log type")?;
 9500
 9501        let message = envelope.payload.message;
 9502
 9503        this.update(&mut cx, |_, cx| {
 9504            cx.emit(LspStoreEvent::LanguageServerLog(
 9505                language_server_id,
 9506                log_type,
 9507                message,
 9508            ));
 9509        })
 9510    }
 9511
 9512    async fn handle_lsp_ext_cancel_flycheck(
 9513        lsp_store: Entity<Self>,
 9514        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9515        cx: AsyncApp,
 9516    ) -> Result<proto::Ack> {
 9517        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9518        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9519            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9520                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9521            } else {
 9522                None
 9523            }
 9524        })?;
 9525        if let Some(task) = task {
 9526            task.context("handling lsp ext cancel flycheck")?;
 9527        }
 9528
 9529        Ok(proto::Ack {})
 9530    }
 9531
 9532    async fn handle_lsp_ext_run_flycheck(
 9533        lsp_store: Entity<Self>,
 9534        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9535        mut cx: AsyncApp,
 9536    ) -> Result<proto::Ack> {
 9537        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9538        lsp_store.update(&mut cx, |lsp_store, cx| {
 9539            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9540                let text_document = if envelope.payload.current_file_only {
 9541                    let buffer_id = envelope
 9542                        .payload
 9543                        .buffer_id
 9544                        .map(|id| BufferId::new(id))
 9545                        .transpose()?;
 9546                    buffer_id
 9547                        .and_then(|buffer_id| {
 9548                            lsp_store
 9549                                .buffer_store()
 9550                                .read(cx)
 9551                                .get(buffer_id)
 9552                                .and_then(|buffer| {
 9553                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9554                                })
 9555                                .map(|path| make_text_document_identifier(&path))
 9556                        })
 9557                        .transpose()?
 9558                } else {
 9559                    None
 9560                };
 9561                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9562                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9563                )?;
 9564            }
 9565            anyhow::Ok(())
 9566        })??;
 9567
 9568        Ok(proto::Ack {})
 9569    }
 9570
 9571    async fn handle_lsp_ext_clear_flycheck(
 9572        lsp_store: Entity<Self>,
 9573        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9574        cx: AsyncApp,
 9575    ) -> Result<proto::Ack> {
 9576        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9577        lsp_store
 9578            .read_with(&cx, |lsp_store, _| {
 9579                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9580                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9581                } else {
 9582                    None
 9583                }
 9584            })
 9585            .context("handling lsp ext clear flycheck")?;
 9586
 9587        Ok(proto::Ack {})
 9588    }
 9589
 9590    pub fn disk_based_diagnostics_started(
 9591        &mut self,
 9592        language_server_id: LanguageServerId,
 9593        cx: &mut Context<Self>,
 9594    ) {
 9595        if let Some(language_server_status) =
 9596            self.language_server_statuses.get_mut(&language_server_id)
 9597        {
 9598            language_server_status.has_pending_diagnostic_updates = true;
 9599        }
 9600
 9601        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9602        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9603            language_server_id,
 9604            name: self
 9605                .language_server_adapter_for_id(language_server_id)
 9606                .map(|adapter| adapter.name()),
 9607            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9608                Default::default(),
 9609            ),
 9610        })
 9611    }
 9612
 9613    pub fn disk_based_diagnostics_finished(
 9614        &mut self,
 9615        language_server_id: LanguageServerId,
 9616        cx: &mut Context<Self>,
 9617    ) {
 9618        if let Some(language_server_status) =
 9619            self.language_server_statuses.get_mut(&language_server_id)
 9620        {
 9621            language_server_status.has_pending_diagnostic_updates = false;
 9622        }
 9623
 9624        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9625        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9626            language_server_id,
 9627            name: self
 9628                .language_server_adapter_for_id(language_server_id)
 9629                .map(|adapter| adapter.name()),
 9630            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9631                Default::default(),
 9632            ),
 9633        })
 9634    }
 9635
 9636    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9637    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9638    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9639    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9640    // the language server might take some time to publish diagnostics.
 9641    fn simulate_disk_based_diagnostics_events_if_needed(
 9642        &mut self,
 9643        language_server_id: LanguageServerId,
 9644        cx: &mut Context<Self>,
 9645    ) {
 9646        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9647
 9648        let Some(LanguageServerState::Running {
 9649            simulate_disk_based_diagnostics_completion,
 9650            adapter,
 9651            ..
 9652        }) = self
 9653            .as_local_mut()
 9654            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9655        else {
 9656            return;
 9657        };
 9658
 9659        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9660            return;
 9661        }
 9662
 9663        let prev_task =
 9664            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9665                cx.background_executor()
 9666                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9667                    .await;
 9668
 9669                this.update(cx, |this, cx| {
 9670                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9671
 9672                    if let Some(LanguageServerState::Running {
 9673                        simulate_disk_based_diagnostics_completion,
 9674                        ..
 9675                    }) = this.as_local_mut().and_then(|local_store| {
 9676                        local_store.language_servers.get_mut(&language_server_id)
 9677                    }) {
 9678                        *simulate_disk_based_diagnostics_completion = None;
 9679                    }
 9680                })
 9681                .ok();
 9682            }));
 9683
 9684        if prev_task.is_none() {
 9685            self.disk_based_diagnostics_started(language_server_id, cx);
 9686        }
 9687    }
 9688
 9689    pub fn language_server_statuses(
 9690        &self,
 9691    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9692        self.language_server_statuses
 9693            .iter()
 9694            .map(|(key, value)| (*key, value))
 9695    }
 9696
 9697    pub(super) fn did_rename_entry(
 9698        &self,
 9699        worktree_id: WorktreeId,
 9700        old_path: &Path,
 9701        new_path: &Path,
 9702        is_dir: bool,
 9703    ) {
 9704        maybe!({
 9705            let local_store = self.as_local()?;
 9706
 9707            let old_uri = lsp::Uri::from_file_path(old_path)
 9708                .ok()
 9709                .map(|uri| uri.to_string())?;
 9710            let new_uri = lsp::Uri::from_file_path(new_path)
 9711                .ok()
 9712                .map(|uri| uri.to_string())?;
 9713
 9714            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9715                let Some(filter) = local_store
 9716                    .language_server_paths_watched_for_rename
 9717                    .get(&language_server.server_id())
 9718                else {
 9719                    continue;
 9720                };
 9721
 9722                if filter.should_send_did_rename(&old_uri, is_dir) {
 9723                    language_server
 9724                        .notify::<DidRenameFiles>(RenameFilesParams {
 9725                            files: vec![FileRename {
 9726                                old_uri: old_uri.clone(),
 9727                                new_uri: new_uri.clone(),
 9728                            }],
 9729                        })
 9730                        .ok();
 9731                }
 9732            }
 9733            Some(())
 9734        });
 9735    }
 9736
 9737    pub(super) fn will_rename_entry(
 9738        this: WeakEntity<Self>,
 9739        worktree_id: WorktreeId,
 9740        old_path: &Path,
 9741        new_path: &Path,
 9742        is_dir: bool,
 9743        cx: AsyncApp,
 9744    ) -> Task<ProjectTransaction> {
 9745        let old_uri = lsp::Uri::from_file_path(old_path)
 9746            .ok()
 9747            .map(|uri| uri.to_string());
 9748        let new_uri = lsp::Uri::from_file_path(new_path)
 9749            .ok()
 9750            .map(|uri| uri.to_string());
 9751        cx.spawn(async move |cx| {
 9752            let mut tasks = vec![];
 9753            this.update(cx, |this, cx| {
 9754                let local_store = this.as_local()?;
 9755                let old_uri = old_uri?;
 9756                let new_uri = new_uri?;
 9757                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9758                    let Some(filter) = local_store
 9759                        .language_server_paths_watched_for_rename
 9760                        .get(&language_server.server_id())
 9761                    else {
 9762                        continue;
 9763                    };
 9764
 9765                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9766                        let apply_edit = cx.spawn({
 9767                            let old_uri = old_uri.clone();
 9768                            let new_uri = new_uri.clone();
 9769                            let language_server = language_server.clone();
 9770                            async move |this, cx| {
 9771                                let edit = language_server
 9772                                    .request::<WillRenameFiles>(RenameFilesParams {
 9773                                        files: vec![FileRename { old_uri, new_uri }],
 9774                                    })
 9775                                    .await
 9776                                    .into_response()
 9777                                    .context("will rename files")
 9778                                    .log_err()
 9779                                    .flatten()?;
 9780
 9781                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9782                                    this.upgrade()?,
 9783                                    edit,
 9784                                    false,
 9785                                    language_server.clone(),
 9786                                    cx,
 9787                                )
 9788                                .await
 9789                                .ok()?;
 9790                                Some(transaction)
 9791                            }
 9792                        });
 9793                        tasks.push(apply_edit);
 9794                    }
 9795                }
 9796                Some(())
 9797            })
 9798            .ok()
 9799            .flatten();
 9800            let mut merged_transaction = ProjectTransaction::default();
 9801            for task in tasks {
 9802                // Await on tasks sequentially so that the order of application of edits is deterministic
 9803                // (at least with regards to the order of registration of language servers)
 9804                if let Some(transaction) = task.await {
 9805                    for (buffer, buffer_transaction) in transaction.0 {
 9806                        merged_transaction.0.insert(buffer, buffer_transaction);
 9807                    }
 9808                }
 9809            }
 9810            merged_transaction
 9811        })
 9812    }
 9813
 9814    fn lsp_notify_abs_paths_changed(
 9815        &mut self,
 9816        server_id: LanguageServerId,
 9817        changes: Vec<PathEvent>,
 9818    ) {
 9819        maybe!({
 9820            let server = self.language_server_for_id(server_id)?;
 9821            let changes = changes
 9822                .into_iter()
 9823                .filter_map(|event| {
 9824                    let typ = match event.kind? {
 9825                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9826                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9827                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9828                    };
 9829                    Some(lsp::FileEvent {
 9830                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9831                        typ,
 9832                    })
 9833                })
 9834                .collect::<Vec<_>>();
 9835            if !changes.is_empty() {
 9836                server
 9837                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9838                        lsp::DidChangeWatchedFilesParams { changes },
 9839                    )
 9840                    .ok();
 9841            }
 9842            Some(())
 9843        });
 9844    }
 9845
 9846    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9847        self.as_local()?.language_server_for_id(id)
 9848    }
 9849
 9850    fn on_lsp_progress(
 9851        &mut self,
 9852        progress_params: lsp::ProgressParams,
 9853        language_server_id: LanguageServerId,
 9854        disk_based_diagnostics_progress_token: Option<String>,
 9855        cx: &mut Context<Self>,
 9856    ) {
 9857        match progress_params.value {
 9858            lsp::ProgressParamsValue::WorkDone(progress) => {
 9859                self.handle_work_done_progress(
 9860                    progress,
 9861                    language_server_id,
 9862                    disk_based_diagnostics_progress_token,
 9863                    ProgressToken::from_lsp(progress_params.token),
 9864                    cx,
 9865                );
 9866            }
 9867            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9868                let registration_id = match progress_params.token {
 9869                    lsp::NumberOrString::Number(_) => None,
 9870                    lsp::NumberOrString::String(token) => token
 9871                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9872                        .map(|(_, id)| id.to_owned()),
 9873                };
 9874                if let Some(LanguageServerState::Running {
 9875                    workspace_diagnostics_refresh_tasks,
 9876                    ..
 9877                }) = self
 9878                    .as_local_mut()
 9879                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9880                    && let Some(workspace_diagnostics) =
 9881                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9882                {
 9883                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9884                    self.apply_workspace_diagnostic_report(
 9885                        language_server_id,
 9886                        report,
 9887                        registration_id.map(SharedString::from),
 9888                        cx,
 9889                    )
 9890                }
 9891            }
 9892        }
 9893    }
 9894
 9895    fn handle_work_done_progress(
 9896        &mut self,
 9897        progress: lsp::WorkDoneProgress,
 9898        language_server_id: LanguageServerId,
 9899        disk_based_diagnostics_progress_token: Option<String>,
 9900        token: ProgressToken,
 9901        cx: &mut Context<Self>,
 9902    ) {
 9903        let language_server_status =
 9904            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9905                status
 9906            } else {
 9907                return;
 9908            };
 9909
 9910        if !language_server_status.progress_tokens.contains(&token) {
 9911            return;
 9912        }
 9913
 9914        let is_disk_based_diagnostics_progress =
 9915            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9916                (&disk_based_diagnostics_progress_token, &token)
 9917            {
 9918                token.starts_with(disk_based_token)
 9919            } else {
 9920                false
 9921            };
 9922
 9923        match progress {
 9924            lsp::WorkDoneProgress::Begin(report) => {
 9925                if is_disk_based_diagnostics_progress {
 9926                    self.disk_based_diagnostics_started(language_server_id, cx);
 9927                }
 9928                self.on_lsp_work_start(
 9929                    language_server_id,
 9930                    token.clone(),
 9931                    LanguageServerProgress {
 9932                        title: Some(report.title),
 9933                        is_disk_based_diagnostics_progress,
 9934                        is_cancellable: report.cancellable.unwrap_or(false),
 9935                        message: report.message.clone(),
 9936                        percentage: report.percentage.map(|p| p as usize),
 9937                        last_update_at: cx.background_executor().now(),
 9938                    },
 9939                    cx,
 9940                );
 9941            }
 9942            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9943                language_server_id,
 9944                token,
 9945                LanguageServerProgress {
 9946                    title: None,
 9947                    is_disk_based_diagnostics_progress,
 9948                    is_cancellable: report.cancellable.unwrap_or(false),
 9949                    message: report.message,
 9950                    percentage: report.percentage.map(|p| p as usize),
 9951                    last_update_at: cx.background_executor().now(),
 9952                },
 9953                cx,
 9954            ),
 9955            lsp::WorkDoneProgress::End(_) => {
 9956                language_server_status.progress_tokens.remove(&token);
 9957                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9958                if is_disk_based_diagnostics_progress {
 9959                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9960                }
 9961            }
 9962        }
 9963    }
 9964
 9965    fn on_lsp_work_start(
 9966        &mut self,
 9967        language_server_id: LanguageServerId,
 9968        token: ProgressToken,
 9969        progress: LanguageServerProgress,
 9970        cx: &mut Context<Self>,
 9971    ) {
 9972        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9973            status.pending_work.insert(token.clone(), progress.clone());
 9974            cx.notify();
 9975        }
 9976        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9977            language_server_id,
 9978            name: self
 9979                .language_server_adapter_for_id(language_server_id)
 9980                .map(|adapter| adapter.name()),
 9981            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9982                token: Some(token.to_proto()),
 9983                title: progress.title,
 9984                message: progress.message,
 9985                percentage: progress.percentage.map(|p| p as u32),
 9986                is_cancellable: Some(progress.is_cancellable),
 9987            }),
 9988        })
 9989    }
 9990
 9991    fn on_lsp_work_progress(
 9992        &mut self,
 9993        language_server_id: LanguageServerId,
 9994        token: ProgressToken,
 9995        progress: LanguageServerProgress,
 9996        cx: &mut Context<Self>,
 9997    ) {
 9998        let mut did_update = false;
 9999        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10000            match status.pending_work.entry(token.clone()) {
10001                btree_map::Entry::Vacant(entry) => {
10002                    entry.insert(progress.clone());
10003                    did_update = true;
10004                }
10005                btree_map::Entry::Occupied(mut entry) => {
10006                    let entry = entry.get_mut();
10007                    if (progress.last_update_at - entry.last_update_at)
10008                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10009                    {
10010                        entry.last_update_at = progress.last_update_at;
10011                        if progress.message.is_some() {
10012                            entry.message = progress.message.clone();
10013                        }
10014                        if progress.percentage.is_some() {
10015                            entry.percentage = progress.percentage;
10016                        }
10017                        if progress.is_cancellable != entry.is_cancellable {
10018                            entry.is_cancellable = progress.is_cancellable;
10019                        }
10020                        did_update = true;
10021                    }
10022                }
10023            }
10024        }
10025
10026        if did_update {
10027            cx.emit(LspStoreEvent::LanguageServerUpdate {
10028                language_server_id,
10029                name: self
10030                    .language_server_adapter_for_id(language_server_id)
10031                    .map(|adapter| adapter.name()),
10032                message: proto::update_language_server::Variant::WorkProgress(
10033                    proto::LspWorkProgress {
10034                        token: Some(token.to_proto()),
10035                        message: progress.message,
10036                        percentage: progress.percentage.map(|p| p as u32),
10037                        is_cancellable: Some(progress.is_cancellable),
10038                    },
10039                ),
10040            })
10041        }
10042    }
10043
10044    fn on_lsp_work_end(
10045        &mut self,
10046        language_server_id: LanguageServerId,
10047        token: ProgressToken,
10048        cx: &mut Context<Self>,
10049    ) {
10050        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10051            if let Some(work) = status.pending_work.remove(&token)
10052                && !work.is_disk_based_diagnostics_progress
10053            {
10054                cx.emit(LspStoreEvent::RefreshInlayHints {
10055                    server_id: language_server_id,
10056                    request_id: None,
10057                });
10058            }
10059            cx.notify();
10060        }
10061
10062        cx.emit(LspStoreEvent::LanguageServerUpdate {
10063            language_server_id,
10064            name: self
10065                .language_server_adapter_for_id(language_server_id)
10066                .map(|adapter| adapter.name()),
10067            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10068                token: Some(token.to_proto()),
10069            }),
10070        })
10071    }
10072
10073    pub async fn handle_resolve_completion_documentation(
10074        this: Entity<Self>,
10075        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10076        mut cx: AsyncApp,
10077    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10078        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10079
10080        let completion = this
10081            .read_with(&cx, |this, cx| {
10082                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10083                let server = this
10084                    .language_server_for_id(id)
10085                    .with_context(|| format!("No language server {id}"))?;
10086
10087                anyhow::Ok(cx.background_spawn(async move {
10088                    let can_resolve = server
10089                        .capabilities()
10090                        .completion_provider
10091                        .as_ref()
10092                        .and_then(|options| options.resolve_provider)
10093                        .unwrap_or(false);
10094                    if can_resolve {
10095                        server
10096                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
10097                            .await
10098                            .into_response()
10099                            .context("resolve completion item")
10100                    } else {
10101                        anyhow::Ok(lsp_completion)
10102                    }
10103                }))
10104            })??
10105            .await?;
10106
10107        let mut documentation_is_markdown = false;
10108        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10109        let documentation = match completion.documentation {
10110            Some(lsp::Documentation::String(text)) => text,
10111
10112            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10113                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10114                value
10115            }
10116
10117            _ => String::new(),
10118        };
10119
10120        // If we have a new buffer_id, that means we're talking to a new client
10121        // and want to check for new text_edits in the completion too.
10122        let mut old_replace_start = None;
10123        let mut old_replace_end = None;
10124        let mut old_insert_start = None;
10125        let mut old_insert_end = None;
10126        let mut new_text = String::default();
10127        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10128            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10129                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10130                anyhow::Ok(buffer.read(cx).snapshot())
10131            })??;
10132
10133            if let Some(text_edit) = completion.text_edit.as_ref() {
10134                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10135
10136                if let Some(mut edit) = edit {
10137                    LineEnding::normalize(&mut edit.new_text);
10138
10139                    new_text = edit.new_text;
10140                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10141                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10142                    if let Some(insert_range) = edit.insert_range {
10143                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10144                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10145                    }
10146                }
10147            }
10148        }
10149
10150        Ok(proto::ResolveCompletionDocumentationResponse {
10151            documentation,
10152            documentation_is_markdown,
10153            old_replace_start,
10154            old_replace_end,
10155            new_text,
10156            lsp_completion,
10157            old_insert_start,
10158            old_insert_end,
10159        })
10160    }
10161
10162    async fn handle_on_type_formatting(
10163        this: Entity<Self>,
10164        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10165        mut cx: AsyncApp,
10166    ) -> Result<proto::OnTypeFormattingResponse> {
10167        let on_type_formatting = this.update(&mut cx, |this, cx| {
10168            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10169            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10170            let position = envelope
10171                .payload
10172                .position
10173                .and_then(deserialize_anchor)
10174                .context("invalid position")?;
10175            anyhow::Ok(this.apply_on_type_formatting(
10176                buffer,
10177                position,
10178                envelope.payload.trigger.clone(),
10179                cx,
10180            ))
10181        })??;
10182
10183        let transaction = on_type_formatting
10184            .await?
10185            .as_ref()
10186            .map(language::proto::serialize_transaction);
10187        Ok(proto::OnTypeFormattingResponse { transaction })
10188    }
10189
10190    async fn handle_refresh_inlay_hints(
10191        lsp_store: Entity<Self>,
10192        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10193        mut cx: AsyncApp,
10194    ) -> Result<proto::Ack> {
10195        lsp_store.update(&mut cx, |_, cx| {
10196            cx.emit(LspStoreEvent::RefreshInlayHints {
10197                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10198                request_id: envelope.payload.request_id.map(|id| id as usize),
10199            });
10200        })?;
10201        Ok(proto::Ack {})
10202    }
10203
10204    async fn handle_pull_workspace_diagnostics(
10205        lsp_store: Entity<Self>,
10206        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10207        mut cx: AsyncApp,
10208    ) -> Result<proto::Ack> {
10209        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10210        lsp_store.update(&mut cx, |lsp_store, _| {
10211            lsp_store.pull_workspace_diagnostics(server_id);
10212        })?;
10213        Ok(proto::Ack {})
10214    }
10215
10216    async fn handle_get_color_presentation(
10217        lsp_store: Entity<Self>,
10218        envelope: TypedEnvelope<proto::GetColorPresentation>,
10219        mut cx: AsyncApp,
10220    ) -> Result<proto::GetColorPresentationResponse> {
10221        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10222        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10223            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10224        })??;
10225
10226        let color = envelope
10227            .payload
10228            .color
10229            .context("invalid color resolve request")?;
10230        let start = color
10231            .lsp_range_start
10232            .context("invalid color resolve request")?;
10233        let end = color
10234            .lsp_range_end
10235            .context("invalid color resolve request")?;
10236
10237        let color = DocumentColor {
10238            lsp_range: lsp::Range {
10239                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10240                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10241            },
10242            color: lsp::Color {
10243                red: color.red,
10244                green: color.green,
10245                blue: color.blue,
10246                alpha: color.alpha,
10247            },
10248            resolved: false,
10249            color_presentations: Vec::new(),
10250        };
10251        let resolved_color = lsp_store
10252            .update(&mut cx, |lsp_store, cx| {
10253                lsp_store.resolve_color_presentation(
10254                    color,
10255                    buffer.clone(),
10256                    LanguageServerId(envelope.payload.server_id as usize),
10257                    cx,
10258                )
10259            })?
10260            .await
10261            .context("resolving color presentation")?;
10262
10263        Ok(proto::GetColorPresentationResponse {
10264            presentations: resolved_color
10265                .color_presentations
10266                .into_iter()
10267                .map(|presentation| proto::ColorPresentation {
10268                    label: presentation.label.to_string(),
10269                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10270                    additional_text_edits: presentation
10271                        .additional_text_edits
10272                        .into_iter()
10273                        .map(serialize_lsp_edit)
10274                        .collect(),
10275                })
10276                .collect(),
10277        })
10278    }
10279
10280    async fn handle_resolve_inlay_hint(
10281        lsp_store: Entity<Self>,
10282        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10283        mut cx: AsyncApp,
10284    ) -> Result<proto::ResolveInlayHintResponse> {
10285        let proto_hint = envelope
10286            .payload
10287            .hint
10288            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10289        let hint = InlayHints::proto_to_project_hint(proto_hint)
10290            .context("resolved proto inlay hint conversion")?;
10291        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10292            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10293            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10294        })??;
10295        let response_hint = lsp_store
10296            .update(&mut cx, |lsp_store, cx| {
10297                lsp_store.resolve_inlay_hint(
10298                    hint,
10299                    buffer,
10300                    LanguageServerId(envelope.payload.language_server_id as usize),
10301                    cx,
10302                )
10303            })?
10304            .await
10305            .context("inlay hints fetch")?;
10306        Ok(proto::ResolveInlayHintResponse {
10307            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10308        })
10309    }
10310
10311    async fn handle_refresh_code_lens(
10312        this: Entity<Self>,
10313        _: TypedEnvelope<proto::RefreshCodeLens>,
10314        mut cx: AsyncApp,
10315    ) -> Result<proto::Ack> {
10316        this.update(&mut cx, |_, cx| {
10317            cx.emit(LspStoreEvent::RefreshCodeLens);
10318        })?;
10319        Ok(proto::Ack {})
10320    }
10321
10322    async fn handle_open_buffer_for_symbol(
10323        this: Entity<Self>,
10324        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10325        mut cx: AsyncApp,
10326    ) -> Result<proto::OpenBufferForSymbolResponse> {
10327        let peer_id = envelope.original_sender_id().unwrap_or_default();
10328        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10329        let symbol = Self::deserialize_symbol(symbol)?;
10330        this.read_with(&cx, |this, _| {
10331            if let SymbolLocation::OutsideProject {
10332                abs_path,
10333                signature,
10334            } = &symbol.path
10335            {
10336                let new_signature = this.symbol_signature(&abs_path);
10337                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10338            }
10339            Ok(())
10340        })??;
10341        let buffer = this
10342            .update(&mut cx, |this, cx| {
10343                this.open_buffer_for_symbol(
10344                    &Symbol {
10345                        language_server_name: symbol.language_server_name,
10346                        source_worktree_id: symbol.source_worktree_id,
10347                        source_language_server_id: symbol.source_language_server_id,
10348                        path: symbol.path,
10349                        name: symbol.name,
10350                        kind: symbol.kind,
10351                        range: symbol.range,
10352                        label: CodeLabel::default(),
10353                    },
10354                    cx,
10355                )
10356            })?
10357            .await?;
10358
10359        this.update(&mut cx, |this, cx| {
10360            let is_private = buffer
10361                .read(cx)
10362                .file()
10363                .map(|f| f.is_private())
10364                .unwrap_or_default();
10365            if is_private {
10366                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10367            } else {
10368                this.buffer_store
10369                    .update(cx, |buffer_store, cx| {
10370                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10371                    })
10372                    .detach_and_log_err(cx);
10373                let buffer_id = buffer.read(cx).remote_id().to_proto();
10374                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10375            }
10376        })?
10377    }
10378
10379    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10380        let mut hasher = Sha256::new();
10381        hasher.update(abs_path.to_string_lossy().as_bytes());
10382        hasher.update(self.nonce.to_be_bytes());
10383        hasher.finalize().as_slice().try_into().unwrap()
10384    }
10385
10386    pub async fn handle_get_project_symbols(
10387        this: Entity<Self>,
10388        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10389        mut cx: AsyncApp,
10390    ) -> Result<proto::GetProjectSymbolsResponse> {
10391        let symbols = this
10392            .update(&mut cx, |this, cx| {
10393                this.symbols(&envelope.payload.query, cx)
10394            })?
10395            .await?;
10396
10397        Ok(proto::GetProjectSymbolsResponse {
10398            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10399        })
10400    }
10401
10402    pub async fn handle_restart_language_servers(
10403        this: Entity<Self>,
10404        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10405        mut cx: AsyncApp,
10406    ) -> Result<proto::Ack> {
10407        this.update(&mut cx, |lsp_store, cx| {
10408            let buffers =
10409                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10410            lsp_store.restart_language_servers_for_buffers(
10411                buffers,
10412                envelope
10413                    .payload
10414                    .only_servers
10415                    .into_iter()
10416                    .filter_map(|selector| {
10417                        Some(match selector.selector? {
10418                            proto::language_server_selector::Selector::ServerId(server_id) => {
10419                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10420                            }
10421                            proto::language_server_selector::Selector::Name(name) => {
10422                                LanguageServerSelector::Name(LanguageServerName(
10423                                    SharedString::from(name),
10424                                ))
10425                            }
10426                        })
10427                    })
10428                    .collect(),
10429                cx,
10430            );
10431        })?;
10432
10433        Ok(proto::Ack {})
10434    }
10435
10436    pub async fn handle_stop_language_servers(
10437        lsp_store: Entity<Self>,
10438        envelope: TypedEnvelope<proto::StopLanguageServers>,
10439        mut cx: AsyncApp,
10440    ) -> Result<proto::Ack> {
10441        lsp_store.update(&mut cx, |lsp_store, cx| {
10442            if envelope.payload.all
10443                && envelope.payload.also_servers.is_empty()
10444                && envelope.payload.buffer_ids.is_empty()
10445            {
10446                lsp_store.stop_all_language_servers(cx);
10447            } else {
10448                let buffers =
10449                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10450                lsp_store
10451                    .stop_language_servers_for_buffers(
10452                        buffers,
10453                        envelope
10454                            .payload
10455                            .also_servers
10456                            .into_iter()
10457                            .filter_map(|selector| {
10458                                Some(match selector.selector? {
10459                                    proto::language_server_selector::Selector::ServerId(
10460                                        server_id,
10461                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10462                                        server_id,
10463                                    )),
10464                                    proto::language_server_selector::Selector::Name(name) => {
10465                                        LanguageServerSelector::Name(LanguageServerName(
10466                                            SharedString::from(name),
10467                                        ))
10468                                    }
10469                                })
10470                            })
10471                            .collect(),
10472                        cx,
10473                    )
10474                    .detach_and_log_err(cx);
10475            }
10476        })?;
10477
10478        Ok(proto::Ack {})
10479    }
10480
10481    pub async fn handle_cancel_language_server_work(
10482        lsp_store: Entity<Self>,
10483        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10484        mut cx: AsyncApp,
10485    ) -> Result<proto::Ack> {
10486        lsp_store.update(&mut cx, |lsp_store, cx| {
10487            if let Some(work) = envelope.payload.work {
10488                match work {
10489                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10490                        let buffers =
10491                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10492                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10493                    }
10494                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10495                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10496                        let token = work
10497                            .token
10498                            .map(|token| {
10499                                ProgressToken::from_proto(token)
10500                                    .context("invalid work progress token")
10501                            })
10502                            .transpose()?;
10503                        lsp_store.cancel_language_server_work(server_id, token, cx);
10504                    }
10505                }
10506            }
10507            anyhow::Ok(())
10508        })??;
10509
10510        Ok(proto::Ack {})
10511    }
10512
10513    fn buffer_ids_to_buffers(
10514        &mut self,
10515        buffer_ids: impl Iterator<Item = u64>,
10516        cx: &mut Context<Self>,
10517    ) -> Vec<Entity<Buffer>> {
10518        buffer_ids
10519            .into_iter()
10520            .flat_map(|buffer_id| {
10521                self.buffer_store
10522                    .read(cx)
10523                    .get(BufferId::new(buffer_id).log_err()?)
10524            })
10525            .collect::<Vec<_>>()
10526    }
10527
10528    async fn handle_apply_additional_edits_for_completion(
10529        this: Entity<Self>,
10530        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10531        mut cx: AsyncApp,
10532    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10533        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10534            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10535            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10536            let completion = Self::deserialize_completion(
10537                envelope.payload.completion.context("invalid completion")?,
10538            )?;
10539            anyhow::Ok((buffer, completion))
10540        })??;
10541
10542        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10543            this.apply_additional_edits_for_completion(
10544                buffer,
10545                Rc::new(RefCell::new(Box::new([Completion {
10546                    replace_range: completion.replace_range,
10547                    new_text: completion.new_text,
10548                    source: completion.source,
10549                    documentation: None,
10550                    label: CodeLabel::default(),
10551                    match_start: None,
10552                    snippet_deduplication_key: None,
10553                    insert_text_mode: None,
10554                    icon_path: None,
10555                    confirm: None,
10556                }]))),
10557                0,
10558                false,
10559                cx,
10560            )
10561        })?;
10562
10563        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10564            transaction: apply_additional_edits
10565                .await?
10566                .as_ref()
10567                .map(language::proto::serialize_transaction),
10568        })
10569    }
10570
10571    pub fn last_formatting_failure(&self) -> Option<&str> {
10572        self.last_formatting_failure.as_deref()
10573    }
10574
10575    pub fn reset_last_formatting_failure(&mut self) {
10576        self.last_formatting_failure = None;
10577    }
10578
10579    pub fn environment_for_buffer(
10580        &self,
10581        buffer: &Entity<Buffer>,
10582        cx: &mut Context<Self>,
10583    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10584        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10585            environment.update(cx, |env, cx| {
10586                env.buffer_environment(buffer, &self.worktree_store, cx)
10587            })
10588        } else {
10589            Task::ready(None).shared()
10590        }
10591    }
10592
10593    pub fn format(
10594        &mut self,
10595        buffers: HashSet<Entity<Buffer>>,
10596        target: LspFormatTarget,
10597        push_to_history: bool,
10598        trigger: FormatTrigger,
10599        cx: &mut Context<Self>,
10600    ) -> Task<anyhow::Result<ProjectTransaction>> {
10601        let logger = zlog::scoped!("format");
10602        if self.as_local().is_some() {
10603            zlog::trace!(logger => "Formatting locally");
10604            let logger = zlog::scoped!(logger => "local");
10605            let buffers = buffers
10606                .into_iter()
10607                .map(|buffer_handle| {
10608                    let buffer = buffer_handle.read(cx);
10609                    let buffer_abs_path = File::from_dyn(buffer.file())
10610                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10611
10612                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10613                })
10614                .collect::<Vec<_>>();
10615
10616            cx.spawn(async move |lsp_store, cx| {
10617                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10618
10619                for (handle, abs_path, id) in buffers {
10620                    let env = lsp_store
10621                        .update(cx, |lsp_store, cx| {
10622                            lsp_store.environment_for_buffer(&handle, cx)
10623                        })?
10624                        .await;
10625
10626                    let ranges = match &target {
10627                        LspFormatTarget::Buffers => None,
10628                        LspFormatTarget::Ranges(ranges) => {
10629                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10630                        }
10631                    };
10632
10633                    formattable_buffers.push(FormattableBuffer {
10634                        handle,
10635                        abs_path,
10636                        env,
10637                        ranges,
10638                    });
10639                }
10640                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10641
10642                let format_timer = zlog::time!(logger => "Formatting buffers");
10643                let result = LocalLspStore::format_locally(
10644                    lsp_store.clone(),
10645                    formattable_buffers,
10646                    push_to_history,
10647                    trigger,
10648                    logger,
10649                    cx,
10650                )
10651                .await;
10652                format_timer.end();
10653
10654                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10655
10656                lsp_store.update(cx, |lsp_store, _| {
10657                    lsp_store.update_last_formatting_failure(&result);
10658                })?;
10659
10660                result
10661            })
10662        } else if let Some((client, project_id)) = self.upstream_client() {
10663            zlog::trace!(logger => "Formatting remotely");
10664            let logger = zlog::scoped!(logger => "remote");
10665            // Don't support formatting ranges via remote
10666            match target {
10667                LspFormatTarget::Buffers => {}
10668                LspFormatTarget::Ranges(_) => {
10669                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10670                    return Task::ready(Ok(ProjectTransaction::default()));
10671                }
10672            }
10673
10674            let buffer_store = self.buffer_store();
10675            cx.spawn(async move |lsp_store, cx| {
10676                zlog::trace!(logger => "Sending remote format request");
10677                let request_timer = zlog::time!(logger => "remote format request");
10678                let result = client
10679                    .request(proto::FormatBuffers {
10680                        project_id,
10681                        trigger: trigger as i32,
10682                        buffer_ids: buffers
10683                            .iter()
10684                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10685                            .collect::<Result<_>>()?,
10686                    })
10687                    .await
10688                    .and_then(|result| result.transaction.context("missing transaction"));
10689                request_timer.end();
10690
10691                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10692
10693                lsp_store.update(cx, |lsp_store, _| {
10694                    lsp_store.update_last_formatting_failure(&result);
10695                })?;
10696
10697                let transaction_response = result?;
10698                let _timer = zlog::time!(logger => "deserializing project transaction");
10699                buffer_store
10700                    .update(cx, |buffer_store, cx| {
10701                        buffer_store.deserialize_project_transaction(
10702                            transaction_response,
10703                            push_to_history,
10704                            cx,
10705                        )
10706                    })?
10707                    .await
10708            })
10709        } else {
10710            zlog::trace!(logger => "Not formatting");
10711            Task::ready(Ok(ProjectTransaction::default()))
10712        }
10713    }
10714
10715    async fn handle_format_buffers(
10716        this: Entity<Self>,
10717        envelope: TypedEnvelope<proto::FormatBuffers>,
10718        mut cx: AsyncApp,
10719    ) -> Result<proto::FormatBuffersResponse> {
10720        let sender_id = envelope.original_sender_id().unwrap_or_default();
10721        let format = this.update(&mut cx, |this, cx| {
10722            let mut buffers = HashSet::default();
10723            for buffer_id in &envelope.payload.buffer_ids {
10724                let buffer_id = BufferId::new(*buffer_id)?;
10725                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10726            }
10727            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10728            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10729        })??;
10730
10731        let project_transaction = format.await?;
10732        let project_transaction = this.update(&mut cx, |this, cx| {
10733            this.buffer_store.update(cx, |buffer_store, cx| {
10734                buffer_store.serialize_project_transaction_for_peer(
10735                    project_transaction,
10736                    sender_id,
10737                    cx,
10738                )
10739            })
10740        })?;
10741        Ok(proto::FormatBuffersResponse {
10742            transaction: Some(project_transaction),
10743        })
10744    }
10745
10746    async fn handle_apply_code_action_kind(
10747        this: Entity<Self>,
10748        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10749        mut cx: AsyncApp,
10750    ) -> Result<proto::ApplyCodeActionKindResponse> {
10751        let sender_id = envelope.original_sender_id().unwrap_or_default();
10752        let format = this.update(&mut cx, |this, cx| {
10753            let mut buffers = HashSet::default();
10754            for buffer_id in &envelope.payload.buffer_ids {
10755                let buffer_id = BufferId::new(*buffer_id)?;
10756                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10757            }
10758            let kind = match envelope.payload.kind.as_str() {
10759                "" => CodeActionKind::EMPTY,
10760                "quickfix" => CodeActionKind::QUICKFIX,
10761                "refactor" => CodeActionKind::REFACTOR,
10762                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10763                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10764                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10765                "source" => CodeActionKind::SOURCE,
10766                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10767                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10768                _ => anyhow::bail!(
10769                    "Invalid code action kind {}",
10770                    envelope.payload.kind.as_str()
10771                ),
10772            };
10773            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10774        })??;
10775
10776        let project_transaction = format.await?;
10777        let project_transaction = this.update(&mut cx, |this, cx| {
10778            this.buffer_store.update(cx, |buffer_store, cx| {
10779                buffer_store.serialize_project_transaction_for_peer(
10780                    project_transaction,
10781                    sender_id,
10782                    cx,
10783                )
10784            })
10785        })?;
10786        Ok(proto::ApplyCodeActionKindResponse {
10787            transaction: Some(project_transaction),
10788        })
10789    }
10790
10791    async fn shutdown_language_server(
10792        server_state: Option<LanguageServerState>,
10793        name: LanguageServerName,
10794        cx: &mut AsyncApp,
10795    ) {
10796        let server = match server_state {
10797            Some(LanguageServerState::Starting { startup, .. }) => {
10798                let mut timer = cx
10799                    .background_executor()
10800                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10801                    .fuse();
10802
10803                select! {
10804                    server = startup.fuse() => server,
10805                    () = timer => {
10806                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10807                        None
10808                    },
10809                }
10810            }
10811
10812            Some(LanguageServerState::Running { server, .. }) => Some(server),
10813
10814            None => None,
10815        };
10816
10817        if let Some(server) = server
10818            && let Some(shutdown) = server.shutdown()
10819        {
10820            shutdown.await;
10821        }
10822    }
10823
10824    // Returns a list of all of the worktrees which no longer have a language server and the root path
10825    // for the stopped server
10826    fn stop_local_language_server(
10827        &mut self,
10828        server_id: LanguageServerId,
10829        cx: &mut Context<Self>,
10830    ) -> Task<()> {
10831        let local = match &mut self.mode {
10832            LspStoreMode::Local(local) => local,
10833            _ => {
10834                return Task::ready(());
10835            }
10836        };
10837
10838        // Remove this server ID from all entries in the given worktree.
10839        local
10840            .language_server_ids
10841            .retain(|_, state| state.id != server_id);
10842        self.buffer_store.update(cx, |buffer_store, cx| {
10843            for buffer in buffer_store.buffers() {
10844                buffer.update(cx, |buffer, cx| {
10845                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10846                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10847                });
10848            }
10849        });
10850
10851        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10852            summaries.retain(|path, summaries_by_server_id| {
10853                if summaries_by_server_id.remove(&server_id).is_some() {
10854                    if let Some((client, project_id)) = self.downstream_client.clone() {
10855                        client
10856                            .send(proto::UpdateDiagnosticSummary {
10857                                project_id,
10858                                worktree_id: worktree_id.to_proto(),
10859                                summary: Some(proto::DiagnosticSummary {
10860                                    path: path.as_ref().to_proto(),
10861                                    language_server_id: server_id.0 as u64,
10862                                    error_count: 0,
10863                                    warning_count: 0,
10864                                }),
10865                                more_summaries: Vec::new(),
10866                            })
10867                            .log_err();
10868                    }
10869                    !summaries_by_server_id.is_empty()
10870                } else {
10871                    true
10872                }
10873            });
10874        }
10875
10876        let local = self.as_local_mut().unwrap();
10877        for diagnostics in local.diagnostics.values_mut() {
10878            diagnostics.retain(|_, diagnostics_by_server_id| {
10879                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10880                    diagnostics_by_server_id.remove(ix);
10881                    !diagnostics_by_server_id.is_empty()
10882                } else {
10883                    true
10884                }
10885            });
10886        }
10887        local.language_server_watched_paths.remove(&server_id);
10888
10889        let server_state = local.language_servers.remove(&server_id);
10890        self.cleanup_lsp_data(server_id);
10891        let name = self
10892            .language_server_statuses
10893            .remove(&server_id)
10894            .map(|status| status.name)
10895            .or_else(|| {
10896                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10897                    Some(adapter.name())
10898                } else {
10899                    None
10900                }
10901            });
10902
10903        if let Some(name) = name {
10904            log::info!("stopping language server {name}");
10905            self.languages
10906                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10907            cx.notify();
10908
10909            return cx.spawn(async move |lsp_store, cx| {
10910                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10911                lsp_store
10912                    .update(cx, |lsp_store, cx| {
10913                        lsp_store
10914                            .languages
10915                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10916                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10917                        cx.notify();
10918                    })
10919                    .ok();
10920            });
10921        }
10922
10923        if server_state.is_some() {
10924            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10925        }
10926        Task::ready(())
10927    }
10928
10929    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10930        if let Some((client, project_id)) = self.upstream_client() {
10931            let request = client.request(proto::StopLanguageServers {
10932                project_id,
10933                buffer_ids: Vec::new(),
10934                also_servers: Vec::new(),
10935                all: true,
10936            });
10937            cx.background_spawn(request).detach_and_log_err(cx);
10938        } else {
10939            let Some(local) = self.as_local_mut() else {
10940                return;
10941            };
10942            let language_servers_to_stop = local
10943                .language_server_ids
10944                .values()
10945                .map(|state| state.id)
10946                .collect();
10947            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10948            let tasks = language_servers_to_stop
10949                .into_iter()
10950                .map(|server| self.stop_local_language_server(server, cx))
10951                .collect::<Vec<_>>();
10952            cx.background_spawn(async move {
10953                futures::future::join_all(tasks).await;
10954            })
10955            .detach();
10956        }
10957    }
10958
10959    pub fn restart_language_servers_for_buffers(
10960        &mut self,
10961        buffers: Vec<Entity<Buffer>>,
10962        only_restart_servers: HashSet<LanguageServerSelector>,
10963        cx: &mut Context<Self>,
10964    ) {
10965        if let Some((client, project_id)) = self.upstream_client() {
10966            let request = client.request(proto::RestartLanguageServers {
10967                project_id,
10968                buffer_ids: buffers
10969                    .into_iter()
10970                    .map(|b| b.read(cx).remote_id().to_proto())
10971                    .collect(),
10972                only_servers: only_restart_servers
10973                    .into_iter()
10974                    .map(|selector| {
10975                        let selector = match selector {
10976                            LanguageServerSelector::Id(language_server_id) => {
10977                                proto::language_server_selector::Selector::ServerId(
10978                                    language_server_id.to_proto(),
10979                                )
10980                            }
10981                            LanguageServerSelector::Name(language_server_name) => {
10982                                proto::language_server_selector::Selector::Name(
10983                                    language_server_name.to_string(),
10984                                )
10985                            }
10986                        };
10987                        proto::LanguageServerSelector {
10988                            selector: Some(selector),
10989                        }
10990                    })
10991                    .collect(),
10992                all: false,
10993            });
10994            cx.background_spawn(request).detach_and_log_err(cx);
10995        } else {
10996            let stop_task = if only_restart_servers.is_empty() {
10997                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10998            } else {
10999                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11000            };
11001            cx.spawn(async move |lsp_store, cx| {
11002                stop_task.await;
11003                lsp_store
11004                    .update(cx, |lsp_store, cx| {
11005                        for buffer in buffers {
11006                            lsp_store.register_buffer_with_language_servers(
11007                                &buffer,
11008                                only_restart_servers.clone(),
11009                                true,
11010                                cx,
11011                            );
11012                        }
11013                    })
11014                    .ok()
11015            })
11016            .detach();
11017        }
11018    }
11019
11020    pub fn stop_language_servers_for_buffers(
11021        &mut self,
11022        buffers: Vec<Entity<Buffer>>,
11023        also_stop_servers: HashSet<LanguageServerSelector>,
11024        cx: &mut Context<Self>,
11025    ) -> Task<Result<()>> {
11026        if let Some((client, project_id)) = self.upstream_client() {
11027            let request = client.request(proto::StopLanguageServers {
11028                project_id,
11029                buffer_ids: buffers
11030                    .into_iter()
11031                    .map(|b| b.read(cx).remote_id().to_proto())
11032                    .collect(),
11033                also_servers: also_stop_servers
11034                    .into_iter()
11035                    .map(|selector| {
11036                        let selector = match selector {
11037                            LanguageServerSelector::Id(language_server_id) => {
11038                                proto::language_server_selector::Selector::ServerId(
11039                                    language_server_id.to_proto(),
11040                                )
11041                            }
11042                            LanguageServerSelector::Name(language_server_name) => {
11043                                proto::language_server_selector::Selector::Name(
11044                                    language_server_name.to_string(),
11045                                )
11046                            }
11047                        };
11048                        proto::LanguageServerSelector {
11049                            selector: Some(selector),
11050                        }
11051                    })
11052                    .collect(),
11053                all: false,
11054            });
11055            cx.background_spawn(async move {
11056                let _ = request.await?;
11057                Ok(())
11058            })
11059        } else {
11060            let task =
11061                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11062            cx.background_spawn(async move {
11063                task.await;
11064                Ok(())
11065            })
11066        }
11067    }
11068
11069    fn stop_local_language_servers_for_buffers(
11070        &mut self,
11071        buffers: &[Entity<Buffer>],
11072        also_stop_servers: HashSet<LanguageServerSelector>,
11073        cx: &mut Context<Self>,
11074    ) -> Task<()> {
11075        let Some(local) = self.as_local_mut() else {
11076            return Task::ready(());
11077        };
11078        let mut language_server_names_to_stop = BTreeSet::default();
11079        let mut language_servers_to_stop = also_stop_servers
11080            .into_iter()
11081            .flat_map(|selector| match selector {
11082                LanguageServerSelector::Id(id) => Some(id),
11083                LanguageServerSelector::Name(name) => {
11084                    language_server_names_to_stop.insert(name);
11085                    None
11086                }
11087            })
11088            .collect::<BTreeSet<_>>();
11089
11090        let mut covered_worktrees = HashSet::default();
11091        for buffer in buffers {
11092            buffer.update(cx, |buffer, cx| {
11093                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11094                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11095                    && covered_worktrees.insert(worktree_id)
11096                {
11097                    language_server_names_to_stop.retain(|name| {
11098                        let old_ids_count = language_servers_to_stop.len();
11099                        let all_language_servers_with_this_name = local
11100                            .language_server_ids
11101                            .iter()
11102                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11103                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11104                        old_ids_count == language_servers_to_stop.len()
11105                    });
11106                }
11107            });
11108        }
11109        for name in language_server_names_to_stop {
11110            language_servers_to_stop.extend(
11111                local
11112                    .language_server_ids
11113                    .iter()
11114                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11115            );
11116        }
11117
11118        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11119        let tasks = language_servers_to_stop
11120            .into_iter()
11121            .map(|server| self.stop_local_language_server(server, cx))
11122            .collect::<Vec<_>>();
11123
11124        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11125    }
11126
11127    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11128        let (worktree, relative_path) =
11129            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11130
11131        let project_path = ProjectPath {
11132            worktree_id: worktree.read(cx).id(),
11133            path: relative_path,
11134        };
11135
11136        Some(
11137            self.buffer_store()
11138                .read(cx)
11139                .get_by_path(&project_path)?
11140                .read(cx),
11141        )
11142    }
11143
11144    #[cfg(any(test, feature = "test-support"))]
11145    pub fn update_diagnostics(
11146        &mut self,
11147        server_id: LanguageServerId,
11148        diagnostics: lsp::PublishDiagnosticsParams,
11149        result_id: Option<SharedString>,
11150        source_kind: DiagnosticSourceKind,
11151        disk_based_sources: &[String],
11152        cx: &mut Context<Self>,
11153    ) -> Result<()> {
11154        self.merge_lsp_diagnostics(
11155            source_kind,
11156            vec![DocumentDiagnosticsUpdate {
11157                diagnostics,
11158                result_id,
11159                server_id,
11160                disk_based_sources: Cow::Borrowed(disk_based_sources),
11161                registration_id: None,
11162            }],
11163            |_, _, _| false,
11164            cx,
11165        )
11166    }
11167
11168    pub fn merge_lsp_diagnostics(
11169        &mut self,
11170        source_kind: DiagnosticSourceKind,
11171        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11172        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11173        cx: &mut Context<Self>,
11174    ) -> Result<()> {
11175        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11176        let updates = lsp_diagnostics
11177            .into_iter()
11178            .filter_map(|update| {
11179                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11180                Some(DocumentDiagnosticsUpdate {
11181                    diagnostics: self.lsp_to_document_diagnostics(
11182                        abs_path,
11183                        source_kind,
11184                        update.server_id,
11185                        update.diagnostics,
11186                        &update.disk_based_sources,
11187                        update.registration_id.clone(),
11188                    ),
11189                    result_id: update.result_id,
11190                    server_id: update.server_id,
11191                    disk_based_sources: update.disk_based_sources,
11192                    registration_id: update.registration_id,
11193                })
11194            })
11195            .collect();
11196        self.merge_diagnostic_entries(updates, merge, cx)?;
11197        Ok(())
11198    }
11199
11200    fn lsp_to_document_diagnostics(
11201        &mut self,
11202        document_abs_path: PathBuf,
11203        source_kind: DiagnosticSourceKind,
11204        server_id: LanguageServerId,
11205        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11206        disk_based_sources: &[String],
11207        registration_id: Option<SharedString>,
11208    ) -> DocumentDiagnostics {
11209        let mut diagnostics = Vec::default();
11210        let mut primary_diagnostic_group_ids = HashMap::default();
11211        let mut sources_by_group_id = HashMap::default();
11212        let mut supporting_diagnostics = HashMap::default();
11213
11214        let adapter = self.language_server_adapter_for_id(server_id);
11215
11216        // Ensure that primary diagnostics are always the most severe
11217        lsp_diagnostics
11218            .diagnostics
11219            .sort_by_key(|item| item.severity);
11220
11221        for diagnostic in &lsp_diagnostics.diagnostics {
11222            let source = diagnostic.source.as_ref();
11223            let range = range_from_lsp(diagnostic.range);
11224            let is_supporting = diagnostic
11225                .related_information
11226                .as_ref()
11227                .is_some_and(|infos| {
11228                    infos.iter().any(|info| {
11229                        primary_diagnostic_group_ids.contains_key(&(
11230                            source,
11231                            diagnostic.code.clone(),
11232                            range_from_lsp(info.location.range),
11233                        ))
11234                    })
11235                });
11236
11237            let is_unnecessary = diagnostic
11238                .tags
11239                .as_ref()
11240                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11241
11242            let underline = self
11243                .language_server_adapter_for_id(server_id)
11244                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11245
11246            if is_supporting {
11247                supporting_diagnostics.insert(
11248                    (source, diagnostic.code.clone(), range),
11249                    (diagnostic.severity, is_unnecessary),
11250                );
11251            } else {
11252                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11253                let is_disk_based =
11254                    source.is_some_and(|source| disk_based_sources.contains(source));
11255
11256                sources_by_group_id.insert(group_id, source);
11257                primary_diagnostic_group_ids
11258                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11259
11260                diagnostics.push(DiagnosticEntry {
11261                    range,
11262                    diagnostic: Diagnostic {
11263                        source: diagnostic.source.clone(),
11264                        source_kind,
11265                        code: diagnostic.code.clone(),
11266                        code_description: diagnostic
11267                            .code_description
11268                            .as_ref()
11269                            .and_then(|d| d.href.clone()),
11270                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11271                        markdown: adapter.as_ref().and_then(|adapter| {
11272                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11273                        }),
11274                        message: diagnostic.message.trim().to_string(),
11275                        group_id,
11276                        is_primary: true,
11277                        is_disk_based,
11278                        is_unnecessary,
11279                        underline,
11280                        data: diagnostic.data.clone(),
11281                        registration_id: registration_id.clone(),
11282                    },
11283                });
11284                if let Some(infos) = &diagnostic.related_information {
11285                    for info in infos {
11286                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11287                            let range = range_from_lsp(info.location.range);
11288                            diagnostics.push(DiagnosticEntry {
11289                                range,
11290                                diagnostic: Diagnostic {
11291                                    source: diagnostic.source.clone(),
11292                                    source_kind,
11293                                    code: diagnostic.code.clone(),
11294                                    code_description: diagnostic
11295                                        .code_description
11296                                        .as_ref()
11297                                        .and_then(|d| d.href.clone()),
11298                                    severity: DiagnosticSeverity::INFORMATION,
11299                                    markdown: adapter.as_ref().and_then(|adapter| {
11300                                        adapter.diagnostic_message_to_markdown(&info.message)
11301                                    }),
11302                                    message: info.message.trim().to_string(),
11303                                    group_id,
11304                                    is_primary: false,
11305                                    is_disk_based,
11306                                    is_unnecessary: false,
11307                                    underline,
11308                                    data: diagnostic.data.clone(),
11309                                    registration_id: registration_id.clone(),
11310                                },
11311                            });
11312                        }
11313                    }
11314                }
11315            }
11316        }
11317
11318        for entry in &mut diagnostics {
11319            let diagnostic = &mut entry.diagnostic;
11320            if !diagnostic.is_primary {
11321                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11322                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11323                    source,
11324                    diagnostic.code.clone(),
11325                    entry.range.clone(),
11326                )) {
11327                    if let Some(severity) = severity {
11328                        diagnostic.severity = severity;
11329                    }
11330                    diagnostic.is_unnecessary = is_unnecessary;
11331                }
11332            }
11333        }
11334
11335        DocumentDiagnostics {
11336            diagnostics,
11337            document_abs_path,
11338            version: lsp_diagnostics.version,
11339        }
11340    }
11341
11342    fn insert_newly_running_language_server(
11343        &mut self,
11344        adapter: Arc<CachedLspAdapter>,
11345        language_server: Arc<LanguageServer>,
11346        server_id: LanguageServerId,
11347        key: LanguageServerSeed,
11348        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11349        cx: &mut Context<Self>,
11350    ) {
11351        let Some(local) = self.as_local_mut() else {
11352            return;
11353        };
11354        // If the language server for this key doesn't match the server id, don't store the
11355        // server. Which will cause it to be dropped, killing the process
11356        if local
11357            .language_server_ids
11358            .get(&key)
11359            .map(|state| state.id != server_id)
11360            .unwrap_or(false)
11361        {
11362            return;
11363        }
11364
11365        // Update language_servers collection with Running variant of LanguageServerState
11366        // indicating that the server is up and running and ready
11367        let workspace_folders = workspace_folders.lock().clone();
11368        language_server.set_workspace_folders(workspace_folders);
11369
11370        let workspace_diagnostics_refresh_tasks = language_server
11371            .capabilities()
11372            .diagnostic_provider
11373            .and_then(|provider| {
11374                local
11375                    .language_server_dynamic_registrations
11376                    .entry(server_id)
11377                    .or_default()
11378                    .diagnostics
11379                    .entry(None)
11380                    .or_insert(provider.clone());
11381                let workspace_refresher =
11382                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11383
11384                Some((None, workspace_refresher))
11385            })
11386            .into_iter()
11387            .collect();
11388        local.language_servers.insert(
11389            server_id,
11390            LanguageServerState::Running {
11391                workspace_diagnostics_refresh_tasks,
11392                adapter: adapter.clone(),
11393                server: language_server.clone(),
11394                simulate_disk_based_diagnostics_completion: None,
11395            },
11396        );
11397        local
11398            .languages
11399            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11400        if let Some(file_ops_caps) = language_server
11401            .capabilities()
11402            .workspace
11403            .as_ref()
11404            .and_then(|ws| ws.file_operations.as_ref())
11405        {
11406            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11407            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11408            if did_rename_caps.or(will_rename_caps).is_some() {
11409                let watcher = RenamePathsWatchedForServer::default()
11410                    .with_did_rename_patterns(did_rename_caps)
11411                    .with_will_rename_patterns(will_rename_caps);
11412                local
11413                    .language_server_paths_watched_for_rename
11414                    .insert(server_id, watcher);
11415            }
11416        }
11417
11418        self.language_server_statuses.insert(
11419            server_id,
11420            LanguageServerStatus {
11421                name: language_server.name(),
11422                pending_work: Default::default(),
11423                has_pending_diagnostic_updates: false,
11424                progress_tokens: Default::default(),
11425                worktree: Some(key.worktree_id),
11426                binary: Some(language_server.binary().clone()),
11427                configuration: Some(language_server.configuration().clone()),
11428                workspace_folders: language_server.workspace_folders(),
11429            },
11430        );
11431
11432        cx.emit(LspStoreEvent::LanguageServerAdded(
11433            server_id,
11434            language_server.name(),
11435            Some(key.worktree_id),
11436        ));
11437
11438        let server_capabilities = language_server.capabilities();
11439        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11440            downstream_client
11441                .send(proto::StartLanguageServer {
11442                    project_id: *project_id,
11443                    server: Some(proto::LanguageServer {
11444                        id: server_id.to_proto(),
11445                        name: language_server.name().to_string(),
11446                        worktree_id: Some(key.worktree_id.to_proto()),
11447                    }),
11448                    capabilities: serde_json::to_string(&server_capabilities)
11449                        .expect("serializing server LSP capabilities"),
11450                })
11451                .log_err();
11452        }
11453        self.lsp_server_capabilities
11454            .insert(server_id, server_capabilities);
11455
11456        // Tell the language server about every open buffer in the worktree that matches the language.
11457        // Also check for buffers in worktrees that reused this server
11458        let mut worktrees_using_server = vec![key.worktree_id];
11459        if let Some(local) = self.as_local() {
11460            // Find all worktrees that have this server in their language server tree
11461            for (worktree_id, servers) in &local.lsp_tree.instances {
11462                if *worktree_id != key.worktree_id {
11463                    for server_map in servers.roots.values() {
11464                        if server_map
11465                            .values()
11466                            .any(|(node, _)| node.id() == Some(server_id))
11467                        {
11468                            worktrees_using_server.push(*worktree_id);
11469                        }
11470                    }
11471                }
11472            }
11473        }
11474
11475        let mut buffer_paths_registered = Vec::new();
11476        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11477            let mut lsp_adapters = HashMap::default();
11478            for buffer_handle in buffer_store.buffers() {
11479                let buffer = buffer_handle.read(cx);
11480                let file = match File::from_dyn(buffer.file()) {
11481                    Some(file) => file,
11482                    None => continue,
11483                };
11484                let language = match buffer.language() {
11485                    Some(language) => language,
11486                    None => continue,
11487                };
11488
11489                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11490                    || !lsp_adapters
11491                        .entry(language.name())
11492                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11493                        .iter()
11494                        .any(|a| a.name == key.name)
11495                {
11496                    continue;
11497                }
11498                // didOpen
11499                let file = match file.as_local() {
11500                    Some(file) => file,
11501                    None => continue,
11502                };
11503
11504                let local = self.as_local_mut().unwrap();
11505
11506                let buffer_id = buffer.remote_id();
11507                if local.registered_buffers.contains_key(&buffer_id) {
11508                    let versions = local
11509                        .buffer_snapshots
11510                        .entry(buffer_id)
11511                        .or_default()
11512                        .entry(server_id)
11513                        .and_modify(|_| {
11514                            assert!(
11515                            false,
11516                            "There should not be an existing snapshot for a newly inserted buffer"
11517                        )
11518                        })
11519                        .or_insert_with(|| {
11520                            vec![LspBufferSnapshot {
11521                                version: 0,
11522                                snapshot: buffer.text_snapshot(),
11523                            }]
11524                        });
11525
11526                    let snapshot = versions.last().unwrap();
11527                    let version = snapshot.version;
11528                    let initial_snapshot = &snapshot.snapshot;
11529                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11530                    language_server.register_buffer(
11531                        uri,
11532                        adapter.language_id(&language.name()),
11533                        version,
11534                        initial_snapshot.text(),
11535                    );
11536                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11537                    local
11538                        .buffers_opened_in_servers
11539                        .entry(buffer_id)
11540                        .or_default()
11541                        .insert(server_id);
11542                }
11543                buffer_handle.update(cx, |buffer, cx| {
11544                    buffer.set_completion_triggers(
11545                        server_id,
11546                        language_server
11547                            .capabilities()
11548                            .completion_provider
11549                            .as_ref()
11550                            .and_then(|provider| {
11551                                provider
11552                                    .trigger_characters
11553                                    .as_ref()
11554                                    .map(|characters| characters.iter().cloned().collect())
11555                            })
11556                            .unwrap_or_default(),
11557                        cx,
11558                    )
11559                });
11560            }
11561        });
11562
11563        for (buffer_id, abs_path) in buffer_paths_registered {
11564            cx.emit(LspStoreEvent::LanguageServerUpdate {
11565                language_server_id: server_id,
11566                name: Some(adapter.name()),
11567                message: proto::update_language_server::Variant::RegisteredForBuffer(
11568                    proto::RegisteredForBuffer {
11569                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11570                        buffer_id: buffer_id.to_proto(),
11571                    },
11572                ),
11573            });
11574        }
11575
11576        cx.notify();
11577    }
11578
11579    pub fn language_servers_running_disk_based_diagnostics(
11580        &self,
11581    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11582        self.language_server_statuses
11583            .iter()
11584            .filter_map(|(id, status)| {
11585                if status.has_pending_diagnostic_updates {
11586                    Some(*id)
11587                } else {
11588                    None
11589                }
11590            })
11591    }
11592
11593    pub(crate) fn cancel_language_server_work_for_buffers(
11594        &mut self,
11595        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11596        cx: &mut Context<Self>,
11597    ) {
11598        if let Some((client, project_id)) = self.upstream_client() {
11599            let request = client.request(proto::CancelLanguageServerWork {
11600                project_id,
11601                work: Some(proto::cancel_language_server_work::Work::Buffers(
11602                    proto::cancel_language_server_work::Buffers {
11603                        buffer_ids: buffers
11604                            .into_iter()
11605                            .map(|b| b.read(cx).remote_id().to_proto())
11606                            .collect(),
11607                    },
11608                )),
11609            });
11610            cx.background_spawn(request).detach_and_log_err(cx);
11611        } else if let Some(local) = self.as_local() {
11612            let servers = buffers
11613                .into_iter()
11614                .flat_map(|buffer| {
11615                    buffer.update(cx, |buffer, cx| {
11616                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11617                    })
11618                })
11619                .collect::<HashSet<_>>();
11620            for server_id in servers {
11621                self.cancel_language_server_work(server_id, None, cx);
11622            }
11623        }
11624    }
11625
11626    pub(crate) fn cancel_language_server_work(
11627        &mut self,
11628        server_id: LanguageServerId,
11629        token_to_cancel: Option<ProgressToken>,
11630        cx: &mut Context<Self>,
11631    ) {
11632        if let Some(local) = self.as_local() {
11633            let status = self.language_server_statuses.get(&server_id);
11634            let server = local.language_servers.get(&server_id);
11635            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11636            {
11637                for (token, progress) in &status.pending_work {
11638                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11639                        && token != token_to_cancel
11640                    {
11641                        continue;
11642                    }
11643                    if progress.is_cancellable {
11644                        server
11645                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11646                                WorkDoneProgressCancelParams {
11647                                    token: token.to_lsp(),
11648                                },
11649                            )
11650                            .ok();
11651                    }
11652                }
11653            }
11654        } else if let Some((client, project_id)) = self.upstream_client() {
11655            let request = client.request(proto::CancelLanguageServerWork {
11656                project_id,
11657                work: Some(
11658                    proto::cancel_language_server_work::Work::LanguageServerWork(
11659                        proto::cancel_language_server_work::LanguageServerWork {
11660                            language_server_id: server_id.to_proto(),
11661                            token: token_to_cancel.map(|token| token.to_proto()),
11662                        },
11663                    ),
11664                ),
11665            });
11666            cx.background_spawn(request).detach_and_log_err(cx);
11667        }
11668    }
11669
11670    fn register_supplementary_language_server(
11671        &mut self,
11672        id: LanguageServerId,
11673        name: LanguageServerName,
11674        server: Arc<LanguageServer>,
11675        cx: &mut Context<Self>,
11676    ) {
11677        if let Some(local) = self.as_local_mut() {
11678            local
11679                .supplementary_language_servers
11680                .insert(id, (name.clone(), server));
11681            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11682        }
11683    }
11684
11685    fn unregister_supplementary_language_server(
11686        &mut self,
11687        id: LanguageServerId,
11688        cx: &mut Context<Self>,
11689    ) {
11690        if let Some(local) = self.as_local_mut() {
11691            local.supplementary_language_servers.remove(&id);
11692            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11693        }
11694    }
11695
11696    pub(crate) fn supplementary_language_servers(
11697        &self,
11698    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11699        self.as_local().into_iter().flat_map(|local| {
11700            local
11701                .supplementary_language_servers
11702                .iter()
11703                .map(|(id, (name, _))| (*id, name.clone()))
11704        })
11705    }
11706
11707    pub fn language_server_adapter_for_id(
11708        &self,
11709        id: LanguageServerId,
11710    ) -> Option<Arc<CachedLspAdapter>> {
11711        self.as_local()
11712            .and_then(|local| local.language_servers.get(&id))
11713            .and_then(|language_server_state| match language_server_state {
11714                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11715                _ => None,
11716            })
11717    }
11718
11719    pub(super) fn update_local_worktree_language_servers(
11720        &mut self,
11721        worktree_handle: &Entity<Worktree>,
11722        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11723        cx: &mut Context<Self>,
11724    ) {
11725        if changes.is_empty() {
11726            return;
11727        }
11728
11729        let Some(local) = self.as_local() else { return };
11730
11731        local.prettier_store.update(cx, |prettier_store, cx| {
11732            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11733        });
11734
11735        let worktree_id = worktree_handle.read(cx).id();
11736        let mut language_server_ids = local
11737            .language_server_ids
11738            .iter()
11739            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11740            .collect::<Vec<_>>();
11741        language_server_ids.sort();
11742        language_server_ids.dedup();
11743
11744        // let abs_path = worktree_handle.read(cx).abs_path();
11745        for server_id in &language_server_ids {
11746            if let Some(LanguageServerState::Running { server, .. }) =
11747                local.language_servers.get(server_id)
11748                && let Some(watched_paths) = local
11749                    .language_server_watched_paths
11750                    .get(server_id)
11751                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11752            {
11753                let params = lsp::DidChangeWatchedFilesParams {
11754                    changes: changes
11755                        .iter()
11756                        .filter_map(|(path, _, change)| {
11757                            if !watched_paths.is_match(path.as_std_path()) {
11758                                return None;
11759                            }
11760                            let typ = match change {
11761                                PathChange::Loaded => return None,
11762                                PathChange::Added => lsp::FileChangeType::CREATED,
11763                                PathChange::Removed => lsp::FileChangeType::DELETED,
11764                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11765                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11766                            };
11767                            let uri = lsp::Uri::from_file_path(
11768                                worktree_handle.read(cx).absolutize(&path),
11769                            )
11770                            .ok()?;
11771                            Some(lsp::FileEvent { uri, typ })
11772                        })
11773                        .collect(),
11774                };
11775                if !params.changes.is_empty() {
11776                    server
11777                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11778                        .ok();
11779                }
11780            }
11781        }
11782        for (path, _, _) in changes {
11783            if let Some(file_name) = path.file_name()
11784                && local.watched_manifest_filenames.contains(file_name)
11785            {
11786                self.request_workspace_config_refresh();
11787                break;
11788            }
11789        }
11790    }
11791
11792    pub fn wait_for_remote_buffer(
11793        &mut self,
11794        id: BufferId,
11795        cx: &mut Context<Self>,
11796    ) -> Task<Result<Entity<Buffer>>> {
11797        self.buffer_store.update(cx, |buffer_store, cx| {
11798            buffer_store.wait_for_remote_buffer(id, cx)
11799        })
11800    }
11801
11802    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11803        let mut result = proto::Symbol {
11804            language_server_name: symbol.language_server_name.0.to_string(),
11805            source_worktree_id: symbol.source_worktree_id.to_proto(),
11806            language_server_id: symbol.source_language_server_id.to_proto(),
11807            name: symbol.name.clone(),
11808            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11809            start: Some(proto::PointUtf16 {
11810                row: symbol.range.start.0.row,
11811                column: symbol.range.start.0.column,
11812            }),
11813            end: Some(proto::PointUtf16 {
11814                row: symbol.range.end.0.row,
11815                column: symbol.range.end.0.column,
11816            }),
11817            worktree_id: Default::default(),
11818            path: Default::default(),
11819            signature: Default::default(),
11820        };
11821        match &symbol.path {
11822            SymbolLocation::InProject(path) => {
11823                result.worktree_id = path.worktree_id.to_proto();
11824                result.path = path.path.to_proto();
11825            }
11826            SymbolLocation::OutsideProject {
11827                abs_path,
11828                signature,
11829            } => {
11830                result.path = abs_path.to_string_lossy().into_owned();
11831                result.signature = signature.to_vec();
11832            }
11833        }
11834        result
11835    }
11836
11837    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11838        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11839        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11840        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11841
11842        let path = if serialized_symbol.signature.is_empty() {
11843            SymbolLocation::InProject(ProjectPath {
11844                worktree_id,
11845                path: RelPath::from_proto(&serialized_symbol.path)
11846                    .context("invalid symbol path")?,
11847            })
11848        } else {
11849            SymbolLocation::OutsideProject {
11850                abs_path: Path::new(&serialized_symbol.path).into(),
11851                signature: serialized_symbol
11852                    .signature
11853                    .try_into()
11854                    .map_err(|_| anyhow!("invalid signature"))?,
11855            }
11856        };
11857
11858        let start = serialized_symbol.start.context("invalid start")?;
11859        let end = serialized_symbol.end.context("invalid end")?;
11860        Ok(CoreSymbol {
11861            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11862            source_worktree_id,
11863            source_language_server_id: LanguageServerId::from_proto(
11864                serialized_symbol.language_server_id,
11865            ),
11866            path,
11867            name: serialized_symbol.name,
11868            range: Unclipped(PointUtf16::new(start.row, start.column))
11869                ..Unclipped(PointUtf16::new(end.row, end.column)),
11870            kind,
11871        })
11872    }
11873
11874    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11875        let mut serialized_completion = proto::Completion {
11876            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11877            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11878            new_text: completion.new_text.clone(),
11879            ..proto::Completion::default()
11880        };
11881        match &completion.source {
11882            CompletionSource::Lsp {
11883                insert_range,
11884                server_id,
11885                lsp_completion,
11886                lsp_defaults,
11887                resolved,
11888            } => {
11889                let (old_insert_start, old_insert_end) = insert_range
11890                    .as_ref()
11891                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11892                    .unzip();
11893
11894                serialized_completion.old_insert_start = old_insert_start;
11895                serialized_completion.old_insert_end = old_insert_end;
11896                serialized_completion.source = proto::completion::Source::Lsp as i32;
11897                serialized_completion.server_id = server_id.0 as u64;
11898                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11899                serialized_completion.lsp_defaults = lsp_defaults
11900                    .as_deref()
11901                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11902                serialized_completion.resolved = *resolved;
11903            }
11904            CompletionSource::BufferWord {
11905                word_range,
11906                resolved,
11907            } => {
11908                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11909                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11910                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11911                serialized_completion.resolved = *resolved;
11912            }
11913            CompletionSource::Custom => {
11914                serialized_completion.source = proto::completion::Source::Custom as i32;
11915                serialized_completion.resolved = true;
11916            }
11917            CompletionSource::Dap { sort_text } => {
11918                serialized_completion.source = proto::completion::Source::Dap as i32;
11919                serialized_completion.sort_text = Some(sort_text.clone());
11920            }
11921        }
11922
11923        serialized_completion
11924    }
11925
11926    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11927        let old_replace_start = completion
11928            .old_replace_start
11929            .and_then(deserialize_anchor)
11930            .context("invalid old start")?;
11931        let old_replace_end = completion
11932            .old_replace_end
11933            .and_then(deserialize_anchor)
11934            .context("invalid old end")?;
11935        let insert_range = {
11936            match completion.old_insert_start.zip(completion.old_insert_end) {
11937                Some((start, end)) => {
11938                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11939                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11940                    Some(start..end)
11941                }
11942                None => None,
11943            }
11944        };
11945        Ok(CoreCompletion {
11946            replace_range: old_replace_start..old_replace_end,
11947            new_text: completion.new_text,
11948            source: match proto::completion::Source::from_i32(completion.source) {
11949                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11950                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11951                    insert_range,
11952                    server_id: LanguageServerId::from_proto(completion.server_id),
11953                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11954                    lsp_defaults: completion
11955                        .lsp_defaults
11956                        .as_deref()
11957                        .map(serde_json::from_slice)
11958                        .transpose()?,
11959                    resolved: completion.resolved,
11960                },
11961                Some(proto::completion::Source::BufferWord) => {
11962                    let word_range = completion
11963                        .buffer_word_start
11964                        .and_then(deserialize_anchor)
11965                        .context("invalid buffer word start")?
11966                        ..completion
11967                            .buffer_word_end
11968                            .and_then(deserialize_anchor)
11969                            .context("invalid buffer word end")?;
11970                    CompletionSource::BufferWord {
11971                        word_range,
11972                        resolved: completion.resolved,
11973                    }
11974                }
11975                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11976                    sort_text: completion
11977                        .sort_text
11978                        .context("expected sort text to exist")?,
11979                },
11980                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11981            },
11982        })
11983    }
11984
11985    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11986        let (kind, lsp_action) = match &action.lsp_action {
11987            LspAction::Action(code_action) => (
11988                proto::code_action::Kind::Action as i32,
11989                serde_json::to_vec(code_action).unwrap(),
11990            ),
11991            LspAction::Command(command) => (
11992                proto::code_action::Kind::Command as i32,
11993                serde_json::to_vec(command).unwrap(),
11994            ),
11995            LspAction::CodeLens(code_lens) => (
11996                proto::code_action::Kind::CodeLens as i32,
11997                serde_json::to_vec(code_lens).unwrap(),
11998            ),
11999        };
12000
12001        proto::CodeAction {
12002            server_id: action.server_id.0 as u64,
12003            start: Some(serialize_anchor(&action.range.start)),
12004            end: Some(serialize_anchor(&action.range.end)),
12005            lsp_action,
12006            kind,
12007            resolved: action.resolved,
12008        }
12009    }
12010
12011    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12012        let start = action
12013            .start
12014            .and_then(deserialize_anchor)
12015            .context("invalid start")?;
12016        let end = action
12017            .end
12018            .and_then(deserialize_anchor)
12019            .context("invalid end")?;
12020        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12021            Some(proto::code_action::Kind::Action) => {
12022                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12023            }
12024            Some(proto::code_action::Kind::Command) => {
12025                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12026            }
12027            Some(proto::code_action::Kind::CodeLens) => {
12028                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12029            }
12030            None => anyhow::bail!("Unknown action kind {}", action.kind),
12031        };
12032        Ok(CodeAction {
12033            server_id: LanguageServerId(action.server_id as usize),
12034            range: start..end,
12035            resolved: action.resolved,
12036            lsp_action,
12037        })
12038    }
12039
12040    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12041        match &formatting_result {
12042            Ok(_) => self.last_formatting_failure = None,
12043            Err(error) => {
12044                let error_string = format!("{error:#}");
12045                log::error!("Formatting failed: {error_string}");
12046                self.last_formatting_failure
12047                    .replace(error_string.lines().join(" "));
12048            }
12049        }
12050    }
12051
12052    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12053        self.lsp_server_capabilities.remove(&for_server);
12054        for lsp_data in self.lsp_data.values_mut() {
12055            lsp_data.remove_server_data(for_server);
12056        }
12057        if let Some(local) = self.as_local_mut() {
12058            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12059            local
12060                .workspace_pull_diagnostics_result_ids
12061                .remove(&for_server);
12062            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12063                buffer_servers.remove(&for_server);
12064            }
12065        }
12066    }
12067
12068    pub fn result_id_for_buffer_pull(
12069        &self,
12070        server_id: LanguageServerId,
12071        buffer_id: BufferId,
12072        registration_id: &Option<SharedString>,
12073        cx: &App,
12074    ) -> Option<SharedString> {
12075        let abs_path = self
12076            .buffer_store
12077            .read(cx)
12078            .get(buffer_id)
12079            .and_then(|b| File::from_dyn(b.read(cx).file()))
12080            .map(|f| f.abs_path(cx))?;
12081        self.as_local()?
12082            .buffer_pull_diagnostics_result_ids
12083            .get(&server_id)?
12084            .get(registration_id)?
12085            .get(&abs_path)?
12086            .clone()
12087    }
12088
12089    /// Gets all result_ids for a workspace diagnostics pull request.
12090    /// 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.
12091    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12092    pub fn result_ids_for_workspace_refresh(
12093        &self,
12094        server_id: LanguageServerId,
12095        registration_id: &Option<SharedString>,
12096    ) -> HashMap<PathBuf, SharedString> {
12097        let Some(local) = self.as_local() else {
12098            return HashMap::default();
12099        };
12100        local
12101            .workspace_pull_diagnostics_result_ids
12102            .get(&server_id)
12103            .into_iter()
12104            .filter_map(|diagnostics| diagnostics.get(registration_id))
12105            .flatten()
12106            .filter_map(|(abs_path, result_id)| {
12107                let result_id = local
12108                    .buffer_pull_diagnostics_result_ids
12109                    .get(&server_id)
12110                    .and_then(|buffer_ids_result_ids| {
12111                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12112                    })
12113                    .cloned()
12114                    .flatten()
12115                    .or_else(|| result_id.clone())?;
12116                Some((abs_path.clone(), result_id))
12117            })
12118            .collect()
12119    }
12120
12121    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12122        if let Some(LanguageServerState::Running {
12123            workspace_diagnostics_refresh_tasks,
12124            ..
12125        }) = self
12126            .as_local_mut()
12127            .and_then(|local| local.language_servers.get_mut(&server_id))
12128        {
12129            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12130                diagnostics.refresh_tx.try_send(()).ok();
12131            }
12132        }
12133    }
12134
12135    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
12136        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
12137            return;
12138        };
12139        let Some(local) = self.as_local_mut() else {
12140            return;
12141        };
12142
12143        for server_id in buffer.update(cx, |buffer, cx| {
12144            local.language_server_ids_for_buffer(buffer, cx)
12145        }) {
12146            if let Some(LanguageServerState::Running {
12147                workspace_diagnostics_refresh_tasks,
12148                ..
12149            }) = local.language_servers.get_mut(&server_id)
12150            {
12151                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12152                    diagnostics.refresh_tx.try_send(()).ok();
12153                }
12154            }
12155        }
12156    }
12157
12158    fn apply_workspace_diagnostic_report(
12159        &mut self,
12160        server_id: LanguageServerId,
12161        report: lsp::WorkspaceDiagnosticReportResult,
12162        registration_id: Option<SharedString>,
12163        cx: &mut Context<Self>,
12164    ) {
12165        let workspace_diagnostics =
12166            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12167                report,
12168                server_id,
12169                registration_id,
12170            );
12171        let mut unchanged_buffers = HashMap::default();
12172        let workspace_diagnostics_updates = workspace_diagnostics
12173            .into_iter()
12174            .filter_map(
12175                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12176                    LspPullDiagnostics::Response {
12177                        server_id,
12178                        uri,
12179                        diagnostics,
12180                        registration_id,
12181                    } => Some((
12182                        server_id,
12183                        uri,
12184                        diagnostics,
12185                        workspace_diagnostics.version,
12186                        registration_id,
12187                    )),
12188                    LspPullDiagnostics::Default => None,
12189                },
12190            )
12191            .fold(
12192                HashMap::default(),
12193                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12194                    let (result_id, diagnostics) = match diagnostics {
12195                        PulledDiagnostics::Unchanged { result_id } => {
12196                            unchanged_buffers
12197                                .entry(new_registration_id.clone())
12198                                .or_insert_with(HashSet::default)
12199                                .insert(uri.clone());
12200                            (Some(result_id), Vec::new())
12201                        }
12202                        PulledDiagnostics::Changed {
12203                            result_id,
12204                            diagnostics,
12205                        } => (result_id, diagnostics),
12206                    };
12207                    let disk_based_sources = Cow::Owned(
12208                        self.language_server_adapter_for_id(server_id)
12209                            .as_ref()
12210                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12211                            .unwrap_or(&[])
12212                            .to_vec(),
12213                    );
12214
12215                    let Some(abs_path) = uri.to_file_path().ok() else {
12216                        return acc;
12217                    };
12218                    let Some((worktree, relative_path)) =
12219                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12220                    else {
12221                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12222                        return acc;
12223                    };
12224                    let worktree_id = worktree.read(cx).id();
12225                    let project_path = ProjectPath {
12226                        worktree_id,
12227                        path: relative_path,
12228                    };
12229                    if let Some(local_lsp_store) = self.as_local_mut() {
12230                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12231                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12232                    }
12233                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12234                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12235                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12236                        acc.entry(server_id)
12237                            .or_insert_with(HashMap::default)
12238                            .entry(new_registration_id.clone())
12239                            .or_insert_with(Vec::new)
12240                            .push(DocumentDiagnosticsUpdate {
12241                                server_id,
12242                                diagnostics: lsp::PublishDiagnosticsParams {
12243                                    uri,
12244                                    diagnostics,
12245                                    version,
12246                                },
12247                                result_id,
12248                                disk_based_sources,
12249                                registration_id: new_registration_id,
12250                            });
12251                    }
12252                    acc
12253                },
12254            );
12255
12256        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12257            for (registration_id, diagnostic_updates) in diagnostic_updates {
12258                self.merge_lsp_diagnostics(
12259                    DiagnosticSourceKind::Pulled,
12260                    diagnostic_updates,
12261                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12262                        DiagnosticSourceKind::Pulled => {
12263                            old_diagnostic.registration_id != registration_id
12264                                || unchanged_buffers
12265                                    .get(&old_diagnostic.registration_id)
12266                                    .is_some_and(|unchanged_buffers| {
12267                                        unchanged_buffers.contains(&document_uri)
12268                                    })
12269                        }
12270                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12271                    },
12272                    cx,
12273                )
12274                .log_err();
12275            }
12276        }
12277    }
12278
12279    fn register_server_capabilities(
12280        &mut self,
12281        server_id: LanguageServerId,
12282        params: lsp::RegistrationParams,
12283        cx: &mut Context<Self>,
12284    ) -> anyhow::Result<()> {
12285        let server = self
12286            .language_server_for_id(server_id)
12287            .with_context(|| format!("no server {server_id} found"))?;
12288        for reg in params.registrations {
12289            match reg.method.as_str() {
12290                "workspace/didChangeWatchedFiles" => {
12291                    if let Some(options) = reg.register_options {
12292                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12293                            let caps = serde_json::from_value(options)?;
12294                            local_lsp_store
12295                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12296                            true
12297                        } else {
12298                            false
12299                        };
12300                        if notify {
12301                            notify_server_capabilities_updated(&server, cx);
12302                        }
12303                    }
12304                }
12305                "workspace/didChangeConfiguration" => {
12306                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12307                }
12308                "workspace/didChangeWorkspaceFolders" => {
12309                    // In this case register options is an empty object, we can ignore it
12310                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12311                        supported: Some(true),
12312                        change_notifications: Some(OneOf::Right(reg.id)),
12313                    };
12314                    server.update_capabilities(|capabilities| {
12315                        capabilities
12316                            .workspace
12317                            .get_or_insert_default()
12318                            .workspace_folders = Some(caps);
12319                    });
12320                    notify_server_capabilities_updated(&server, cx);
12321                }
12322                "workspace/symbol" => {
12323                    let options = parse_register_capabilities(reg)?;
12324                    server.update_capabilities(|capabilities| {
12325                        capabilities.workspace_symbol_provider = Some(options);
12326                    });
12327                    notify_server_capabilities_updated(&server, cx);
12328                }
12329                "workspace/fileOperations" => {
12330                    if let Some(options) = reg.register_options {
12331                        let caps = serde_json::from_value(options)?;
12332                        server.update_capabilities(|capabilities| {
12333                            capabilities
12334                                .workspace
12335                                .get_or_insert_default()
12336                                .file_operations = Some(caps);
12337                        });
12338                        notify_server_capabilities_updated(&server, cx);
12339                    }
12340                }
12341                "workspace/executeCommand" => {
12342                    if let Some(options) = reg.register_options {
12343                        let options = serde_json::from_value(options)?;
12344                        server.update_capabilities(|capabilities| {
12345                            capabilities.execute_command_provider = Some(options);
12346                        });
12347                        notify_server_capabilities_updated(&server, cx);
12348                    }
12349                }
12350                "textDocument/rangeFormatting" => {
12351                    let options = parse_register_capabilities(reg)?;
12352                    server.update_capabilities(|capabilities| {
12353                        capabilities.document_range_formatting_provider = Some(options);
12354                    });
12355                    notify_server_capabilities_updated(&server, cx);
12356                }
12357                "textDocument/onTypeFormatting" => {
12358                    if let Some(options) = reg
12359                        .register_options
12360                        .map(serde_json::from_value)
12361                        .transpose()?
12362                    {
12363                        server.update_capabilities(|capabilities| {
12364                            capabilities.document_on_type_formatting_provider = Some(options);
12365                        });
12366                        notify_server_capabilities_updated(&server, cx);
12367                    }
12368                }
12369                "textDocument/formatting" => {
12370                    let options = parse_register_capabilities(reg)?;
12371                    server.update_capabilities(|capabilities| {
12372                        capabilities.document_formatting_provider = Some(options);
12373                    });
12374                    notify_server_capabilities_updated(&server, cx);
12375                }
12376                "textDocument/rename" => {
12377                    let options = parse_register_capabilities(reg)?;
12378                    server.update_capabilities(|capabilities| {
12379                        capabilities.rename_provider = Some(options);
12380                    });
12381                    notify_server_capabilities_updated(&server, cx);
12382                }
12383                "textDocument/inlayHint" => {
12384                    let options = parse_register_capabilities(reg)?;
12385                    server.update_capabilities(|capabilities| {
12386                        capabilities.inlay_hint_provider = Some(options);
12387                    });
12388                    notify_server_capabilities_updated(&server, cx);
12389                }
12390                "textDocument/documentSymbol" => {
12391                    let options = parse_register_capabilities(reg)?;
12392                    server.update_capabilities(|capabilities| {
12393                        capabilities.document_symbol_provider = Some(options);
12394                    });
12395                    notify_server_capabilities_updated(&server, cx);
12396                }
12397                "textDocument/codeAction" => {
12398                    let options = parse_register_capabilities(reg)?;
12399                    let provider = match options {
12400                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12401                        OneOf::Right(caps) => caps,
12402                    };
12403                    server.update_capabilities(|capabilities| {
12404                        capabilities.code_action_provider = Some(provider);
12405                    });
12406                    notify_server_capabilities_updated(&server, cx);
12407                }
12408                "textDocument/definition" => {
12409                    let options = parse_register_capabilities(reg)?;
12410                    server.update_capabilities(|capabilities| {
12411                        capabilities.definition_provider = Some(options);
12412                    });
12413                    notify_server_capabilities_updated(&server, cx);
12414                }
12415                "textDocument/completion" => {
12416                    if let Some(caps) = reg
12417                        .register_options
12418                        .map(serde_json::from_value::<CompletionOptions>)
12419                        .transpose()?
12420                    {
12421                        server.update_capabilities(|capabilities| {
12422                            capabilities.completion_provider = Some(caps.clone());
12423                        });
12424
12425                        if let Some(local) = self.as_local() {
12426                            let mut buffers_with_language_server = Vec::new();
12427                            for handle in self.buffer_store.read(cx).buffers() {
12428                                let buffer_id = handle.read(cx).remote_id();
12429                                if local
12430                                    .buffers_opened_in_servers
12431                                    .get(&buffer_id)
12432                                    .filter(|s| s.contains(&server_id))
12433                                    .is_some()
12434                                {
12435                                    buffers_with_language_server.push(handle);
12436                                }
12437                            }
12438                            let triggers = caps
12439                                .trigger_characters
12440                                .unwrap_or_default()
12441                                .into_iter()
12442                                .collect::<BTreeSet<_>>();
12443                            for handle in buffers_with_language_server {
12444                                let triggers = triggers.clone();
12445                                let _ = handle.update(cx, move |buffer, cx| {
12446                                    buffer.set_completion_triggers(server_id, triggers, cx);
12447                                });
12448                            }
12449                        }
12450                        notify_server_capabilities_updated(&server, cx);
12451                    }
12452                }
12453                "textDocument/hover" => {
12454                    let options = parse_register_capabilities(reg)?;
12455                    let provider = match options {
12456                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12457                        OneOf::Right(caps) => caps,
12458                    };
12459                    server.update_capabilities(|capabilities| {
12460                        capabilities.hover_provider = Some(provider);
12461                    });
12462                    notify_server_capabilities_updated(&server, cx);
12463                }
12464                "textDocument/signatureHelp" => {
12465                    if let Some(caps) = reg
12466                        .register_options
12467                        .map(serde_json::from_value)
12468                        .transpose()?
12469                    {
12470                        server.update_capabilities(|capabilities| {
12471                            capabilities.signature_help_provider = Some(caps);
12472                        });
12473                        notify_server_capabilities_updated(&server, cx);
12474                    }
12475                }
12476                "textDocument/didChange" => {
12477                    if let Some(sync_kind) = reg
12478                        .register_options
12479                        .and_then(|opts| opts.get("syncKind").cloned())
12480                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12481                        .transpose()?
12482                    {
12483                        server.update_capabilities(|capabilities| {
12484                            let mut sync_options =
12485                                Self::take_text_document_sync_options(capabilities);
12486                            sync_options.change = Some(sync_kind);
12487                            capabilities.text_document_sync =
12488                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12489                        });
12490                        notify_server_capabilities_updated(&server, cx);
12491                    }
12492                }
12493                "textDocument/didSave" => {
12494                    if let Some(include_text) = reg
12495                        .register_options
12496                        .map(|opts| {
12497                            let transpose = opts
12498                                .get("includeText")
12499                                .cloned()
12500                                .map(serde_json::from_value::<Option<bool>>)
12501                                .transpose();
12502                            match transpose {
12503                                Ok(value) => Ok(value.flatten()),
12504                                Err(e) => Err(e),
12505                            }
12506                        })
12507                        .transpose()?
12508                    {
12509                        server.update_capabilities(|capabilities| {
12510                            let mut sync_options =
12511                                Self::take_text_document_sync_options(capabilities);
12512                            sync_options.save =
12513                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12514                                    include_text,
12515                                }));
12516                            capabilities.text_document_sync =
12517                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12518                        });
12519                        notify_server_capabilities_updated(&server, cx);
12520                    }
12521                }
12522                "textDocument/codeLens" => {
12523                    if let Some(caps) = reg
12524                        .register_options
12525                        .map(serde_json::from_value)
12526                        .transpose()?
12527                    {
12528                        server.update_capabilities(|capabilities| {
12529                            capabilities.code_lens_provider = Some(caps);
12530                        });
12531                        notify_server_capabilities_updated(&server, cx);
12532                    }
12533                }
12534                "textDocument/diagnostic" => {
12535                    if let Some(caps) = reg
12536                        .register_options
12537                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12538                        .transpose()?
12539                    {
12540                        let local = self
12541                            .as_local_mut()
12542                            .context("Expected LSP Store to be local")?;
12543                        let state = local
12544                            .language_servers
12545                            .get_mut(&server_id)
12546                            .context("Could not obtain Language Servers state")?;
12547                        local
12548                            .language_server_dynamic_registrations
12549                            .entry(server_id)
12550                            .or_default()
12551                            .diagnostics
12552                            .insert(Some(reg.id.clone()), caps.clone());
12553
12554                        let supports_workspace_diagnostics =
12555                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12556                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12557                                    diagnostic_options.workspace_diagnostics
12558                                }
12559                                DiagnosticServerCapabilities::RegistrationOptions(
12560                                    diagnostic_registration_options,
12561                                ) => {
12562                                    diagnostic_registration_options
12563                                        .diagnostic_options
12564                                        .workspace_diagnostics
12565                                }
12566                            };
12567
12568                        if supports_workspace_diagnostics(&caps) {
12569                            if let LanguageServerState::Running {
12570                                workspace_diagnostics_refresh_tasks,
12571                                ..
12572                            } = state
12573                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12574                                    Some(reg.id.clone()),
12575                                    caps.clone(),
12576                                    server.clone(),
12577                                    cx,
12578                                )
12579                            {
12580                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12581                            }
12582                        }
12583
12584                        server.update_capabilities(|capabilities| {
12585                            capabilities.diagnostic_provider = Some(caps);
12586                        });
12587
12588                        notify_server_capabilities_updated(&server, cx);
12589                    }
12590                }
12591                "textDocument/documentColor" => {
12592                    let options = parse_register_capabilities(reg)?;
12593                    let provider = match options {
12594                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12595                        OneOf::Right(caps) => caps,
12596                    };
12597                    server.update_capabilities(|capabilities| {
12598                        capabilities.color_provider = Some(provider);
12599                    });
12600                    notify_server_capabilities_updated(&server, cx);
12601                }
12602                _ => log::warn!("unhandled capability registration: {reg:?}"),
12603            }
12604        }
12605
12606        Ok(())
12607    }
12608
12609    fn unregister_server_capabilities(
12610        &mut self,
12611        server_id: LanguageServerId,
12612        params: lsp::UnregistrationParams,
12613        cx: &mut Context<Self>,
12614    ) -> anyhow::Result<()> {
12615        let server = self
12616            .language_server_for_id(server_id)
12617            .with_context(|| format!("no server {server_id} found"))?;
12618        for unreg in params.unregisterations.iter() {
12619            match unreg.method.as_str() {
12620                "workspace/didChangeWatchedFiles" => {
12621                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12622                        local_lsp_store
12623                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12624                        true
12625                    } else {
12626                        false
12627                    };
12628                    if notify {
12629                        notify_server_capabilities_updated(&server, cx);
12630                    }
12631                }
12632                "workspace/didChangeConfiguration" => {
12633                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12634                }
12635                "workspace/didChangeWorkspaceFolders" => {
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                            .workspace_folders = None;
12644                    });
12645                    notify_server_capabilities_updated(&server, cx);
12646                }
12647                "workspace/symbol" => {
12648                    server.update_capabilities(|capabilities| {
12649                        capabilities.workspace_symbol_provider = None
12650                    });
12651                    notify_server_capabilities_updated(&server, cx);
12652                }
12653                "workspace/fileOperations" => {
12654                    server.update_capabilities(|capabilities| {
12655                        capabilities
12656                            .workspace
12657                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12658                                workspace_folders: None,
12659                                file_operations: None,
12660                            })
12661                            .file_operations = None;
12662                    });
12663                    notify_server_capabilities_updated(&server, cx);
12664                }
12665                "workspace/executeCommand" => {
12666                    server.update_capabilities(|capabilities| {
12667                        capabilities.execute_command_provider = None;
12668                    });
12669                    notify_server_capabilities_updated(&server, cx);
12670                }
12671                "textDocument/rangeFormatting" => {
12672                    server.update_capabilities(|capabilities| {
12673                        capabilities.document_range_formatting_provider = None
12674                    });
12675                    notify_server_capabilities_updated(&server, cx);
12676                }
12677                "textDocument/onTypeFormatting" => {
12678                    server.update_capabilities(|capabilities| {
12679                        capabilities.document_on_type_formatting_provider = None;
12680                    });
12681                    notify_server_capabilities_updated(&server, cx);
12682                }
12683                "textDocument/formatting" => {
12684                    server.update_capabilities(|capabilities| {
12685                        capabilities.document_formatting_provider = None;
12686                    });
12687                    notify_server_capabilities_updated(&server, cx);
12688                }
12689                "textDocument/rename" => {
12690                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12691                    notify_server_capabilities_updated(&server, cx);
12692                }
12693                "textDocument/codeAction" => {
12694                    server.update_capabilities(|capabilities| {
12695                        capabilities.code_action_provider = None;
12696                    });
12697                    notify_server_capabilities_updated(&server, cx);
12698                }
12699                "textDocument/definition" => {
12700                    server.update_capabilities(|capabilities| {
12701                        capabilities.definition_provider = None;
12702                    });
12703                    notify_server_capabilities_updated(&server, cx);
12704                }
12705                "textDocument/completion" => {
12706                    server.update_capabilities(|capabilities| {
12707                        capabilities.completion_provider = None;
12708                    });
12709                    notify_server_capabilities_updated(&server, cx);
12710                }
12711                "textDocument/hover" => {
12712                    server.update_capabilities(|capabilities| {
12713                        capabilities.hover_provider = None;
12714                    });
12715                    notify_server_capabilities_updated(&server, cx);
12716                }
12717                "textDocument/signatureHelp" => {
12718                    server.update_capabilities(|capabilities| {
12719                        capabilities.signature_help_provider = None;
12720                    });
12721                    notify_server_capabilities_updated(&server, cx);
12722                }
12723                "textDocument/didChange" => {
12724                    server.update_capabilities(|capabilities| {
12725                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12726                        sync_options.change = None;
12727                        capabilities.text_document_sync =
12728                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12729                    });
12730                    notify_server_capabilities_updated(&server, cx);
12731                }
12732                "textDocument/didSave" => {
12733                    server.update_capabilities(|capabilities| {
12734                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12735                        sync_options.save = None;
12736                        capabilities.text_document_sync =
12737                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12738                    });
12739                    notify_server_capabilities_updated(&server, cx);
12740                }
12741                "textDocument/codeLens" => {
12742                    server.update_capabilities(|capabilities| {
12743                        capabilities.code_lens_provider = None;
12744                    });
12745                    notify_server_capabilities_updated(&server, cx);
12746                }
12747                "textDocument/diagnostic" => {
12748                    let local = self
12749                        .as_local_mut()
12750                        .context("Expected LSP Store to be local")?;
12751
12752                    let state = local
12753                        .language_servers
12754                        .get_mut(&server_id)
12755                        .context("Could not obtain Language Servers state")?;
12756                    let registrations = local
12757                        .language_server_dynamic_registrations
12758                        .get_mut(&server_id)
12759                        .with_context(|| {
12760                            format!("Expected dynamic registration to exist for server {server_id}")
12761                        })?;
12762                    registrations.diagnostics
12763                        .remove(&Some(unreg.id.clone()))
12764                        .with_context(|| format!(
12765                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12766                            unreg.id)
12767                        )?;
12768                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12769
12770                    if let LanguageServerState::Running {
12771                        workspace_diagnostics_refresh_tasks,
12772                        ..
12773                    } = state
12774                    {
12775                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12776                    }
12777
12778                    if removed_last_diagnostic_provider {
12779                        server.update_capabilities(|capabilities| {
12780                            debug_assert!(capabilities.diagnostic_provider.is_some());
12781                            capabilities.diagnostic_provider = None;
12782                        });
12783                    }
12784
12785                    notify_server_capabilities_updated(&server, cx);
12786                }
12787                "textDocument/documentColor" => {
12788                    server.update_capabilities(|capabilities| {
12789                        capabilities.color_provider = None;
12790                    });
12791                    notify_server_capabilities_updated(&server, cx);
12792                }
12793                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12794            }
12795        }
12796
12797        Ok(())
12798    }
12799
12800    async fn deduplicate_range_based_lsp_requests<T>(
12801        lsp_store: &Entity<Self>,
12802        server_id: Option<LanguageServerId>,
12803        lsp_request_id: LspRequestId,
12804        proto_request: &T::ProtoRequest,
12805        range: Range<Anchor>,
12806        cx: &mut AsyncApp,
12807    ) -> Result<()>
12808    where
12809        T: LspCommand,
12810        T::ProtoRequest: proto::LspRequestMessage,
12811    {
12812        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12813        let version = deserialize_version(proto_request.buffer_version());
12814        let buffer = lsp_store.update(cx, |this, cx| {
12815            this.buffer_store.read(cx).get_existing(buffer_id)
12816        })??;
12817        buffer
12818            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12819            .await?;
12820        lsp_store.update(cx, |lsp_store, cx| {
12821            let buffer_snapshot = buffer.read(cx).snapshot();
12822            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12823            let chunks_queried_for = lsp_data
12824                .inlay_hints
12825                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12826                .collect::<Vec<_>>();
12827            match chunks_queried_for.as_slice() {
12828                &[chunk] => {
12829                    let key = LspKey {
12830                        request_type: TypeId::of::<T>(),
12831                        server_queried: server_id,
12832                    };
12833                    let previous_request = lsp_data
12834                        .chunk_lsp_requests
12835                        .entry(key)
12836                        .or_default()
12837                        .insert(chunk, lsp_request_id);
12838                    if let Some((previous_request, running_requests)) =
12839                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12840                    {
12841                        running_requests.remove(&previous_request);
12842                    }
12843                }
12844                _ambiguous_chunks => {
12845                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12846                    // there, a buffer version-based check will be performed and outdated requests discarded.
12847                }
12848            }
12849            anyhow::Ok(())
12850        })??;
12851
12852        Ok(())
12853    }
12854
12855    async fn query_lsp_locally<T>(
12856        lsp_store: Entity<Self>,
12857        for_server_id: Option<LanguageServerId>,
12858        sender_id: proto::PeerId,
12859        lsp_request_id: LspRequestId,
12860        proto_request: T::ProtoRequest,
12861        position: Option<Anchor>,
12862        cx: &mut AsyncApp,
12863    ) -> Result<()>
12864    where
12865        T: LspCommand + Clone,
12866        T::ProtoRequest: proto::LspRequestMessage,
12867        <T::ProtoRequest as proto::RequestMessage>::Response:
12868            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12869    {
12870        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12871        let version = deserialize_version(proto_request.buffer_version());
12872        let buffer = lsp_store.update(cx, |this, cx| {
12873            this.buffer_store.read(cx).get_existing(buffer_id)
12874        })??;
12875        buffer
12876            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12877            .await?;
12878        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12879        let request =
12880            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12881        let key = LspKey {
12882            request_type: TypeId::of::<T>(),
12883            server_queried: for_server_id,
12884        };
12885        lsp_store.update(cx, |lsp_store, cx| {
12886            let request_task = match for_server_id {
12887                Some(server_id) => {
12888                    let server_task = lsp_store.request_lsp(
12889                        buffer.clone(),
12890                        LanguageServerToQuery::Other(server_id),
12891                        request.clone(),
12892                        cx,
12893                    );
12894                    cx.background_spawn(async move {
12895                        let mut responses = Vec::new();
12896                        match server_task.await {
12897                            Ok(response) => responses.push((server_id, response)),
12898                            // rust-analyzer likes to error with this when its still loading up
12899                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12900                            Err(e) => log::error!(
12901                                "Error handling response for request {request:?}: {e:#}"
12902                            ),
12903                        }
12904                        responses
12905                    })
12906                }
12907                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12908            };
12909            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12910            if T::ProtoRequest::stop_previous_requests() {
12911                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12912                    lsp_requests.clear();
12913                }
12914            }
12915            lsp_data.lsp_requests.entry(key).or_default().insert(
12916                lsp_request_id,
12917                cx.spawn(async move |lsp_store, cx| {
12918                    let response = request_task.await;
12919                    lsp_store
12920                        .update(cx, |lsp_store, cx| {
12921                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12922                            {
12923                                let response = response
12924                                    .into_iter()
12925                                    .map(|(server_id, response)| {
12926                                        (
12927                                            server_id.to_proto(),
12928                                            T::response_to_proto(
12929                                                response,
12930                                                lsp_store,
12931                                                sender_id,
12932                                                &buffer_version,
12933                                                cx,
12934                                            )
12935                                            .into(),
12936                                        )
12937                                    })
12938                                    .collect::<HashMap<_, _>>();
12939                                match client.send_lsp_response::<T::ProtoRequest>(
12940                                    project_id,
12941                                    lsp_request_id,
12942                                    response,
12943                                ) {
12944                                    Ok(()) => {}
12945                                    Err(e) => {
12946                                        log::error!("Failed to send LSP response: {e:#}",)
12947                                    }
12948                                }
12949                            }
12950                        })
12951                        .ok();
12952                }),
12953            );
12954        })?;
12955        Ok(())
12956    }
12957
12958    fn take_text_document_sync_options(
12959        capabilities: &mut lsp::ServerCapabilities,
12960    ) -> lsp::TextDocumentSyncOptions {
12961        match capabilities.text_document_sync.take() {
12962            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12963            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12964                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12965                sync_options.change = Some(sync_kind);
12966                sync_options
12967            }
12968            None => lsp::TextDocumentSyncOptions::default(),
12969        }
12970    }
12971
12972    #[cfg(any(test, feature = "test-support"))]
12973    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12974        Some(
12975            self.lsp_data
12976                .get_mut(&buffer_id)?
12977                .code_lens
12978                .take()?
12979                .update
12980                .take()?
12981                .1,
12982        )
12983    }
12984
12985    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12986        self.downstream_client.clone()
12987    }
12988
12989    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12990        self.worktree_store.clone()
12991    }
12992
12993    /// Gets what's stored in the LSP data for the given buffer.
12994    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12995        self.lsp_data.get_mut(&buffer_id)
12996    }
12997
12998    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12999    /// new [`BufferLspData`] will be created to replace the previous state.
13000    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13001        let (buffer_id, buffer_version) =
13002            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13003        let lsp_data = self
13004            .lsp_data
13005            .entry(buffer_id)
13006            .or_insert_with(|| BufferLspData::new(buffer, cx));
13007        if buffer_version.changed_since(&lsp_data.buffer_version) {
13008            *lsp_data = BufferLspData::new(buffer, cx);
13009        }
13010        lsp_data
13011    }
13012}
13013
13014// Registration with registerOptions as null, should fallback to true.
13015// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13016fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13017    reg: lsp::Registration,
13018) -> Result<OneOf<bool, T>> {
13019    Ok(match reg.register_options {
13020        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13021        None => OneOf::Left(true),
13022    })
13023}
13024
13025fn subscribe_to_binary_statuses(
13026    languages: &Arc<LanguageRegistry>,
13027    cx: &mut Context<'_, LspStore>,
13028) -> Task<()> {
13029    let mut server_statuses = languages.language_server_binary_statuses();
13030    cx.spawn(async move |lsp_store, cx| {
13031        while let Some((server_name, binary_status)) = server_statuses.next().await {
13032            if lsp_store
13033                .update(cx, |_, cx| {
13034                    let mut message = None;
13035                    let binary_status = match binary_status {
13036                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13037                        BinaryStatus::CheckingForUpdate => {
13038                            proto::ServerBinaryStatus::CheckingForUpdate
13039                        }
13040                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13041                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13042                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13043                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13044                        BinaryStatus::Failed { error } => {
13045                            message = Some(error);
13046                            proto::ServerBinaryStatus::Failed
13047                        }
13048                    };
13049                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13050                        // Binary updates are about the binary that might not have any language server id at that point.
13051                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13052                        language_server_id: LanguageServerId(0),
13053                        name: Some(server_name),
13054                        message: proto::update_language_server::Variant::StatusUpdate(
13055                            proto::StatusUpdate {
13056                                message,
13057                                status: Some(proto::status_update::Status::Binary(
13058                                    binary_status as i32,
13059                                )),
13060                            },
13061                        ),
13062                    });
13063                })
13064                .is_err()
13065            {
13066                break;
13067            }
13068        }
13069    })
13070}
13071
13072fn lsp_workspace_diagnostics_refresh(
13073    registration_id: Option<String>,
13074    options: DiagnosticServerCapabilities,
13075    server: Arc<LanguageServer>,
13076    cx: &mut Context<'_, LspStore>,
13077) -> Option<WorkspaceRefreshTask> {
13078    let identifier = workspace_diagnostic_identifier(&options)?;
13079    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13080
13081    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13082    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13083    refresh_tx.try_send(()).ok();
13084
13085    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13086        let mut attempts = 0;
13087        let max_attempts = 50;
13088        let mut requests = 0;
13089
13090        loop {
13091            let Some(()) = refresh_rx.recv().await else {
13092                return;
13093            };
13094
13095            'request: loop {
13096                requests += 1;
13097                if attempts > max_attempts {
13098                    log::error!(
13099                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13100                    );
13101                    return;
13102                }
13103                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13104                cx.background_executor()
13105                    .timer(Duration::from_millis(backoff_millis))
13106                    .await;
13107                attempts += 1;
13108
13109                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13110                    lsp_store
13111                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13112                        .into_iter()
13113                        .filter_map(|(abs_path, result_id)| {
13114                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13115                            Some(lsp::PreviousResultId {
13116                                uri,
13117                                value: result_id.to_string(),
13118                            })
13119                        })
13120                        .collect()
13121                }) else {
13122                    return;
13123                };
13124
13125                let token = if let Some(registration_id) = &registration_id {
13126                    format!(
13127                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13128                        server.server_id(),
13129                    )
13130                } else {
13131                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13132                };
13133
13134                progress_rx.try_recv().ok();
13135                let timer =
13136                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13137                let progress = pin!(progress_rx.recv().fuse());
13138                let response_result = server
13139                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13140                        lsp::WorkspaceDiagnosticParams {
13141                            previous_result_ids,
13142                            identifier: identifier.clone(),
13143                            work_done_progress_params: Default::default(),
13144                            partial_result_params: lsp::PartialResultParams {
13145                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13146                            },
13147                        },
13148                        select(timer, progress).then(|either| match either {
13149                            Either::Left((message, ..)) => ready(message).left_future(),
13150                            Either::Right(..) => pending::<String>().right_future(),
13151                        }),
13152                    )
13153                    .await;
13154
13155                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13156                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13157                match response_result {
13158                    ConnectionResult::Timeout => {
13159                        log::error!("Timeout during workspace diagnostics pull");
13160                        continue 'request;
13161                    }
13162                    ConnectionResult::ConnectionReset => {
13163                        log::error!("Server closed a workspace diagnostics pull request");
13164                        continue 'request;
13165                    }
13166                    ConnectionResult::Result(Err(e)) => {
13167                        log::error!("Error during workspace diagnostics pull: {e:#}");
13168                        break 'request;
13169                    }
13170                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13171                        attempts = 0;
13172                        if lsp_store
13173                            .update(cx, |lsp_store, cx| {
13174                                lsp_store.apply_workspace_diagnostic_report(
13175                                    server.server_id(),
13176                                    pulled_diagnostics,
13177                                    registration_id_shared.clone(),
13178                                    cx,
13179                                )
13180                            })
13181                            .is_err()
13182                        {
13183                            return;
13184                        }
13185                        break 'request;
13186                    }
13187                }
13188            }
13189        }
13190    });
13191
13192    Some(WorkspaceRefreshTask {
13193        refresh_tx,
13194        progress_tx,
13195        task: workspace_query_language_server,
13196    })
13197}
13198
13199fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13200    match &options {
13201        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13202            diagnostic_options.identifier.clone()
13203        }
13204        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13205            let diagnostic_options = &registration_options.diagnostic_options;
13206            diagnostic_options.identifier.clone()
13207        }
13208    }
13209}
13210
13211fn workspace_diagnostic_identifier(
13212    options: &DiagnosticServerCapabilities,
13213) -> Option<Option<String>> {
13214    match &options {
13215        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13216            if !diagnostic_options.workspace_diagnostics {
13217                return None;
13218            }
13219            Some(diagnostic_options.identifier.clone())
13220        }
13221        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13222            let diagnostic_options = &registration_options.diagnostic_options;
13223            if !diagnostic_options.workspace_diagnostics {
13224                return None;
13225            }
13226            Some(diagnostic_options.identifier.clone())
13227        }
13228    }
13229}
13230
13231fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13232    let CompletionSource::BufferWord {
13233        word_range,
13234        resolved,
13235    } = &mut completion.source
13236    else {
13237        return;
13238    };
13239    if *resolved {
13240        return;
13241    }
13242
13243    if completion.new_text
13244        != snapshot
13245            .text_for_range(word_range.clone())
13246            .collect::<String>()
13247    {
13248        return;
13249    }
13250
13251    let mut offset = 0;
13252    for chunk in snapshot.chunks(word_range.clone(), true) {
13253        let end_offset = offset + chunk.text.len();
13254        if let Some(highlight_id) = chunk.syntax_highlight_id {
13255            completion
13256                .label
13257                .runs
13258                .push((offset..end_offset, highlight_id));
13259        }
13260        offset = end_offset;
13261    }
13262    *resolved = true;
13263}
13264
13265impl EventEmitter<LspStoreEvent> for LspStore {}
13266
13267fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13268    hover
13269        .contents
13270        .retain(|hover_block| !hover_block.text.trim().is_empty());
13271    if hover.contents.is_empty() {
13272        None
13273    } else {
13274        Some(hover)
13275    }
13276}
13277
13278async fn populate_labels_for_completions(
13279    new_completions: Vec<CoreCompletion>,
13280    language: Option<Arc<Language>>,
13281    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13282) -> Vec<Completion> {
13283    let lsp_completions = new_completions
13284        .iter()
13285        .filter_map(|new_completion| {
13286            new_completion
13287                .source
13288                .lsp_completion(true)
13289                .map(|lsp_completion| lsp_completion.into_owned())
13290        })
13291        .collect::<Vec<_>>();
13292
13293    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13294        lsp_adapter
13295            .labels_for_completions(&lsp_completions, language)
13296            .await
13297            .log_err()
13298            .unwrap_or_default()
13299    } else {
13300        Vec::new()
13301    }
13302    .into_iter()
13303    .fuse();
13304
13305    let mut completions = Vec::new();
13306    for completion in new_completions {
13307        match completion.source.lsp_completion(true) {
13308            Some(lsp_completion) => {
13309                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13310
13311                let mut label = labels.next().flatten().unwrap_or_else(|| {
13312                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13313                });
13314                ensure_uniform_list_compatible_label(&mut label);
13315                completions.push(Completion {
13316                    label,
13317                    documentation,
13318                    replace_range: completion.replace_range,
13319                    new_text: completion.new_text,
13320                    insert_text_mode: lsp_completion.insert_text_mode,
13321                    source: completion.source,
13322                    icon_path: None,
13323                    confirm: None,
13324                    match_start: None,
13325                    snippet_deduplication_key: None,
13326                });
13327            }
13328            None => {
13329                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13330                ensure_uniform_list_compatible_label(&mut label);
13331                completions.push(Completion {
13332                    label,
13333                    documentation: None,
13334                    replace_range: completion.replace_range,
13335                    new_text: completion.new_text,
13336                    source: completion.source,
13337                    insert_text_mode: None,
13338                    icon_path: None,
13339                    confirm: None,
13340                    match_start: None,
13341                    snippet_deduplication_key: None,
13342                });
13343            }
13344        }
13345    }
13346    completions
13347}
13348
13349#[derive(Debug)]
13350pub enum LanguageServerToQuery {
13351    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13352    FirstCapable,
13353    /// Query a specific language server.
13354    Other(LanguageServerId),
13355}
13356
13357#[derive(Default)]
13358struct RenamePathsWatchedForServer {
13359    did_rename: Vec<RenameActionPredicate>,
13360    will_rename: Vec<RenameActionPredicate>,
13361}
13362
13363impl RenamePathsWatchedForServer {
13364    fn with_did_rename_patterns(
13365        mut self,
13366        did_rename: Option<&FileOperationRegistrationOptions>,
13367    ) -> Self {
13368        if let Some(did_rename) = did_rename {
13369            self.did_rename = did_rename
13370                .filters
13371                .iter()
13372                .filter_map(|filter| filter.try_into().log_err())
13373                .collect();
13374        }
13375        self
13376    }
13377    fn with_will_rename_patterns(
13378        mut self,
13379        will_rename: Option<&FileOperationRegistrationOptions>,
13380    ) -> Self {
13381        if let Some(will_rename) = will_rename {
13382            self.will_rename = will_rename
13383                .filters
13384                .iter()
13385                .filter_map(|filter| filter.try_into().log_err())
13386                .collect();
13387        }
13388        self
13389    }
13390
13391    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13392        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13393    }
13394    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13395        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13396    }
13397}
13398
13399impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13400    type Error = globset::Error;
13401    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13402        Ok(Self {
13403            kind: ops.pattern.matches.clone(),
13404            glob: GlobBuilder::new(&ops.pattern.glob)
13405                .case_insensitive(
13406                    ops.pattern
13407                        .options
13408                        .as_ref()
13409                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13410                )
13411                .build()?
13412                .compile_matcher(),
13413        })
13414    }
13415}
13416struct RenameActionPredicate {
13417    glob: GlobMatcher,
13418    kind: Option<FileOperationPatternKind>,
13419}
13420
13421impl RenameActionPredicate {
13422    // Returns true if language server should be notified
13423    fn eval(&self, path: &str, is_dir: bool) -> bool {
13424        self.kind.as_ref().is_none_or(|kind| {
13425            let expected_kind = if is_dir {
13426                FileOperationPatternKind::Folder
13427            } else {
13428                FileOperationPatternKind::File
13429            };
13430            kind == &expected_kind
13431        }) && self.glob.is_match(path)
13432    }
13433}
13434
13435#[derive(Default)]
13436struct LanguageServerWatchedPaths {
13437    worktree_paths: HashMap<WorktreeId, GlobSet>,
13438    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13439}
13440
13441#[derive(Default)]
13442struct LanguageServerWatchedPathsBuilder {
13443    worktree_paths: HashMap<WorktreeId, GlobSet>,
13444    abs_paths: HashMap<Arc<Path>, GlobSet>,
13445}
13446
13447impl LanguageServerWatchedPathsBuilder {
13448    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13449        self.worktree_paths.insert(worktree_id, glob_set);
13450    }
13451    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13452        self.abs_paths.insert(path, glob_set);
13453    }
13454    fn build(
13455        self,
13456        fs: Arc<dyn Fs>,
13457        language_server_id: LanguageServerId,
13458        cx: &mut Context<LspStore>,
13459    ) -> LanguageServerWatchedPaths {
13460        let lsp_store = cx.weak_entity();
13461
13462        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13463        let abs_paths = self
13464            .abs_paths
13465            .into_iter()
13466            .map(|(abs_path, globset)| {
13467                let task = cx.spawn({
13468                    let abs_path = abs_path.clone();
13469                    let fs = fs.clone();
13470
13471                    let lsp_store = lsp_store.clone();
13472                    async move |_, cx| {
13473                        maybe!(async move {
13474                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13475                            while let Some(update) = push_updates.0.next().await {
13476                                let action = lsp_store
13477                                    .update(cx, |this, _| {
13478                                        let Some(local) = this.as_local() else {
13479                                            return ControlFlow::Break(());
13480                                        };
13481                                        let Some(watcher) = local
13482                                            .language_server_watched_paths
13483                                            .get(&language_server_id)
13484                                        else {
13485                                            return ControlFlow::Break(());
13486                                        };
13487                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13488                                            "Watched abs path is not registered with a watcher",
13489                                        );
13490                                        let matching_entries = update
13491                                            .into_iter()
13492                                            .filter(|event| globs.is_match(&event.path))
13493                                            .collect::<Vec<_>>();
13494                                        this.lsp_notify_abs_paths_changed(
13495                                            language_server_id,
13496                                            matching_entries,
13497                                        );
13498                                        ControlFlow::Continue(())
13499                                    })
13500                                    .ok()?;
13501
13502                                if action.is_break() {
13503                                    break;
13504                                }
13505                            }
13506                            Some(())
13507                        })
13508                        .await;
13509                    }
13510                });
13511                (abs_path, (globset, task))
13512            })
13513            .collect();
13514        LanguageServerWatchedPaths {
13515            worktree_paths: self.worktree_paths,
13516            abs_paths,
13517        }
13518    }
13519}
13520
13521struct LspBufferSnapshot {
13522    version: i32,
13523    snapshot: TextBufferSnapshot,
13524}
13525
13526/// A prompt requested by LSP server.
13527#[derive(Clone, Debug)]
13528pub struct LanguageServerPromptRequest {
13529    pub level: PromptLevel,
13530    pub message: String,
13531    pub actions: Vec<MessageActionItem>,
13532    pub lsp_name: String,
13533    pub(crate) response_channel: Sender<MessageActionItem>,
13534}
13535
13536impl LanguageServerPromptRequest {
13537    pub async fn respond(self, index: usize) -> Option<()> {
13538        if let Some(response) = self.actions.into_iter().nth(index) {
13539            self.response_channel.send(response).await.ok()
13540        } else {
13541            None
13542        }
13543    }
13544}
13545impl PartialEq for LanguageServerPromptRequest {
13546    fn eq(&self, other: &Self) -> bool {
13547        self.message == other.message && self.actions == other.actions
13548    }
13549}
13550
13551#[derive(Clone, Debug, PartialEq)]
13552pub enum LanguageServerLogType {
13553    Log(MessageType),
13554    Trace { verbose_info: Option<String> },
13555    Rpc { received: bool },
13556}
13557
13558impl LanguageServerLogType {
13559    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13560        match self {
13561            Self::Log(log_type) => {
13562                use proto::log_message::LogLevel;
13563                let level = match *log_type {
13564                    MessageType::ERROR => LogLevel::Error,
13565                    MessageType::WARNING => LogLevel::Warning,
13566                    MessageType::INFO => LogLevel::Info,
13567                    MessageType::LOG => LogLevel::Log,
13568                    other => {
13569                        log::warn!("Unknown lsp log message type: {other:?}");
13570                        LogLevel::Log
13571                    }
13572                };
13573                proto::language_server_log::LogType::Log(proto::LogMessage {
13574                    level: level as i32,
13575                })
13576            }
13577            Self::Trace { verbose_info } => {
13578                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13579                    verbose_info: verbose_info.to_owned(),
13580                })
13581            }
13582            Self::Rpc { received } => {
13583                let kind = if *received {
13584                    proto::rpc_message::Kind::Received
13585                } else {
13586                    proto::rpc_message::Kind::Sent
13587                };
13588                let kind = kind as i32;
13589                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13590            }
13591        }
13592    }
13593
13594    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13595        use proto::log_message::LogLevel;
13596        use proto::rpc_message;
13597        match log_type {
13598            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13599                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13600                    LogLevel::Error => MessageType::ERROR,
13601                    LogLevel::Warning => MessageType::WARNING,
13602                    LogLevel::Info => MessageType::INFO,
13603                    LogLevel::Log => MessageType::LOG,
13604                },
13605            ),
13606            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13607                verbose_info: trace_message.verbose_info,
13608            },
13609            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13610                received: match rpc_message::Kind::from_i32(message.kind)
13611                    .unwrap_or(rpc_message::Kind::Received)
13612                {
13613                    rpc_message::Kind::Received => true,
13614                    rpc_message::Kind::Sent => false,
13615                },
13616            },
13617        }
13618    }
13619}
13620
13621pub struct WorkspaceRefreshTask {
13622    refresh_tx: mpsc::Sender<()>,
13623    progress_tx: mpsc::Sender<()>,
13624    #[allow(dead_code)]
13625    task: Task<()>,
13626}
13627
13628pub enum LanguageServerState {
13629    Starting {
13630        startup: Task<Option<Arc<LanguageServer>>>,
13631        /// List of language servers that will be added to the workspace once it's initialization completes.
13632        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13633    },
13634
13635    Running {
13636        adapter: Arc<CachedLspAdapter>,
13637        server: Arc<LanguageServer>,
13638        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13639        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13640    },
13641}
13642
13643impl LanguageServerState {
13644    fn add_workspace_folder(&self, uri: Uri) {
13645        match self {
13646            LanguageServerState::Starting {
13647                pending_workspace_folders,
13648                ..
13649            } => {
13650                pending_workspace_folders.lock().insert(uri);
13651            }
13652            LanguageServerState::Running { server, .. } => {
13653                server.add_workspace_folder(uri);
13654            }
13655        }
13656    }
13657    fn _remove_workspace_folder(&self, uri: Uri) {
13658        match self {
13659            LanguageServerState::Starting {
13660                pending_workspace_folders,
13661                ..
13662            } => {
13663                pending_workspace_folders.lock().remove(&uri);
13664            }
13665            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13666        }
13667    }
13668}
13669
13670impl std::fmt::Debug for LanguageServerState {
13671    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13672        match self {
13673            LanguageServerState::Starting { .. } => {
13674                f.debug_struct("LanguageServerState::Starting").finish()
13675            }
13676            LanguageServerState::Running { .. } => {
13677                f.debug_struct("LanguageServerState::Running").finish()
13678            }
13679        }
13680    }
13681}
13682
13683#[derive(Clone, Debug, Serialize)]
13684pub struct LanguageServerProgress {
13685    pub is_disk_based_diagnostics_progress: bool,
13686    pub is_cancellable: bool,
13687    pub title: Option<String>,
13688    pub message: Option<String>,
13689    pub percentage: Option<usize>,
13690    #[serde(skip_serializing)]
13691    pub last_update_at: Instant,
13692}
13693
13694#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13695pub struct DiagnosticSummary {
13696    pub error_count: usize,
13697    pub warning_count: usize,
13698}
13699
13700impl DiagnosticSummary {
13701    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13702        let mut this = Self {
13703            error_count: 0,
13704            warning_count: 0,
13705        };
13706
13707        for entry in diagnostics {
13708            if entry.diagnostic.is_primary {
13709                match entry.diagnostic.severity {
13710                    DiagnosticSeverity::ERROR => this.error_count += 1,
13711                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13712                    _ => {}
13713                }
13714            }
13715        }
13716
13717        this
13718    }
13719
13720    pub fn is_empty(&self) -> bool {
13721        self.error_count == 0 && self.warning_count == 0
13722    }
13723
13724    pub fn to_proto(
13725        self,
13726        language_server_id: LanguageServerId,
13727        path: &RelPath,
13728    ) -> proto::DiagnosticSummary {
13729        proto::DiagnosticSummary {
13730            path: path.to_proto(),
13731            language_server_id: language_server_id.0 as u64,
13732            error_count: self.error_count as u32,
13733            warning_count: self.warning_count as u32,
13734        }
13735    }
13736}
13737
13738#[derive(Clone, Debug)]
13739pub enum CompletionDocumentation {
13740    /// There is no documentation for this completion.
13741    Undocumented,
13742    /// A single line of documentation.
13743    SingleLine(SharedString),
13744    /// Multiple lines of plain text documentation.
13745    MultiLinePlainText(SharedString),
13746    /// Markdown documentation.
13747    MultiLineMarkdown(SharedString),
13748    /// Both single line and multiple lines of plain text documentation.
13749    SingleLineAndMultiLinePlainText {
13750        single_line: SharedString,
13751        plain_text: Option<SharedString>,
13752    },
13753}
13754
13755impl CompletionDocumentation {
13756    #[cfg(any(test, feature = "test-support"))]
13757    pub fn text(&self) -> SharedString {
13758        match self {
13759            CompletionDocumentation::Undocumented => "".into(),
13760            CompletionDocumentation::SingleLine(s) => s.clone(),
13761            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13762            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13763            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13764                single_line.clone()
13765            }
13766        }
13767    }
13768}
13769
13770impl From<lsp::Documentation> for CompletionDocumentation {
13771    fn from(docs: lsp::Documentation) -> Self {
13772        match docs {
13773            lsp::Documentation::String(text) => {
13774                if text.lines().count() <= 1 {
13775                    CompletionDocumentation::SingleLine(text.into())
13776                } else {
13777                    CompletionDocumentation::MultiLinePlainText(text.into())
13778                }
13779            }
13780
13781            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13782                lsp::MarkupKind::PlainText => {
13783                    if value.lines().count() <= 1 {
13784                        CompletionDocumentation::SingleLine(value.into())
13785                    } else {
13786                        CompletionDocumentation::MultiLinePlainText(value.into())
13787                    }
13788                }
13789
13790                lsp::MarkupKind::Markdown => {
13791                    CompletionDocumentation::MultiLineMarkdown(value.into())
13792                }
13793            },
13794        }
13795    }
13796}
13797
13798pub enum ResolvedHint {
13799    Resolved(InlayHint),
13800    Resolving(Shared<Task<()>>),
13801}
13802
13803fn glob_literal_prefix(glob: &Path) -> PathBuf {
13804    glob.components()
13805        .take_while(|component| match component {
13806            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13807            _ => true,
13808        })
13809        .collect()
13810}
13811
13812pub struct SshLspAdapter {
13813    name: LanguageServerName,
13814    binary: LanguageServerBinary,
13815    initialization_options: Option<String>,
13816    code_action_kinds: Option<Vec<CodeActionKind>>,
13817}
13818
13819impl SshLspAdapter {
13820    pub fn new(
13821        name: LanguageServerName,
13822        binary: LanguageServerBinary,
13823        initialization_options: Option<String>,
13824        code_action_kinds: Option<String>,
13825    ) -> Self {
13826        Self {
13827            name,
13828            binary,
13829            initialization_options,
13830            code_action_kinds: code_action_kinds
13831                .as_ref()
13832                .and_then(|c| serde_json::from_str(c).ok()),
13833        }
13834    }
13835}
13836
13837impl LspInstaller for SshLspAdapter {
13838    type BinaryVersion = ();
13839    async fn check_if_user_installed(
13840        &self,
13841        _: &dyn LspAdapterDelegate,
13842        _: Option<Toolchain>,
13843        _: &AsyncApp,
13844    ) -> Option<LanguageServerBinary> {
13845        Some(self.binary.clone())
13846    }
13847
13848    async fn cached_server_binary(
13849        &self,
13850        _: PathBuf,
13851        _: &dyn LspAdapterDelegate,
13852    ) -> Option<LanguageServerBinary> {
13853        None
13854    }
13855
13856    async fn fetch_latest_server_version(
13857        &self,
13858        _: &dyn LspAdapterDelegate,
13859        _: bool,
13860        _: &mut AsyncApp,
13861    ) -> Result<()> {
13862        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13863    }
13864
13865    async fn fetch_server_binary(
13866        &self,
13867        _: (),
13868        _: PathBuf,
13869        _: &dyn LspAdapterDelegate,
13870    ) -> Result<LanguageServerBinary> {
13871        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13872    }
13873}
13874
13875#[async_trait(?Send)]
13876impl LspAdapter for SshLspAdapter {
13877    fn name(&self) -> LanguageServerName {
13878        self.name.clone()
13879    }
13880
13881    async fn initialization_options(
13882        self: Arc<Self>,
13883        _: &Arc<dyn LspAdapterDelegate>,
13884    ) -> Result<Option<serde_json::Value>> {
13885        let Some(options) = &self.initialization_options else {
13886            return Ok(None);
13887        };
13888        let result = serde_json::from_str(options)?;
13889        Ok(result)
13890    }
13891
13892    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13893        self.code_action_kinds.clone()
13894    }
13895}
13896
13897pub fn language_server_settings<'a>(
13898    delegate: &'a dyn LspAdapterDelegate,
13899    language: &LanguageServerName,
13900    cx: &'a App,
13901) -> Option<&'a LspSettings> {
13902    language_server_settings_for(
13903        SettingsLocation {
13904            worktree_id: delegate.worktree_id(),
13905            path: RelPath::empty(),
13906        },
13907        language,
13908        cx,
13909    )
13910}
13911
13912pub fn language_server_settings_for<'a>(
13913    location: SettingsLocation<'a>,
13914    language: &LanguageServerName,
13915    cx: &'a App,
13916) -> Option<&'a LspSettings> {
13917    ProjectSettings::get(Some(location), cx).lsp.get(language)
13918}
13919
13920pub struct LocalLspAdapterDelegate {
13921    lsp_store: WeakEntity<LspStore>,
13922    worktree: worktree::Snapshot,
13923    fs: Arc<dyn Fs>,
13924    http_client: Arc<dyn HttpClient>,
13925    language_registry: Arc<LanguageRegistry>,
13926    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13927}
13928
13929impl LocalLspAdapterDelegate {
13930    pub fn new(
13931        language_registry: Arc<LanguageRegistry>,
13932        environment: &Entity<ProjectEnvironment>,
13933        lsp_store: WeakEntity<LspStore>,
13934        worktree: &Entity<Worktree>,
13935        http_client: Arc<dyn HttpClient>,
13936        fs: Arc<dyn Fs>,
13937        cx: &mut App,
13938    ) -> Arc<Self> {
13939        let load_shell_env_task =
13940            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
13941
13942        Arc::new(Self {
13943            lsp_store,
13944            worktree: worktree.read(cx).snapshot(),
13945            fs,
13946            http_client,
13947            language_registry,
13948            load_shell_env_task,
13949        })
13950    }
13951
13952    fn from_local_lsp(
13953        local: &LocalLspStore,
13954        worktree: &Entity<Worktree>,
13955        cx: &mut App,
13956    ) -> Arc<Self> {
13957        Self::new(
13958            local.languages.clone(),
13959            &local.environment,
13960            local.weak.clone(),
13961            worktree,
13962            local.http_client.clone(),
13963            local.fs.clone(),
13964            cx,
13965        )
13966    }
13967}
13968
13969#[async_trait]
13970impl LspAdapterDelegate for LocalLspAdapterDelegate {
13971    fn show_notification(&self, message: &str, cx: &mut App) {
13972        self.lsp_store
13973            .update(cx, |_, cx| {
13974                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13975            })
13976            .ok();
13977    }
13978
13979    fn http_client(&self) -> Arc<dyn HttpClient> {
13980        self.http_client.clone()
13981    }
13982
13983    fn worktree_id(&self) -> WorktreeId {
13984        self.worktree.id()
13985    }
13986
13987    fn worktree_root_path(&self) -> &Path {
13988        self.worktree.abs_path().as_ref()
13989    }
13990
13991    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
13992        self.worktree.resolve_executable_path(path)
13993    }
13994
13995    async fn shell_env(&self) -> HashMap<String, String> {
13996        let task = self.load_shell_env_task.clone();
13997        task.await.unwrap_or_default()
13998    }
13999
14000    async fn npm_package_installed_version(
14001        &self,
14002        package_name: &str,
14003    ) -> Result<Option<(PathBuf, Version)>> {
14004        let local_package_directory = self.worktree_root_path();
14005        let node_modules_directory = local_package_directory.join("node_modules");
14006
14007        if let Some(version) =
14008            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14009        {
14010            return Ok(Some((node_modules_directory, version)));
14011        }
14012        let Some(npm) = self.which("npm".as_ref()).await else {
14013            log::warn!(
14014                "Failed to find npm executable for {:?}",
14015                local_package_directory
14016            );
14017            return Ok(None);
14018        };
14019
14020        let env = self.shell_env().await;
14021        let output = util::command::new_smol_command(&npm)
14022            .args(["root", "-g"])
14023            .envs(env)
14024            .current_dir(local_package_directory)
14025            .output()
14026            .await?;
14027        let global_node_modules =
14028            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14029
14030        if let Some(version) =
14031            read_package_installed_version(global_node_modules.clone(), package_name).await?
14032        {
14033            return Ok(Some((global_node_modules, version)));
14034        }
14035        return Ok(None);
14036    }
14037
14038    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14039        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14040        if self.fs.is_file(&worktree_abs_path).await {
14041            worktree_abs_path.pop();
14042        }
14043
14044        let env = self.shell_env().await;
14045
14046        let shell_path = env.get("PATH").cloned();
14047
14048        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14049    }
14050
14051    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14052        let mut working_dir = self.worktree_root_path().to_path_buf();
14053        if self.fs.is_file(&working_dir).await {
14054            working_dir.pop();
14055        }
14056        let output = util::command::new_smol_command(&command.path)
14057            .args(command.arguments)
14058            .envs(command.env.clone().unwrap_or_default())
14059            .current_dir(working_dir)
14060            .output()
14061            .await?;
14062
14063        anyhow::ensure!(
14064            output.status.success(),
14065            "{}, stdout: {:?}, stderr: {:?}",
14066            output.status,
14067            String::from_utf8_lossy(&output.stdout),
14068            String::from_utf8_lossy(&output.stderr)
14069        );
14070        Ok(())
14071    }
14072
14073    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14074        self.language_registry
14075            .update_lsp_binary_status(server_name, status);
14076    }
14077
14078    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14079        self.language_registry
14080            .all_lsp_adapters()
14081            .into_iter()
14082            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14083            .collect()
14084    }
14085
14086    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14087        let dir = self.language_registry.language_server_download_dir(name)?;
14088
14089        if !dir.exists() {
14090            smol::fs::create_dir_all(&dir)
14091                .await
14092                .context("failed to create container directory")
14093                .log_err()?;
14094        }
14095
14096        Some(dir)
14097    }
14098
14099    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14100        let entry = self
14101            .worktree
14102            .entry_for_path(path)
14103            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14104        let abs_path = self.worktree.absolutize(&entry.path);
14105        self.fs.load(&abs_path).await
14106    }
14107}
14108
14109async fn populate_labels_for_symbols(
14110    symbols: Vec<CoreSymbol>,
14111    language_registry: &Arc<LanguageRegistry>,
14112    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14113    output: &mut Vec<Symbol>,
14114) {
14115    #[allow(clippy::mutable_key_type)]
14116    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14117
14118    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14119    for symbol in symbols {
14120        let Some(file_name) = symbol.path.file_name() else {
14121            continue;
14122        };
14123        let language = language_registry
14124            .load_language_for_file_path(Path::new(file_name))
14125            .await
14126            .ok()
14127            .or_else(|| {
14128                unknown_paths.insert(file_name.into());
14129                None
14130            });
14131        symbols_by_language
14132            .entry(language)
14133            .or_default()
14134            .push(symbol);
14135    }
14136
14137    for unknown_path in unknown_paths {
14138        log::info!("no language found for symbol in file {unknown_path:?}");
14139    }
14140
14141    let mut label_params = Vec::new();
14142    for (language, mut symbols) in symbols_by_language {
14143        label_params.clear();
14144        label_params.extend(
14145            symbols
14146                .iter_mut()
14147                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14148        );
14149
14150        let mut labels = Vec::new();
14151        if let Some(language) = language {
14152            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14153                language_registry
14154                    .lsp_adapters(&language.name())
14155                    .first()
14156                    .cloned()
14157            });
14158            if let Some(lsp_adapter) = lsp_adapter {
14159                labels = lsp_adapter
14160                    .labels_for_symbols(&label_params, &language)
14161                    .await
14162                    .log_err()
14163                    .unwrap_or_default();
14164            }
14165        }
14166
14167        for ((symbol, (name, _)), label) in symbols
14168            .into_iter()
14169            .zip(label_params.drain(..))
14170            .zip(labels.into_iter().chain(iter::repeat(None)))
14171        {
14172            output.push(Symbol {
14173                language_server_name: symbol.language_server_name,
14174                source_worktree_id: symbol.source_worktree_id,
14175                source_language_server_id: symbol.source_language_server_id,
14176                path: symbol.path,
14177                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14178                name,
14179                kind: symbol.kind,
14180                range: symbol.range,
14181            });
14182        }
14183    }
14184}
14185
14186fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14187    match server.capabilities().text_document_sync.as_ref()? {
14188        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14189            // Server wants didSave but didn't specify includeText.
14190            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14191            // Server doesn't want didSave at all.
14192            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14193            // Server provided SaveOptions.
14194            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14195                Some(save_options.include_text.unwrap_or(false))
14196            }
14197        },
14198        // We do not have any save info. Kind affects didChange only.
14199        lsp::TextDocumentSyncCapability::Kind(_) => None,
14200    }
14201}
14202
14203/// Completion items are displayed in a `UniformList`.
14204/// Usually, those items are single-line strings, but in LSP responses,
14205/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14206/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14207/// 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,
14208/// breaking the completions menu presentation.
14209///
14210/// 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.
14211fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14212    let mut new_text = String::with_capacity(label.text.len());
14213    let mut offset_map = vec![0; label.text.len() + 1];
14214    let mut last_char_was_space = false;
14215    let mut new_idx = 0;
14216    let chars = label.text.char_indices().fuse();
14217    let mut newlines_removed = false;
14218
14219    for (idx, c) in chars {
14220        offset_map[idx] = new_idx;
14221
14222        match c {
14223            '\n' if last_char_was_space => {
14224                newlines_removed = true;
14225            }
14226            '\t' | ' ' if last_char_was_space => {}
14227            '\n' if !last_char_was_space => {
14228                new_text.push(' ');
14229                new_idx += 1;
14230                last_char_was_space = true;
14231                newlines_removed = true;
14232            }
14233            ' ' | '\t' => {
14234                new_text.push(' ');
14235                new_idx += 1;
14236                last_char_was_space = true;
14237            }
14238            _ => {
14239                new_text.push(c);
14240                new_idx += c.len_utf8();
14241                last_char_was_space = false;
14242            }
14243        }
14244    }
14245    offset_map[label.text.len()] = new_idx;
14246
14247    // Only modify the label if newlines were removed.
14248    if !newlines_removed {
14249        return;
14250    }
14251
14252    let last_index = new_idx;
14253    let mut run_ranges_errors = Vec::new();
14254    label.runs.retain_mut(|(range, _)| {
14255        match offset_map.get(range.start) {
14256            Some(&start) => range.start = start,
14257            None => {
14258                run_ranges_errors.push(range.clone());
14259                return false;
14260            }
14261        }
14262
14263        match offset_map.get(range.end) {
14264            Some(&end) => range.end = end,
14265            None => {
14266                run_ranges_errors.push(range.clone());
14267                range.end = last_index;
14268            }
14269        }
14270        true
14271    });
14272    if !run_ranges_errors.is_empty() {
14273        log::error!(
14274            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14275            label.text
14276        );
14277    }
14278
14279    let mut wrong_filter_range = None;
14280    if label.filter_range == (0..label.text.len()) {
14281        label.filter_range = 0..new_text.len();
14282    } else {
14283        let mut original_filter_range = Some(label.filter_range.clone());
14284        match offset_map.get(label.filter_range.start) {
14285            Some(&start) => label.filter_range.start = start,
14286            None => {
14287                wrong_filter_range = original_filter_range.take();
14288                label.filter_range.start = last_index;
14289            }
14290        }
14291
14292        match offset_map.get(label.filter_range.end) {
14293            Some(&end) => label.filter_range.end = end,
14294            None => {
14295                wrong_filter_range = original_filter_range.take();
14296                label.filter_range.end = last_index;
14297            }
14298        }
14299    }
14300    if let Some(wrong_filter_range) = wrong_filter_range {
14301        log::error!(
14302            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14303            label.text
14304        );
14305    }
14306
14307    label.text = new_text;
14308}
14309
14310#[cfg(test)]
14311mod tests {
14312    use language::HighlightId;
14313
14314    use super::*;
14315
14316    #[test]
14317    fn test_glob_literal_prefix() {
14318        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14319        assert_eq!(
14320            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14321            Path::new("node_modules")
14322        );
14323        assert_eq!(
14324            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14325            Path::new("foo")
14326        );
14327        assert_eq!(
14328            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14329            Path::new("foo/bar/baz.js")
14330        );
14331
14332        #[cfg(target_os = "windows")]
14333        {
14334            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14335            assert_eq!(
14336                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14337                Path::new("node_modules")
14338            );
14339            assert_eq!(
14340                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14341                Path::new("foo")
14342            );
14343            assert_eq!(
14344                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14345                Path::new("foo/bar/baz.js")
14346            );
14347        }
14348    }
14349
14350    #[test]
14351    fn test_multi_len_chars_normalization() {
14352        let mut label = CodeLabel::new(
14353            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14354            0..6,
14355            vec![(0..6, HighlightId(1))],
14356        );
14357        ensure_uniform_list_compatible_label(&mut label);
14358        assert_eq!(
14359            label,
14360            CodeLabel::new(
14361                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14362                0..6,
14363                vec![(0..6, HighlightId(1))],
14364            )
14365        );
14366    }
14367}