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, Capability, CodeLabel,
   65    Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language,
   66    LanguageName, LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller,
   67    ManifestDelegate, ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16,
   68    Toolchain, 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#[cfg(test)]
  253impl DocumentDiagnostics {
  254    pub fn new(
  255        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  256        document_abs_path: PathBuf,
  257        version: Option<i32>,
  258    ) -> Self {
  259        Self {
  260            diagnostics,
  261            document_abs_path,
  262            version,
  263        }
  264    }
  265}
  266
  267#[derive(Default, Debug)]
  268struct DynamicRegistrations {
  269    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  270    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  271}
  272
  273pub struct LocalLspStore {
  274    weak: WeakEntity<LspStore>,
  275    pub worktree_store: Entity<WorktreeStore>,
  276    toolchain_store: Entity<LocalToolchainStore>,
  277    http_client: Arc<dyn HttpClient>,
  278    environment: Entity<ProjectEnvironment>,
  279    fs: Arc<dyn Fs>,
  280    languages: Arc<LanguageRegistry>,
  281    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  282    yarn: Entity<YarnPathStore>,
  283    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  284    buffers_being_formatted: HashSet<BufferId>,
  285    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  286    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  287    watched_manifest_filenames: HashSet<ManifestName>,
  288    language_server_paths_watched_for_rename:
  289        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  290    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  291    supplementary_language_servers:
  292        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  293    prettier_store: Entity<PrettierStore>,
  294    next_diagnostic_group_id: usize,
  295    diagnostics: HashMap<
  296        WorktreeId,
  297        HashMap<
  298            Arc<RelPath>,
  299            Vec<(
  300                LanguageServerId,
  301                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  302            )>,
  303        >,
  304    >,
  305    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  306    _subscription: gpui::Subscription,
  307    lsp_tree: LanguageServerTree,
  308    registered_buffers: HashMap<BufferId, usize>,
  309    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  310    buffer_pull_diagnostics_result_ids: HashMap<
  311        LanguageServerId,
  312        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  313    >,
  314    workspace_pull_diagnostics_result_ids: HashMap<
  315        LanguageServerId,
  316        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  317    >,
  318    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, Receiver<()>)>,
  319}
  320
  321impl LocalLspStore {
  322    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  323    pub fn running_language_server_for_id(
  324        &self,
  325        id: LanguageServerId,
  326    ) -> Option<&Arc<LanguageServer>> {
  327        let language_server_state = self.language_servers.get(&id)?;
  328
  329        match language_server_state {
  330            LanguageServerState::Running { server, .. } => Some(server),
  331            LanguageServerState::Starting { .. } => None,
  332        }
  333    }
  334
  335    fn get_or_insert_language_server(
  336        &mut self,
  337        worktree_handle: &Entity<Worktree>,
  338        delegate: Arc<LocalLspAdapterDelegate>,
  339        disposition: &Arc<LaunchDisposition>,
  340        language_name: &LanguageName,
  341        cx: &mut App,
  342    ) -> LanguageServerId {
  343        let key = LanguageServerSeed {
  344            worktree_id: worktree_handle.read(cx).id(),
  345            name: disposition.server_name.clone(),
  346            settings: disposition.settings.clone(),
  347            toolchain: disposition.toolchain.clone(),
  348        };
  349        if let Some(state) = self.language_server_ids.get_mut(&key) {
  350            state.project_roots.insert(disposition.path.path.clone());
  351            state.id
  352        } else {
  353            let adapter = self
  354                .languages
  355                .lsp_adapters(language_name)
  356                .into_iter()
  357                .find(|adapter| adapter.name() == disposition.server_name)
  358                .expect("To find LSP adapter");
  359            let new_language_server_id = self.start_language_server(
  360                worktree_handle,
  361                delegate,
  362                adapter,
  363                disposition.settings.clone(),
  364                key.clone(),
  365                cx,
  366            );
  367            if let Some(state) = self.language_server_ids.get_mut(&key) {
  368                state.project_roots.insert(disposition.path.path.clone());
  369            } else {
  370                debug_assert!(
  371                    false,
  372                    "Expected `start_language_server` to ensure that `key` exists in a map"
  373                );
  374            }
  375            new_language_server_id
  376        }
  377    }
  378
  379    fn start_language_server(
  380        &mut self,
  381        worktree_handle: &Entity<Worktree>,
  382        delegate: Arc<LocalLspAdapterDelegate>,
  383        adapter: Arc<CachedLspAdapter>,
  384        settings: Arc<LspSettings>,
  385        key: LanguageServerSeed,
  386        cx: &mut App,
  387    ) -> LanguageServerId {
  388        let worktree = worktree_handle.read(cx);
  389
  390        let worktree_id = worktree.id();
  391        let worktree_abs_path = worktree.abs_path();
  392        let toolchain = key.toolchain.clone();
  393        let override_options = settings.initialization_options.clone();
  394
  395        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  396
  397        let server_id = self.languages.next_language_server_id();
  398        log::trace!(
  399            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  400            adapter.name.0
  401        );
  402
  403        let untrusted_worktree_task =
  404            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  405                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  406                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  407                });
  408                if can_trust {
  409                    self.restricted_worktrees_tasks.remove(&worktree_id);
  410                    None
  411                } else {
  412                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  413                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  414                        hash_map::Entry::Vacant(v) => {
  415                            let (tx, rx) = smol::channel::bounded::<()>(1);
  416                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, _| {
  417                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  418                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  419                                        tx.send_blocking(()).ok();
  420                                    }
  421                                }
  422                            });
  423                            v.insert((subscription, rx.clone()));
  424                            Some(rx)
  425                        }
  426                    }
  427                }
  428            });
  429        let update_binary_status = untrusted_worktree_task.is_none();
  430
  431        let binary = self.get_language_server_binary(
  432            worktree_abs_path.clone(),
  433            adapter.clone(),
  434            settings,
  435            toolchain.clone(),
  436            delegate.clone(),
  437            true,
  438            untrusted_worktree_task,
  439            cx,
  440        );
  441        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  442
  443        let pending_server = cx.spawn({
  444            let adapter = adapter.clone();
  445            let server_name = adapter.name.clone();
  446            let stderr_capture = stderr_capture.clone();
  447            #[cfg(any(test, feature = "test-support"))]
  448            let lsp_store = self.weak.clone();
  449            let pending_workspace_folders = pending_workspace_folders.clone();
  450            async move |cx| {
  451                let binary = binary.await?;
  452                #[cfg(any(test, feature = "test-support"))]
  453                if let Some(server) = lsp_store
  454                    .update(&mut cx.clone(), |this, cx| {
  455                        this.languages.create_fake_language_server(
  456                            server_id,
  457                            &server_name,
  458                            binary.clone(),
  459                            &mut cx.to_async(),
  460                        )
  461                    })
  462                    .ok()
  463                    .flatten()
  464                {
  465                    return Ok(server);
  466                }
  467
  468                let code_action_kinds = adapter.code_action_kinds();
  469                lsp::LanguageServer::new(
  470                    stderr_capture,
  471                    server_id,
  472                    server_name,
  473                    binary,
  474                    &worktree_abs_path,
  475                    code_action_kinds,
  476                    Some(pending_workspace_folders),
  477                    cx,
  478                )
  479            }
  480        });
  481
  482        let startup = {
  483            let server_name = adapter.name.0.clone();
  484            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  485            let key = key.clone();
  486            let adapter = adapter.clone();
  487            let lsp_store = self.weak.clone();
  488            let pending_workspace_folders = pending_workspace_folders.clone();
  489
  490            let pull_diagnostics = ProjectSettings::get_global(cx)
  491                .diagnostics
  492                .lsp_pull_diagnostics
  493                .enabled;
  494            cx.spawn(async move |cx| {
  495                let result = async {
  496                    let language_server = pending_server.await?;
  497
  498                    let workspace_config = Self::workspace_configuration_for_adapter(
  499                        adapter.adapter.clone(),
  500                        &delegate,
  501                        toolchain,
  502                        None,
  503                        cx,
  504                    )
  505                    .await?;
  506
  507                    let mut initialization_options = Self::initialization_options_for_adapter(
  508                        adapter.adapter.clone(),
  509                        &delegate,
  510                    )
  511                    .await?;
  512
  513                    match (&mut initialization_options, override_options) {
  514                        (Some(initialization_options), Some(override_options)) => {
  515                            merge_json_value_into(override_options, initialization_options);
  516                        }
  517                        (None, override_options) => initialization_options = override_options,
  518                        _ => {}
  519                    }
  520
  521                    let initialization_params = cx.update(|cx| {
  522                        let mut params =
  523                            language_server.default_initialize_params(pull_diagnostics, cx);
  524                        params.initialization_options = initialization_options;
  525                        adapter.adapter.prepare_initialize_params(params, cx)
  526                    })?;
  527
  528                    Self::setup_lsp_messages(
  529                        lsp_store.clone(),
  530                        &language_server,
  531                        delegate.clone(),
  532                        adapter.clone(),
  533                    );
  534
  535                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  536                        settings: workspace_config,
  537                    };
  538                    let language_server = cx
  539                        .update(|cx| {
  540                            language_server.initialize(
  541                                initialization_params,
  542                                Arc::new(did_change_configuration_params.clone()),
  543                                cx,
  544                            )
  545                        })
  546                        .await
  547                        .inspect_err(|_| {
  548                            if let Some(lsp_store) = lsp_store.upgrade() {
  549                                lsp_store.update(cx, |lsp_store, cx| {
  550                                    lsp_store.cleanup_lsp_data(server_id);
  551                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  552                                });
  553                            }
  554                        })?;
  555
  556                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  557                        did_change_configuration_params,
  558                    )?;
  559
  560                    anyhow::Ok(language_server)
  561                }
  562                .await;
  563
  564                match result {
  565                    Ok(server) => {
  566                        lsp_store
  567                            .update(cx, |lsp_store, cx| {
  568                                lsp_store.insert_newly_running_language_server(
  569                                    adapter,
  570                                    server.clone(),
  571                                    server_id,
  572                                    key,
  573                                    pending_workspace_folders,
  574                                    cx,
  575                                );
  576                            })
  577                            .ok();
  578                        stderr_capture.lock().take();
  579                        Some(server)
  580                    }
  581
  582                    Err(err) => {
  583                        let log = stderr_capture.lock().take().unwrap_or_default();
  584                        delegate.update_status(
  585                            adapter.name(),
  586                            BinaryStatus::Failed {
  587                                error: if log.is_empty() {
  588                                    format!("{err:#}")
  589                                } else {
  590                                    format!("{err:#}\n-- stderr --\n{log}")
  591                                },
  592                            },
  593                        );
  594                        log::error!(
  595                            "Failed to start language server {server_name:?}: {}",
  596                            redact_command(&format!("{err:?}"))
  597                        );
  598                        if !log.is_empty() {
  599                            log::error!("server stderr: {}", redact_command(&log));
  600                        }
  601                        None
  602                    }
  603                }
  604            })
  605        };
  606        let state = LanguageServerState::Starting {
  607            startup,
  608            pending_workspace_folders,
  609        };
  610
  611        if update_binary_status {
  612            self.languages
  613                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  614        }
  615
  616        self.language_servers.insert(server_id, state);
  617        self.language_server_ids
  618            .entry(key)
  619            .or_insert(UnifiedLanguageServer {
  620                id: server_id,
  621                project_roots: Default::default(),
  622            });
  623        server_id
  624    }
  625
  626    fn get_language_server_binary(
  627        &self,
  628        worktree_abs_path: Arc<Path>,
  629        adapter: Arc<CachedLspAdapter>,
  630        settings: Arc<LspSettings>,
  631        toolchain: Option<Toolchain>,
  632        delegate: Arc<dyn LspAdapterDelegate>,
  633        allow_binary_download: bool,
  634        untrusted_worktree_task: Option<Receiver<()>>,
  635        cx: &mut App,
  636    ) -> Task<Result<LanguageServerBinary>> {
  637        if let Some(settings) = &settings.binary
  638            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  639        {
  640            let settings = settings.clone();
  641            let languages = self.languages.clone();
  642            return cx.background_spawn(async move {
  643                if let Some(untrusted_worktree_task) = untrusted_worktree_task {
  644                    log::info!(
  645                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  646                        adapter.name(),
  647                    );
  648                    untrusted_worktree_task.recv().await.ok();
  649                    log::info!(
  650                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  651                        adapter.name(),
  652                    );
  653                    languages
  654                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  655                }
  656                let mut env = delegate.shell_env().await;
  657                env.extend(settings.env.unwrap_or_default());
  658
  659                Ok(LanguageServerBinary {
  660                    path: delegate.resolve_executable_path(path),
  661                    env: Some(env),
  662                    arguments: settings
  663                        .arguments
  664                        .unwrap_or_default()
  665                        .iter()
  666                        .map(Into::into)
  667                        .collect(),
  668                })
  669            });
  670        }
  671        let lsp_binary_options = LanguageServerBinaryOptions {
  672            allow_path_lookup: !settings
  673                .binary
  674                .as_ref()
  675                .and_then(|b| b.ignore_system_version)
  676                .unwrap_or_default(),
  677            allow_binary_download,
  678            pre_release: settings
  679                .fetch
  680                .as_ref()
  681                .and_then(|f| f.pre_release)
  682                .unwrap_or(false),
  683        };
  684
  685        cx.spawn(async move |cx| {
  686            if let Some(untrusted_worktree_task) = untrusted_worktree_task {
  687                log::info!(
  688                    "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  689                    adapter.name(),
  690                );
  691                untrusted_worktree_task.recv().await.ok();
  692                log::info!(
  693                    "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  694                    adapter.name(),
  695                );
  696            }
  697
  698            let (existing_binary, maybe_download_binary) = adapter
  699                .clone()
  700                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  701                .await
  702                .await;
  703
  704            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  705
  706            let mut binary = match (existing_binary, maybe_download_binary) {
  707                (binary, None) => binary?,
  708                (Err(_), Some(downloader)) => downloader.await?,
  709                (Ok(existing_binary), Some(downloader)) => {
  710                    let mut download_timeout = cx
  711                        .background_executor()
  712                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  713                        .fuse();
  714                    let mut downloader = downloader.fuse();
  715                    futures::select! {
  716                        _ = download_timeout => {
  717                            // Return existing binary and kick the existing work to the background.
  718                            cx.spawn(async move |_| downloader.await).detach();
  719                            Ok(existing_binary)
  720                        },
  721                        downloaded_or_existing_binary = downloader => {
  722                            // If download fails, this results in the existing binary.
  723                            downloaded_or_existing_binary
  724                        }
  725                    }?
  726                }
  727            };
  728            let mut shell_env = delegate.shell_env().await;
  729
  730            shell_env.extend(binary.env.unwrap_or_default());
  731
  732            if let Some(settings) = settings.binary.as_ref() {
  733                if let Some(arguments) = &settings.arguments {
  734                    binary.arguments = arguments.iter().map(Into::into).collect();
  735                }
  736                if let Some(env) = &settings.env {
  737                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  738                }
  739            }
  740
  741            binary.env = Some(shell_env);
  742            Ok(binary)
  743        })
  744    }
  745
  746    fn setup_lsp_messages(
  747        lsp_store: WeakEntity<LspStore>,
  748        language_server: &LanguageServer,
  749        delegate: Arc<dyn LspAdapterDelegate>,
  750        adapter: Arc<CachedLspAdapter>,
  751    ) {
  752        let name = language_server.name();
  753        let server_id = language_server.server_id();
  754        language_server
  755            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  756                let adapter = adapter.clone();
  757                let this = lsp_store.clone();
  758                move |mut params, cx| {
  759                    let adapter = adapter.clone();
  760                    if let Some(this) = this.upgrade() {
  761                        this.update(cx, |this, cx| {
  762                            {
  763                                let buffer = params
  764                                    .uri
  765                                    .to_file_path()
  766                                    .map(|file_path| this.get_buffer(&file_path, cx))
  767                                    .ok()
  768                                    .flatten();
  769                                adapter.process_diagnostics(&mut params, server_id, buffer);
  770                            }
  771
  772                            this.merge_lsp_diagnostics(
  773                                DiagnosticSourceKind::Pushed,
  774                                vec![DocumentDiagnosticsUpdate {
  775                                    server_id,
  776                                    diagnostics: params,
  777                                    result_id: None,
  778                                    disk_based_sources: Cow::Borrowed(
  779                                        &adapter.disk_based_diagnostic_sources,
  780                                    ),
  781                                    registration_id: None,
  782                                }],
  783                                |_, diagnostic, cx| match diagnostic.source_kind {
  784                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  785                                        adapter.retain_old_diagnostic(diagnostic, cx)
  786                                    }
  787                                    DiagnosticSourceKind::Pulled => true,
  788                                },
  789                                cx,
  790                            )
  791                            .log_err();
  792                        });
  793                    }
  794                }
  795            })
  796            .detach();
  797        language_server
  798            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  799                let adapter = adapter.adapter.clone();
  800                let delegate = delegate.clone();
  801                let this = lsp_store.clone();
  802                move |params, cx| {
  803                    let adapter = adapter.clone();
  804                    let delegate = delegate.clone();
  805                    let this = this.clone();
  806                    let mut cx = cx.clone();
  807                    async move {
  808                        let toolchain_for_id = this
  809                            .update(&mut cx, |this, _| {
  810                                this.as_local()?.language_server_ids.iter().find_map(
  811                                    |(seed, value)| {
  812                                        (value.id == server_id).then(|| seed.toolchain.clone())
  813                                    },
  814                                )
  815                            })?
  816                            .context("Expected the LSP store to be in a local mode")?;
  817
  818                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  819                        for item in &params.items {
  820                            let scope_uri = item.scope_uri.clone();
  821                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  822                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  823                            else {
  824                                // We've already queried workspace configuration of this URI.
  825                                continue;
  826                            };
  827                            let workspace_config = Self::workspace_configuration_for_adapter(
  828                                adapter.clone(),
  829                                &delegate,
  830                                toolchain_for_id.clone(),
  831                                scope_uri,
  832                                &mut cx,
  833                            )
  834                            .await?;
  835                            new_scope_uri.insert(workspace_config);
  836                        }
  837
  838                        Ok(params
  839                            .items
  840                            .into_iter()
  841                            .filter_map(|item| {
  842                                let workspace_config =
  843                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  844                                if let Some(section) = &item.section {
  845                                    Some(
  846                                        workspace_config
  847                                            .get(section)
  848                                            .cloned()
  849                                            .unwrap_or(serde_json::Value::Null),
  850                                    )
  851                                } else {
  852                                    Some(workspace_config.clone())
  853                                }
  854                            })
  855                            .collect())
  856                    }
  857                }
  858            })
  859            .detach();
  860
  861        language_server
  862            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  863                let this = lsp_store.clone();
  864                move |_, cx| {
  865                    let this = this.clone();
  866                    let cx = cx.clone();
  867                    async move {
  868                        let Some(server) =
  869                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  870                        else {
  871                            return Ok(None);
  872                        };
  873                        let root = server.workspace_folders();
  874                        Ok(Some(
  875                            root.into_iter()
  876                                .map(|uri| WorkspaceFolder {
  877                                    uri,
  878                                    name: Default::default(),
  879                                })
  880                                .collect(),
  881                        ))
  882                    }
  883                }
  884            })
  885            .detach();
  886        // Even though we don't have handling for these requests, respond to them to
  887        // avoid stalling any language server like `gopls` which waits for a response
  888        // to these requests when initializing.
  889        language_server
  890            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  891                let this = lsp_store.clone();
  892                move |params, cx| {
  893                    let this = this.clone();
  894                    let mut cx = cx.clone();
  895                    async move {
  896                        this.update(&mut cx, |this, _| {
  897                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  898                            {
  899                                status
  900                                    .progress_tokens
  901                                    .insert(ProgressToken::from_lsp(params.token));
  902                            }
  903                        })?;
  904
  905                        Ok(())
  906                    }
  907                }
  908            })
  909            .detach();
  910
  911        language_server
  912            .on_request::<lsp::request::RegisterCapability, _, _>({
  913                let lsp_store = lsp_store.clone();
  914                move |params, cx| {
  915                    let lsp_store = lsp_store.clone();
  916                    let mut cx = cx.clone();
  917                    async move {
  918                        lsp_store
  919                            .update(&mut cx, |lsp_store, cx| {
  920                                if lsp_store.as_local().is_some() {
  921                                    match lsp_store
  922                                        .register_server_capabilities(server_id, params, cx)
  923                                    {
  924                                        Ok(()) => {}
  925                                        Err(e) => {
  926                                            log::error!(
  927                                                "Failed to register server capabilities: {e:#}"
  928                                            );
  929                                        }
  930                                    };
  931                                }
  932                            })
  933                            .ok();
  934                        Ok(())
  935                    }
  936                }
  937            })
  938            .detach();
  939
  940        language_server
  941            .on_request::<lsp::request::UnregisterCapability, _, _>({
  942                let lsp_store = lsp_store.clone();
  943                move |params, cx| {
  944                    let lsp_store = lsp_store.clone();
  945                    let mut cx = cx.clone();
  946                    async move {
  947                        lsp_store
  948                            .update(&mut cx, |lsp_store, cx| {
  949                                if lsp_store.as_local().is_some() {
  950                                    match lsp_store
  951                                        .unregister_server_capabilities(server_id, params, cx)
  952                                    {
  953                                        Ok(()) => {}
  954                                        Err(e) => {
  955                                            log::error!(
  956                                                "Failed to unregister server capabilities: {e:#}"
  957                                            );
  958                                        }
  959                                    }
  960                                }
  961                            })
  962                            .ok();
  963                        Ok(())
  964                    }
  965                }
  966            })
  967            .detach();
  968
  969        language_server
  970            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  971                let this = lsp_store.clone();
  972                move |params, cx| {
  973                    let mut cx = cx.clone();
  974                    let this = this.clone();
  975                    async move {
  976                        LocalLspStore::on_lsp_workspace_edit(
  977                            this.clone(),
  978                            params,
  979                            server_id,
  980                            &mut cx,
  981                        )
  982                        .await
  983                    }
  984                }
  985            })
  986            .detach();
  987
  988        language_server
  989            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  990                let lsp_store = lsp_store.clone();
  991                let request_id = Arc::new(AtomicUsize::new(0));
  992                move |(), cx| {
  993                    let lsp_store = lsp_store.clone();
  994                    let request_id = request_id.clone();
  995                    let mut cx = cx.clone();
  996                    async move {
  997                        lsp_store
  998                            .update(&mut cx, |lsp_store, cx| {
  999                                let request_id =
 1000                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1001                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1002                                    server_id,
 1003                                    request_id,
 1004                                });
 1005                                lsp_store
 1006                                    .downstream_client
 1007                                    .as_ref()
 1008                                    .map(|(client, project_id)| {
 1009                                        client.send(proto::RefreshInlayHints {
 1010                                            project_id: *project_id,
 1011                                            server_id: server_id.to_proto(),
 1012                                            request_id: request_id.map(|id| id as u64),
 1013                                        })
 1014                                    })
 1015                            })?
 1016                            .transpose()?;
 1017                        Ok(())
 1018                    }
 1019                }
 1020            })
 1021            .detach();
 1022
 1023        language_server
 1024            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1025                let this = lsp_store.clone();
 1026                move |(), cx| {
 1027                    let this = this.clone();
 1028                    let mut cx = cx.clone();
 1029                    async move {
 1030                        this.update(&mut cx, |this, cx| {
 1031                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1032                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1033                                client.send(proto::RefreshCodeLens {
 1034                                    project_id: *project_id,
 1035                                })
 1036                            })
 1037                        })?
 1038                        .transpose()?;
 1039                        Ok(())
 1040                    }
 1041                }
 1042            })
 1043            .detach();
 1044
 1045        language_server
 1046            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1047                let this = lsp_store.clone();
 1048                move |(), cx| {
 1049                    let this = this.clone();
 1050                    let mut cx = cx.clone();
 1051                    async move {
 1052                        this.update(&mut cx, |lsp_store, cx| {
 1053                            lsp_store.pull_workspace_diagnostics(server_id);
 1054                            lsp_store
 1055                                .downstream_client
 1056                                .as_ref()
 1057                                .map(|(client, project_id)| {
 1058                                    client.send(proto::PullWorkspaceDiagnostics {
 1059                                        project_id: *project_id,
 1060                                        server_id: server_id.to_proto(),
 1061                                    })
 1062                                })
 1063                                .transpose()?;
 1064                            anyhow::Ok(
 1065                                lsp_store.pull_document_diagnostics_for_server(server_id, cx),
 1066                            )
 1067                        })??
 1068                        .await;
 1069                        Ok(())
 1070                    }
 1071                }
 1072            })
 1073            .detach();
 1074
 1075        language_server
 1076            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1077                let this = lsp_store.clone();
 1078                let name = name.to_string();
 1079                let adapter = adapter.clone();
 1080                move |params, cx| {
 1081                    let this = this.clone();
 1082                    let name = name.to_string();
 1083                    let adapter = adapter.clone();
 1084                    let mut cx = cx.clone();
 1085                    async move {
 1086                        let actions = params.actions.unwrap_or_default();
 1087                        let message = params.message.clone();
 1088                        let (tx, rx) = smol::channel::bounded(1);
 1089                        let request = LanguageServerPromptRequest {
 1090                            level: match params.typ {
 1091                                lsp::MessageType::ERROR => PromptLevel::Critical,
 1092                                lsp::MessageType::WARNING => PromptLevel::Warning,
 1093                                _ => PromptLevel::Info,
 1094                            },
 1095                            message: params.message,
 1096                            actions,
 1097                            response_channel: tx,
 1098                            lsp_name: name.clone(),
 1099                        };
 1100
 1101                        let did_update = this
 1102                            .update(&mut cx, |_, cx| {
 1103                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1104                            })
 1105                            .is_ok();
 1106                        if did_update {
 1107                            let response = rx.recv().await.ok();
 1108                            if let Some(ref selected_action) = response {
 1109                                let context = language::PromptResponseContext {
 1110                                    message,
 1111                                    selected_action: selected_action.clone(),
 1112                                };
 1113                                adapter.process_prompt_response(&context, &mut cx)
 1114                            }
 1115
 1116                            Ok(response)
 1117                        } else {
 1118                            Ok(None)
 1119                        }
 1120                    }
 1121                }
 1122            })
 1123            .detach();
 1124        language_server
 1125            .on_notification::<lsp::notification::ShowMessage, _>({
 1126                let this = lsp_store.clone();
 1127                let name = name.to_string();
 1128                move |params, cx| {
 1129                    let this = this.clone();
 1130                    let name = name.to_string();
 1131                    let mut cx = cx.clone();
 1132
 1133                    let (tx, _) = smol::channel::bounded(1);
 1134                    let request = LanguageServerPromptRequest {
 1135                        level: match params.typ {
 1136                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1137                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1138                            _ => PromptLevel::Info,
 1139                        },
 1140                        message: params.message,
 1141                        actions: vec![],
 1142                        response_channel: tx,
 1143                        lsp_name: name,
 1144                    };
 1145
 1146                    let _ = this.update(&mut cx, |_, cx| {
 1147                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1148                    });
 1149                }
 1150            })
 1151            .detach();
 1152
 1153        let disk_based_diagnostics_progress_token =
 1154            adapter.disk_based_diagnostics_progress_token.clone();
 1155
 1156        language_server
 1157            .on_notification::<lsp::notification::Progress, _>({
 1158                let this = lsp_store.clone();
 1159                move |params, cx| {
 1160                    if let Some(this) = this.upgrade() {
 1161                        this.update(cx, |this, cx| {
 1162                            this.on_lsp_progress(
 1163                                params,
 1164                                server_id,
 1165                                disk_based_diagnostics_progress_token.clone(),
 1166                                cx,
 1167                            );
 1168                        });
 1169                    }
 1170                }
 1171            })
 1172            .detach();
 1173
 1174        language_server
 1175            .on_notification::<lsp::notification::LogMessage, _>({
 1176                let this = lsp_store.clone();
 1177                move |params, cx| {
 1178                    if let Some(this) = this.upgrade() {
 1179                        this.update(cx, |_, cx| {
 1180                            cx.emit(LspStoreEvent::LanguageServerLog(
 1181                                server_id,
 1182                                LanguageServerLogType::Log(params.typ),
 1183                                params.message,
 1184                            ));
 1185                        });
 1186                    }
 1187                }
 1188            })
 1189            .detach();
 1190
 1191        language_server
 1192            .on_notification::<lsp::notification::LogTrace, _>({
 1193                let this = lsp_store.clone();
 1194                move |params, cx| {
 1195                    let mut cx = cx.clone();
 1196                    if let Some(this) = this.upgrade() {
 1197                        this.update(&mut cx, |_, cx| {
 1198                            cx.emit(LspStoreEvent::LanguageServerLog(
 1199                                server_id,
 1200                                LanguageServerLogType::Trace {
 1201                                    verbose_info: params.verbose,
 1202                                },
 1203                                params.message,
 1204                            ));
 1205                        });
 1206                    }
 1207                }
 1208            })
 1209            .detach();
 1210
 1211        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1212        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1213        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1214        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1215    }
 1216
 1217    fn shutdown_language_servers_on_quit(
 1218        &mut self,
 1219        _: &mut Context<LspStore>,
 1220    ) -> impl Future<Output = ()> + use<> {
 1221        let shutdown_futures = self
 1222            .language_servers
 1223            .drain()
 1224            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1225            .collect::<Vec<_>>();
 1226
 1227        async move {
 1228            join_all(shutdown_futures).await;
 1229        }
 1230    }
 1231
 1232    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1233        match server_state {
 1234            LanguageServerState::Running { server, .. } => {
 1235                if let Some(shutdown) = server.shutdown() {
 1236                    shutdown.await;
 1237                }
 1238            }
 1239            LanguageServerState::Starting { startup, .. } => {
 1240                if let Some(server) = startup.await
 1241                    && let Some(shutdown) = server.shutdown()
 1242                {
 1243                    shutdown.await;
 1244                }
 1245            }
 1246        }
 1247        Ok(())
 1248    }
 1249
 1250    fn language_servers_for_worktree(
 1251        &self,
 1252        worktree_id: WorktreeId,
 1253    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1254        self.language_server_ids
 1255            .iter()
 1256            .filter_map(move |(seed, state)| {
 1257                if seed.worktree_id != worktree_id {
 1258                    return None;
 1259                }
 1260
 1261                if let Some(LanguageServerState::Running { server, .. }) =
 1262                    self.language_servers.get(&state.id)
 1263                {
 1264                    Some(server)
 1265                } else {
 1266                    None
 1267                }
 1268            })
 1269    }
 1270
 1271    fn language_server_ids_for_project_path(
 1272        &self,
 1273        project_path: ProjectPath,
 1274        language: &Language,
 1275        cx: &mut App,
 1276    ) -> Vec<LanguageServerId> {
 1277        let Some(worktree) = self
 1278            .worktree_store
 1279            .read(cx)
 1280            .worktree_for_id(project_path.worktree_id, cx)
 1281        else {
 1282            return Vec::new();
 1283        };
 1284        let delegate: Arc<dyn ManifestDelegate> =
 1285            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1286
 1287        self.lsp_tree
 1288            .get(
 1289                project_path,
 1290                language.name(),
 1291                language.manifest(),
 1292                &delegate,
 1293                cx,
 1294            )
 1295            .collect::<Vec<_>>()
 1296    }
 1297
 1298    fn language_server_ids_for_buffer(
 1299        &self,
 1300        buffer: &Buffer,
 1301        cx: &mut App,
 1302    ) -> Vec<LanguageServerId> {
 1303        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1304            let worktree_id = file.worktree_id(cx);
 1305
 1306            let path: Arc<RelPath> = file
 1307                .path()
 1308                .parent()
 1309                .map(Arc::from)
 1310                .unwrap_or_else(|| file.path().clone());
 1311            let worktree_path = ProjectPath { worktree_id, path };
 1312            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1313        } else {
 1314            Vec::new()
 1315        }
 1316    }
 1317
 1318    fn language_servers_for_buffer<'a>(
 1319        &'a self,
 1320        buffer: &'a Buffer,
 1321        cx: &'a mut App,
 1322    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1323        self.language_server_ids_for_buffer(buffer, cx)
 1324            .into_iter()
 1325            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1326                LanguageServerState::Running {
 1327                    adapter, server, ..
 1328                } => Some((adapter, server)),
 1329                _ => None,
 1330            })
 1331    }
 1332
 1333    async fn execute_code_action_kind_locally(
 1334        lsp_store: WeakEntity<LspStore>,
 1335        mut buffers: Vec<Entity<Buffer>>,
 1336        kind: CodeActionKind,
 1337        push_to_history: bool,
 1338        cx: &mut AsyncApp,
 1339    ) -> anyhow::Result<ProjectTransaction> {
 1340        // Do not allow multiple concurrent code actions requests for the
 1341        // same buffer.
 1342        lsp_store.update(cx, |this, cx| {
 1343            let this = this.as_local_mut().unwrap();
 1344            buffers.retain(|buffer| {
 1345                this.buffers_being_formatted
 1346                    .insert(buffer.read(cx).remote_id())
 1347            });
 1348        })?;
 1349        let _cleanup = defer({
 1350            let this = lsp_store.clone();
 1351            let mut cx = cx.clone();
 1352            let buffers = &buffers;
 1353            move || {
 1354                this.update(&mut cx, |this, cx| {
 1355                    let this = this.as_local_mut().unwrap();
 1356                    for buffer in buffers {
 1357                        this.buffers_being_formatted
 1358                            .remove(&buffer.read(cx).remote_id());
 1359                    }
 1360                })
 1361                .ok();
 1362            }
 1363        });
 1364        let mut project_transaction = ProjectTransaction::default();
 1365
 1366        for buffer in &buffers {
 1367            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1368                buffer.update(cx, |buffer, cx| {
 1369                    lsp_store
 1370                        .as_local()
 1371                        .unwrap()
 1372                        .language_servers_for_buffer(buffer, cx)
 1373                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1374                        .collect::<Vec<_>>()
 1375                })
 1376            })?;
 1377            for (_, language_server) in adapters_and_servers.iter() {
 1378                let actions = Self::get_server_code_actions_from_action_kinds(
 1379                    &lsp_store,
 1380                    language_server.server_id(),
 1381                    vec![kind.clone()],
 1382                    buffer,
 1383                    cx,
 1384                )
 1385                .await?;
 1386                Self::execute_code_actions_on_server(
 1387                    &lsp_store,
 1388                    language_server,
 1389                    actions,
 1390                    push_to_history,
 1391                    &mut project_transaction,
 1392                    cx,
 1393                )
 1394                .await?;
 1395            }
 1396        }
 1397        Ok(project_transaction)
 1398    }
 1399
 1400    async fn format_locally(
 1401        lsp_store: WeakEntity<LspStore>,
 1402        mut buffers: Vec<FormattableBuffer>,
 1403        push_to_history: bool,
 1404        trigger: FormatTrigger,
 1405        logger: zlog::Logger,
 1406        cx: &mut AsyncApp,
 1407    ) -> anyhow::Result<ProjectTransaction> {
 1408        // Do not allow multiple concurrent formatting requests for the
 1409        // same buffer.
 1410        lsp_store.update(cx, |this, cx| {
 1411            let this = this.as_local_mut().unwrap();
 1412            buffers.retain(|buffer| {
 1413                this.buffers_being_formatted
 1414                    .insert(buffer.handle.read(cx).remote_id())
 1415            });
 1416        })?;
 1417
 1418        let _cleanup = defer({
 1419            let this = lsp_store.clone();
 1420            let mut cx = cx.clone();
 1421            let buffers = &buffers;
 1422            move || {
 1423                this.update(&mut cx, |this, cx| {
 1424                    let this = this.as_local_mut().unwrap();
 1425                    for buffer in buffers {
 1426                        this.buffers_being_formatted
 1427                            .remove(&buffer.handle.read(cx).remote_id());
 1428                    }
 1429                })
 1430                .ok();
 1431            }
 1432        });
 1433
 1434        let mut project_transaction = ProjectTransaction::default();
 1435
 1436        for buffer in &buffers {
 1437            zlog::debug!(
 1438                logger =>
 1439                "formatting buffer '{:?}'",
 1440                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1441            );
 1442            // Create an empty transaction to hold all of the formatting edits.
 1443            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1444                // ensure no transactions created while formatting are
 1445                // grouped with the previous transaction in the history
 1446                // based on the transaction group interval
 1447                buffer.finalize_last_transaction();
 1448                buffer
 1449                    .start_transaction()
 1450                    .context("transaction already open")?;
 1451                buffer.end_transaction(cx);
 1452                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1453                buffer.finalize_last_transaction();
 1454                anyhow::Ok(transaction_id)
 1455            })?;
 1456
 1457            let result = Self::format_buffer_locally(
 1458                lsp_store.clone(),
 1459                buffer,
 1460                formatting_transaction_id,
 1461                trigger,
 1462                logger,
 1463                cx,
 1464            )
 1465            .await;
 1466
 1467            buffer.handle.update(cx, |buffer, cx| {
 1468                let Some(formatting_transaction) =
 1469                    buffer.get_transaction(formatting_transaction_id).cloned()
 1470                else {
 1471                    zlog::warn!(logger => "no formatting transaction");
 1472                    return;
 1473                };
 1474                if formatting_transaction.edit_ids.is_empty() {
 1475                    zlog::debug!(logger => "no changes made while formatting");
 1476                    buffer.forget_transaction(formatting_transaction_id);
 1477                    return;
 1478                }
 1479                if !push_to_history {
 1480                    zlog::trace!(logger => "forgetting format transaction");
 1481                    buffer.forget_transaction(formatting_transaction.id);
 1482                }
 1483                project_transaction
 1484                    .0
 1485                    .insert(cx.entity(), formatting_transaction);
 1486            });
 1487
 1488            result?;
 1489        }
 1490
 1491        Ok(project_transaction)
 1492    }
 1493
 1494    async fn format_buffer_locally(
 1495        lsp_store: WeakEntity<LspStore>,
 1496        buffer: &FormattableBuffer,
 1497        formatting_transaction_id: clock::Lamport,
 1498        trigger: FormatTrigger,
 1499        logger: zlog::Logger,
 1500        cx: &mut AsyncApp,
 1501    ) -> Result<()> {
 1502        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1503            buffer.handle.update(cx, |buffer, cx| {
 1504                let adapters_and_servers = lsp_store
 1505                    .as_local()
 1506                    .unwrap()
 1507                    .language_servers_for_buffer(buffer, cx)
 1508                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1509                    .collect::<Vec<_>>();
 1510                let settings =
 1511                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1512                        .into_owned();
 1513                (adapters_and_servers, settings)
 1514            })
 1515        })?;
 1516
 1517        /// Apply edits to the buffer that will become part of the formatting transaction.
 1518        /// Fails if the buffer has been edited since the start of that transaction.
 1519        fn extend_formatting_transaction(
 1520            buffer: &FormattableBuffer,
 1521            formatting_transaction_id: text::TransactionId,
 1522            cx: &mut AsyncApp,
 1523            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1524        ) -> anyhow::Result<()> {
 1525            buffer.handle.update(cx, |buffer, cx| {
 1526                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1527                if last_transaction_id != Some(formatting_transaction_id) {
 1528                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1529                }
 1530                buffer.start_transaction();
 1531                operation(buffer, cx);
 1532                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1533                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1534                }
 1535                Ok(())
 1536            })
 1537        }
 1538
 1539        // handle whitespace formatting
 1540        if settings.remove_trailing_whitespace_on_save {
 1541            zlog::trace!(logger => "removing trailing whitespace");
 1542            let diff = buffer
 1543                .handle
 1544                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1545                .await;
 1546            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1547                buffer.apply_diff(diff, cx);
 1548            })?;
 1549        }
 1550
 1551        if settings.ensure_final_newline_on_save {
 1552            zlog::trace!(logger => "ensuring final newline");
 1553            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1554                buffer.ensure_final_newline(cx);
 1555            })?;
 1556        }
 1557
 1558        // Formatter for `code_actions_on_format` that runs before
 1559        // the rest of the formatters
 1560        let mut code_actions_on_format_formatters = None;
 1561        let should_run_code_actions_on_format = !matches!(
 1562            (trigger, &settings.format_on_save),
 1563            (FormatTrigger::Save, &FormatOnSave::Off)
 1564        );
 1565        if should_run_code_actions_on_format {
 1566            let have_code_actions_to_run_on_format = settings
 1567                .code_actions_on_format
 1568                .values()
 1569                .any(|enabled| *enabled);
 1570            if have_code_actions_to_run_on_format {
 1571                zlog::trace!(logger => "going to run code actions on format");
 1572                code_actions_on_format_formatters = Some(
 1573                    settings
 1574                        .code_actions_on_format
 1575                        .iter()
 1576                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1577                        .cloned()
 1578                        .map(Formatter::CodeAction)
 1579                        .collect::<Vec<_>>(),
 1580                );
 1581            }
 1582        }
 1583
 1584        let formatters = match (trigger, &settings.format_on_save) {
 1585            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1586            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1587                settings.formatter.as_ref()
 1588            }
 1589        };
 1590
 1591        let formatters = code_actions_on_format_formatters
 1592            .iter()
 1593            .flatten()
 1594            .chain(formatters);
 1595
 1596        for formatter in formatters {
 1597            let formatter = if formatter == &Formatter::Auto {
 1598                if settings.prettier.allowed {
 1599                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1600                    &Formatter::Prettier
 1601                } else {
 1602                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1603                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1604                }
 1605            } else {
 1606                formatter
 1607            };
 1608            match formatter {
 1609                Formatter::Auto => unreachable!("Auto resolved above"),
 1610                Formatter::Prettier => {
 1611                    let logger = zlog::scoped!(logger => "prettier");
 1612                    zlog::trace!(logger => "formatting");
 1613                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1614
 1615                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1616                        lsp_store.prettier_store().unwrap().downgrade()
 1617                    })?;
 1618                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1619                        .await
 1620                        .transpose()?;
 1621                    let Some(diff) = diff else {
 1622                        zlog::trace!(logger => "No changes");
 1623                        continue;
 1624                    };
 1625
 1626                    extend_formatting_transaction(
 1627                        buffer,
 1628                        formatting_transaction_id,
 1629                        cx,
 1630                        |buffer, cx| {
 1631                            buffer.apply_diff(diff, cx);
 1632                        },
 1633                    )?;
 1634                }
 1635                Formatter::External { command, arguments } => {
 1636                    let logger = zlog::scoped!(logger => "command");
 1637                    zlog::trace!(logger => "formatting");
 1638                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1639
 1640                    let diff = Self::format_via_external_command(
 1641                        buffer,
 1642                        command.as_ref(),
 1643                        arguments.as_deref(),
 1644                        cx,
 1645                    )
 1646                    .await
 1647                    .with_context(|| {
 1648                        format!("Failed to format buffer via external command: {}", command)
 1649                    })?;
 1650                    let Some(diff) = diff else {
 1651                        zlog::trace!(logger => "No changes");
 1652                        continue;
 1653                    };
 1654
 1655                    extend_formatting_transaction(
 1656                        buffer,
 1657                        formatting_transaction_id,
 1658                        cx,
 1659                        |buffer, cx| {
 1660                            buffer.apply_diff(diff, cx);
 1661                        },
 1662                    )?;
 1663                }
 1664                Formatter::LanguageServer(specifier) => {
 1665                    let logger = zlog::scoped!(logger => "language-server");
 1666                    zlog::trace!(logger => "formatting");
 1667                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1668
 1669                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1670                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1671                        continue;
 1672                    };
 1673
 1674                    let language_server = match specifier {
 1675                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1676                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1677                                if adapter.name.0.as_ref() == name {
 1678                                    Some(server.clone())
 1679                                } else {
 1680                                    None
 1681                                }
 1682                            })
 1683                        }
 1684                        settings::LanguageServerFormatterSpecifier::Current => {
 1685                            adapters_and_servers.first().map(|e| e.1.clone())
 1686                        }
 1687                    };
 1688
 1689                    let Some(language_server) = language_server else {
 1690                        log::debug!(
 1691                            "No language server found to format buffer '{:?}'. Skipping",
 1692                            buffer_path_abs.as_path().to_string_lossy()
 1693                        );
 1694                        continue;
 1695                    };
 1696
 1697                    zlog::trace!(
 1698                        logger =>
 1699                        "Formatting buffer '{:?}' using language server '{:?}'",
 1700                        buffer_path_abs.as_path().to_string_lossy(),
 1701                        language_server.name()
 1702                    );
 1703
 1704                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1705                        zlog::trace!(logger => "formatting ranges");
 1706                        Self::format_ranges_via_lsp(
 1707                            &lsp_store,
 1708                            &buffer.handle,
 1709                            ranges,
 1710                            buffer_path_abs,
 1711                            &language_server,
 1712                            &settings,
 1713                            cx,
 1714                        )
 1715                        .await
 1716                        .context("Failed to format ranges via language server")?
 1717                    } else {
 1718                        zlog::trace!(logger => "formatting full");
 1719                        Self::format_via_lsp(
 1720                            &lsp_store,
 1721                            &buffer.handle,
 1722                            buffer_path_abs,
 1723                            &language_server,
 1724                            &settings,
 1725                            cx,
 1726                        )
 1727                        .await
 1728                        .context("failed to format via language server")?
 1729                    };
 1730
 1731                    if edits.is_empty() {
 1732                        zlog::trace!(logger => "No changes");
 1733                        continue;
 1734                    }
 1735                    extend_formatting_transaction(
 1736                        buffer,
 1737                        formatting_transaction_id,
 1738                        cx,
 1739                        |buffer, cx| {
 1740                            buffer.edit(edits, None, cx);
 1741                        },
 1742                    )?;
 1743                }
 1744                Formatter::CodeAction(code_action_name) => {
 1745                    let logger = zlog::scoped!(logger => "code-actions");
 1746                    zlog::trace!(logger => "formatting");
 1747                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1748
 1749                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1750                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1751                        continue;
 1752                    };
 1753
 1754                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1755                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1756
 1757                    let mut actions_and_servers = Vec::new();
 1758
 1759                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1760                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1761                            &lsp_store,
 1762                            language_server.server_id(),
 1763                            vec![code_action_kind.clone()],
 1764                            &buffer.handle,
 1765                            cx,
 1766                        )
 1767                        .await
 1768                        .with_context(|| {
 1769                            format!(
 1770                                "Failed to resolve code action {:?} with language server {}",
 1771                                code_action_kind,
 1772                                language_server.name()
 1773                            )
 1774                        });
 1775                        let Ok(actions) = actions_result else {
 1776                            // note: it may be better to set result to the error and break formatters here
 1777                            // but for now we try to execute the actions that we can resolve and skip the rest
 1778                            zlog::error!(
 1779                                logger =>
 1780                                "Failed to resolve code action {:?} with language server {}",
 1781                                code_action_kind,
 1782                                language_server.name()
 1783                            );
 1784                            continue;
 1785                        };
 1786                        for action in actions {
 1787                            actions_and_servers.push((action, index));
 1788                        }
 1789                    }
 1790
 1791                    if actions_and_servers.is_empty() {
 1792                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1793                        continue;
 1794                    }
 1795
 1796                    'actions: for (mut action, server_index) in actions_and_servers {
 1797                        let server = &adapters_and_servers[server_index].1;
 1798
 1799                        let describe_code_action = |action: &CodeAction| {
 1800                            format!(
 1801                                "code action '{}' with title \"{}\" on server {}",
 1802                                action
 1803                                    .lsp_action
 1804                                    .action_kind()
 1805                                    .unwrap_or("unknown".into())
 1806                                    .as_str(),
 1807                                action.lsp_action.title(),
 1808                                server.name(),
 1809                            )
 1810                        };
 1811
 1812                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1813
 1814                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1815                            zlog::error!(
 1816                                logger =>
 1817                                "Failed to resolve {}. Error: {}",
 1818                                describe_code_action(&action),
 1819                                err
 1820                            );
 1821                            continue;
 1822                        }
 1823
 1824                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1825                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1826                            // but filters out and logs warnings for code actions that require unreasonably
 1827                            // difficult handling on our part, such as:
 1828                            // - applying edits that call commands
 1829                            //   which can result in arbitrary workspace edits being sent from the server that
 1830                            //   have no way of being tied back to the command that initiated them (i.e. we
 1831                            //   can't know which edits are part of the format request, or if the server is done sending
 1832                            //   actions in response to the command)
 1833                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1834                            //   as we then would need to handle such changes correctly in the local history as well
 1835                            //   as the remote history through the ProjectTransaction
 1836                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1837                            // Supporting these actions is not impossible, but not supported as of yet.
 1838                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1839                                zlog::trace!(
 1840                                    logger =>
 1841                                    "No changes for code action. Skipping {}",
 1842                                    describe_code_action(&action),
 1843                                );
 1844                                continue;
 1845                            }
 1846
 1847                            let mut operations = Vec::new();
 1848                            if let Some(document_changes) = edit.document_changes {
 1849                                match document_changes {
 1850                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1851                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1852                                    ),
 1853                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1854                                }
 1855                            } else if let Some(changes) = edit.changes {
 1856                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1857                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1858                                        text_document:
 1859                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1860                                                uri,
 1861                                                version: None,
 1862                                            },
 1863                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1864                                    })
 1865                                }));
 1866                            }
 1867
 1868                            let mut edits = Vec::with_capacity(operations.len());
 1869
 1870                            if operations.is_empty() {
 1871                                zlog::trace!(
 1872                                    logger =>
 1873                                    "No changes for code action. Skipping {}",
 1874                                    describe_code_action(&action),
 1875                                );
 1876                                continue;
 1877                            }
 1878                            for operation in operations {
 1879                                let op = match operation {
 1880                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1881                                    lsp::DocumentChangeOperation::Op(_) => {
 1882                                        zlog::warn!(
 1883                                            logger =>
 1884                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1885                                            describe_code_action(&action),
 1886                                        );
 1887                                        continue 'actions;
 1888                                    }
 1889                                };
 1890                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1891                                    zlog::warn!(
 1892                                        logger =>
 1893                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1894                                        &op.text_document.uri,
 1895                                        describe_code_action(&action),
 1896                                    );
 1897                                    continue 'actions;
 1898                                };
 1899                                if &file_path != buffer_path_abs {
 1900                                    zlog::warn!(
 1901                                        logger =>
 1902                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1903                                        file_path,
 1904                                        buffer_path_abs,
 1905                                        describe_code_action(&action),
 1906                                    );
 1907                                    continue 'actions;
 1908                                }
 1909
 1910                                let mut lsp_edits = Vec::new();
 1911                                for edit in op.edits {
 1912                                    match edit {
 1913                                        Edit::Plain(edit) => {
 1914                                            if !lsp_edits.contains(&edit) {
 1915                                                lsp_edits.push(edit);
 1916                                            }
 1917                                        }
 1918                                        Edit::Annotated(edit) => {
 1919                                            if !lsp_edits.contains(&edit.text_edit) {
 1920                                                lsp_edits.push(edit.text_edit);
 1921                                            }
 1922                                        }
 1923                                        Edit::Snippet(_) => {
 1924                                            zlog::warn!(
 1925                                                logger =>
 1926                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1927                                                describe_code_action(&action),
 1928                                            );
 1929                                            continue 'actions;
 1930                                        }
 1931                                    }
 1932                                }
 1933                                let edits_result = lsp_store
 1934                                    .update(cx, |lsp_store, cx| {
 1935                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1936                                            &buffer.handle,
 1937                                            lsp_edits,
 1938                                            server.server_id(),
 1939                                            op.text_document.version,
 1940                                            cx,
 1941                                        )
 1942                                    })?
 1943                                    .await;
 1944                                let Ok(resolved_edits) = edits_result else {
 1945                                    zlog::warn!(
 1946                                        logger =>
 1947                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1948                                        buffer_path_abs.as_path(),
 1949                                        describe_code_action(&action),
 1950                                    );
 1951                                    continue 'actions;
 1952                                };
 1953                                edits.extend(resolved_edits);
 1954                            }
 1955
 1956                            if edits.is_empty() {
 1957                                zlog::warn!(logger => "No edits resolved from LSP");
 1958                                continue;
 1959                            }
 1960
 1961                            extend_formatting_transaction(
 1962                                buffer,
 1963                                formatting_transaction_id,
 1964                                cx,
 1965                                |buffer, cx| {
 1966                                    zlog::info!(
 1967                                        "Applying edits {edits:?}. Content: {:?}",
 1968                                        buffer.text()
 1969                                    );
 1970                                    buffer.edit(edits, None, cx);
 1971                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1972                                },
 1973                            )?;
 1974                        }
 1975
 1976                        if let Some(command) = action.lsp_action.command() {
 1977                            zlog::warn!(
 1978                                logger =>
 1979                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1980                                &command.command,
 1981                            );
 1982
 1983                            // bail early if command is invalid
 1984                            let server_capabilities = server.capabilities();
 1985                            let available_commands = server_capabilities
 1986                                .execute_command_provider
 1987                                .as_ref()
 1988                                .map(|options| options.commands.as_slice())
 1989                                .unwrap_or_default();
 1990                            if !available_commands.contains(&command.command) {
 1991                                zlog::warn!(
 1992                                    logger =>
 1993                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1994                                    command.command,
 1995                                    server.name(),
 1996                                );
 1997                                continue;
 1998                            }
 1999
 2000                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 2001                            extend_formatting_transaction(
 2002                                buffer,
 2003                                formatting_transaction_id,
 2004                                cx,
 2005                                |_, _| {},
 2006                            )?;
 2007                            zlog::info!(logger => "Executing command {}", &command.command);
 2008
 2009                            lsp_store.update(cx, |this, _| {
 2010                                this.as_local_mut()
 2011                                    .unwrap()
 2012                                    .last_workspace_edits_by_language_server
 2013                                    .remove(&server.server_id());
 2014                            })?;
 2015
 2016                            let execute_command_result = server
 2017                                .request::<lsp::request::ExecuteCommand>(
 2018                                    lsp::ExecuteCommandParams {
 2019                                        command: command.command.clone(),
 2020                                        arguments: command.arguments.clone().unwrap_or_default(),
 2021                                        ..Default::default()
 2022                                    },
 2023                                )
 2024                                .await
 2025                                .into_response();
 2026
 2027                            if execute_command_result.is_err() {
 2028                                zlog::error!(
 2029                                    logger =>
 2030                                    "Failed to execute command '{}' as part of {}",
 2031                                    &command.command,
 2032                                    describe_code_action(&action),
 2033                                );
 2034                                continue 'actions;
 2035                            }
 2036
 2037                            let mut project_transaction_command =
 2038                                lsp_store.update(cx, |this, _| {
 2039                                    this.as_local_mut()
 2040                                        .unwrap()
 2041                                        .last_workspace_edits_by_language_server
 2042                                        .remove(&server.server_id())
 2043                                        .unwrap_or_default()
 2044                                })?;
 2045
 2046                            if let Some(transaction) =
 2047                                project_transaction_command.0.remove(&buffer.handle)
 2048                            {
 2049                                zlog::trace!(
 2050                                    logger =>
 2051                                    "Successfully captured {} edits that resulted from command {}",
 2052                                    transaction.edit_ids.len(),
 2053                                    &command.command,
 2054                                );
 2055                                let transaction_id_project_transaction = transaction.id;
 2056                                buffer.handle.update(cx, |buffer, _| {
 2057                                    // it may have been removed from history if push_to_history was
 2058                                    // false in deserialize_workspace_edit. If so push it so we
 2059                                    // can merge it with the format transaction
 2060                                    // and pop the combined transaction off the history stack
 2061                                    // later if push_to_history is false
 2062                                    if buffer.get_transaction(transaction.id).is_none() {
 2063                                        buffer.push_transaction(transaction, Instant::now());
 2064                                    }
 2065                                    buffer.merge_transactions(
 2066                                        transaction_id_project_transaction,
 2067                                        formatting_transaction_id,
 2068                                    );
 2069                                });
 2070                            }
 2071
 2072                            if !project_transaction_command.0.is_empty() {
 2073                                let mut extra_buffers = String::new();
 2074                                for buffer in project_transaction_command.0.keys() {
 2075                                    buffer.read_with(cx, |b, cx| {
 2076                                        if let Some(path) = b.project_path(cx) {
 2077                                            if !extra_buffers.is_empty() {
 2078                                                extra_buffers.push_str(", ");
 2079                                            }
 2080                                            extra_buffers.push_str(path.path.as_unix_str());
 2081                                        }
 2082                                    });
 2083                                }
 2084                                zlog::warn!(
 2085                                    logger =>
 2086                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2087                                    &command.command,
 2088                                    extra_buffers,
 2089                                );
 2090                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2091                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2092                                // add it so it's included, and merge it into the format transaction when its created later
 2093                            }
 2094                        }
 2095                    }
 2096                }
 2097            }
 2098        }
 2099
 2100        Ok(())
 2101    }
 2102
 2103    pub async fn format_ranges_via_lsp(
 2104        this: &WeakEntity<LspStore>,
 2105        buffer_handle: &Entity<Buffer>,
 2106        ranges: &[Range<Anchor>],
 2107        abs_path: &Path,
 2108        language_server: &Arc<LanguageServer>,
 2109        settings: &LanguageSettings,
 2110        cx: &mut AsyncApp,
 2111    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2112        let capabilities = &language_server.capabilities();
 2113        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2114        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2115            anyhow::bail!(
 2116                "{} language server does not support range formatting",
 2117                language_server.name()
 2118            );
 2119        }
 2120
 2121        let uri = file_path_to_lsp_url(abs_path)?;
 2122        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2123
 2124        let lsp_edits = {
 2125            let mut lsp_ranges = Vec::new();
 2126            this.update(cx, |_this, cx| {
 2127                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2128                // not have been sent to the language server. This seems like a fairly systemic
 2129                // issue, though, the resolution probably is not specific to formatting.
 2130                //
 2131                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2132                // LSP.
 2133                let snapshot = buffer_handle.read(cx).snapshot();
 2134                for range in ranges {
 2135                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2136                }
 2137                anyhow::Ok(())
 2138            })??;
 2139
 2140            let mut edits = None;
 2141            for range in lsp_ranges {
 2142                if let Some(mut edit) = language_server
 2143                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2144                        text_document: text_document.clone(),
 2145                        range,
 2146                        options: lsp_command::lsp_formatting_options(settings),
 2147                        work_done_progress_params: Default::default(),
 2148                    })
 2149                    .await
 2150                    .into_response()?
 2151                {
 2152                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2153                }
 2154            }
 2155            edits
 2156        };
 2157
 2158        if let Some(lsp_edits) = lsp_edits {
 2159            this.update(cx, |this, cx| {
 2160                this.as_local_mut().unwrap().edits_from_lsp(
 2161                    buffer_handle,
 2162                    lsp_edits,
 2163                    language_server.server_id(),
 2164                    None,
 2165                    cx,
 2166                )
 2167            })?
 2168            .await
 2169        } else {
 2170            Ok(Vec::with_capacity(0))
 2171        }
 2172    }
 2173
 2174    async fn format_via_lsp(
 2175        this: &WeakEntity<LspStore>,
 2176        buffer: &Entity<Buffer>,
 2177        abs_path: &Path,
 2178        language_server: &Arc<LanguageServer>,
 2179        settings: &LanguageSettings,
 2180        cx: &mut AsyncApp,
 2181    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2182        let logger = zlog::scoped!("lsp_format");
 2183        zlog::debug!(logger => "Formatting via LSP");
 2184
 2185        let uri = file_path_to_lsp_url(abs_path)?;
 2186        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2187        let capabilities = &language_server.capabilities();
 2188
 2189        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2190        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2191
 2192        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2193            let _timer = zlog::time!(logger => "format-full");
 2194            language_server
 2195                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2196                    text_document,
 2197                    options: lsp_command::lsp_formatting_options(settings),
 2198                    work_done_progress_params: Default::default(),
 2199                })
 2200                .await
 2201                .into_response()?
 2202        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2203            let _timer = zlog::time!(logger => "format-range");
 2204            let buffer_start = lsp::Position::new(0, 0);
 2205            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2206            language_server
 2207                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2208                    text_document: text_document.clone(),
 2209                    range: lsp::Range::new(buffer_start, buffer_end),
 2210                    options: lsp_command::lsp_formatting_options(settings),
 2211                    work_done_progress_params: Default::default(),
 2212                })
 2213                .await
 2214                .into_response()?
 2215        } else {
 2216            None
 2217        };
 2218
 2219        if let Some(lsp_edits) = lsp_edits {
 2220            this.update(cx, |this, cx| {
 2221                this.as_local_mut().unwrap().edits_from_lsp(
 2222                    buffer,
 2223                    lsp_edits,
 2224                    language_server.server_id(),
 2225                    None,
 2226                    cx,
 2227                )
 2228            })?
 2229            .await
 2230        } else {
 2231            Ok(Vec::with_capacity(0))
 2232        }
 2233    }
 2234
 2235    async fn format_via_external_command(
 2236        buffer: &FormattableBuffer,
 2237        command: &str,
 2238        arguments: Option<&[String]>,
 2239        cx: &mut AsyncApp,
 2240    ) -> Result<Option<Diff>> {
 2241        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2242            let file = File::from_dyn(buffer.file())?;
 2243            let worktree = file.worktree.read(cx);
 2244            let mut worktree_path = worktree.abs_path().to_path_buf();
 2245            if worktree.root_entry()?.is_file() {
 2246                worktree_path.pop();
 2247            }
 2248            Some(worktree_path)
 2249        });
 2250
 2251        let mut child = util::command::new_smol_command(command);
 2252
 2253        if let Some(buffer_env) = buffer.env.as_ref() {
 2254            child.envs(buffer_env);
 2255        }
 2256
 2257        if let Some(working_dir_path) = working_dir_path {
 2258            child.current_dir(working_dir_path);
 2259        }
 2260
 2261        if let Some(arguments) = arguments {
 2262            child.args(arguments.iter().map(|arg| {
 2263                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2264                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2265                } else {
 2266                    arg.replace("{buffer_path}", "Untitled")
 2267                }
 2268            }));
 2269        }
 2270
 2271        let mut child = child
 2272            .stdin(smol::process::Stdio::piped())
 2273            .stdout(smol::process::Stdio::piped())
 2274            .stderr(smol::process::Stdio::piped())
 2275            .spawn()?;
 2276
 2277        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2278        let text = buffer
 2279            .handle
 2280            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2281        for chunk in text.chunks() {
 2282            stdin.write_all(chunk.as_bytes()).await?;
 2283        }
 2284        stdin.flush().await?;
 2285
 2286        let output = child.output().await?;
 2287        anyhow::ensure!(
 2288            output.status.success(),
 2289            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2290            output.status.code(),
 2291            String::from_utf8_lossy(&output.stdout),
 2292            String::from_utf8_lossy(&output.stderr),
 2293        );
 2294
 2295        let stdout = String::from_utf8(output.stdout)?;
 2296        Ok(Some(
 2297            buffer
 2298                .handle
 2299                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2300                .await,
 2301        ))
 2302    }
 2303
 2304    async fn try_resolve_code_action(
 2305        lang_server: &LanguageServer,
 2306        action: &mut CodeAction,
 2307    ) -> anyhow::Result<()> {
 2308        match &mut action.lsp_action {
 2309            LspAction::Action(lsp_action) => {
 2310                if !action.resolved
 2311                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2312                    && lsp_action.data.is_some()
 2313                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2314                {
 2315                    **lsp_action = lang_server
 2316                        .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2317                        .await
 2318                        .into_response()?;
 2319                }
 2320            }
 2321            LspAction::CodeLens(lens) => {
 2322                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2323                    *lens = lang_server
 2324                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2325                        .await
 2326                        .into_response()?;
 2327                }
 2328            }
 2329            LspAction::Command(_) => {}
 2330        }
 2331
 2332        action.resolved = true;
 2333        anyhow::Ok(())
 2334    }
 2335
 2336    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2337        let buffer = buffer_handle.read(cx);
 2338
 2339        let file = buffer.file().cloned();
 2340
 2341        let Some(file) = File::from_dyn(file.as_ref()) else {
 2342            return;
 2343        };
 2344        if !file.is_local() {
 2345            return;
 2346        }
 2347        let path = ProjectPath::from_file(file, cx);
 2348        let worktree_id = file.worktree_id(cx);
 2349        let language = buffer.language().cloned();
 2350
 2351        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2352            for (server_id, diagnostics) in
 2353                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2354            {
 2355                self.update_buffer_diagnostics(
 2356                    buffer_handle,
 2357                    server_id,
 2358                    None,
 2359                    None,
 2360                    None,
 2361                    Vec::new(),
 2362                    diagnostics,
 2363                    cx,
 2364                )
 2365                .log_err();
 2366            }
 2367        }
 2368        let Some(language) = language else {
 2369            return;
 2370        };
 2371        let Some(snapshot) = self
 2372            .worktree_store
 2373            .read(cx)
 2374            .worktree_for_id(worktree_id, cx)
 2375            .map(|worktree| worktree.read(cx).snapshot())
 2376        else {
 2377            return;
 2378        };
 2379        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2380
 2381        for server_id in
 2382            self.lsp_tree
 2383                .get(path, language.name(), language.manifest(), &delegate, cx)
 2384        {
 2385            let server = self
 2386                .language_servers
 2387                .get(&server_id)
 2388                .and_then(|server_state| {
 2389                    if let LanguageServerState::Running { server, .. } = server_state {
 2390                        Some(server.clone())
 2391                    } else {
 2392                        None
 2393                    }
 2394                });
 2395            let server = match server {
 2396                Some(server) => server,
 2397                None => continue,
 2398            };
 2399
 2400            buffer_handle.update(cx, |buffer, cx| {
 2401                buffer.set_completion_triggers(
 2402                    server.server_id(),
 2403                    server
 2404                        .capabilities()
 2405                        .completion_provider
 2406                        .as_ref()
 2407                        .and_then(|provider| {
 2408                            provider
 2409                                .trigger_characters
 2410                                .as_ref()
 2411                                .map(|characters| characters.iter().cloned().collect())
 2412                        })
 2413                        .unwrap_or_default(),
 2414                    cx,
 2415                );
 2416            });
 2417        }
 2418    }
 2419
 2420    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2421        buffer.update(cx, |buffer, cx| {
 2422            let Some(language) = buffer.language() else {
 2423                return;
 2424            };
 2425            let path = ProjectPath {
 2426                worktree_id: old_file.worktree_id(cx),
 2427                path: old_file.path.clone(),
 2428            };
 2429            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2430                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2431                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2432            }
 2433        });
 2434    }
 2435
 2436    fn update_buffer_diagnostics(
 2437        &mut self,
 2438        buffer: &Entity<Buffer>,
 2439        server_id: LanguageServerId,
 2440        registration_id: Option<Option<SharedString>>,
 2441        result_id: Option<SharedString>,
 2442        version: Option<i32>,
 2443        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2444        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2445        cx: &mut Context<LspStore>,
 2446    ) -> Result<()> {
 2447        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2448            Ordering::Equal
 2449                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2450                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2451                .then_with(|| a.severity.cmp(&b.severity))
 2452                .then_with(|| a.message.cmp(&b.message))
 2453        }
 2454
 2455        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2456        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2457        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2458
 2459        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2460            Ordering::Equal
 2461                .then_with(|| a.range.start.cmp(&b.range.start))
 2462                .then_with(|| b.range.end.cmp(&a.range.end))
 2463                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2464        });
 2465
 2466        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2467
 2468        let edits_since_save = std::cell::LazyCell::new(|| {
 2469            let saved_version = buffer.read(cx).saved_version();
 2470            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2471        });
 2472
 2473        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2474
 2475        for (new_diagnostic, entry) in diagnostics {
 2476            let start;
 2477            let end;
 2478            if entry.diagnostic.is_disk_based {
 2479                if !new_diagnostic {
 2480                    continue;
 2481                }
 2482                // Some diagnostics are based on files on disk instead of buffers'
 2483                // current contents. Adjust these diagnostics' ranges to reflect
 2484                // any unsaved edits.
 2485                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2486                // and were properly adjusted on reuse.
 2487                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2488                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2489            } else {
 2490                start = entry.range.start;
 2491                end = entry.range.end;
 2492            }
 2493
 2494            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2495                ..snapshot.clip_point_utf16(end, Bias::Right);
 2496
 2497            // Expand empty ranges by one codepoint
 2498            if range.start == range.end {
 2499                // This will be go to the next boundary when being clipped
 2500                range.end.column += 1;
 2501                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2502                if range.start == range.end && range.end.column > 0 {
 2503                    range.start.column -= 1;
 2504                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2505                }
 2506            }
 2507
 2508            sanitized_diagnostics.push(DiagnosticEntry {
 2509                range,
 2510                diagnostic: entry.diagnostic,
 2511            });
 2512        }
 2513        drop(edits_since_save);
 2514
 2515        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2516        buffer.update(cx, |buffer, cx| {
 2517            if let Some(registration_id) = registration_id {
 2518                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2519                    self.buffer_pull_diagnostics_result_ids
 2520                        .entry(server_id)
 2521                        .or_default()
 2522                        .entry(registration_id)
 2523                        .or_default()
 2524                        .insert(abs_path, result_id);
 2525                }
 2526            }
 2527
 2528            buffer.update_diagnostics(server_id, set, cx)
 2529        });
 2530
 2531        Ok(())
 2532    }
 2533
 2534    fn register_language_server_for_invisible_worktree(
 2535        &mut self,
 2536        worktree: &Entity<Worktree>,
 2537        language_server_id: LanguageServerId,
 2538        cx: &mut App,
 2539    ) {
 2540        let worktree = worktree.read(cx);
 2541        let worktree_id = worktree.id();
 2542        debug_assert!(!worktree.is_visible());
 2543        let Some(mut origin_seed) = self
 2544            .language_server_ids
 2545            .iter()
 2546            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2547        else {
 2548            return;
 2549        };
 2550        origin_seed.worktree_id = worktree_id;
 2551        self.language_server_ids
 2552            .entry(origin_seed)
 2553            .or_insert_with(|| UnifiedLanguageServer {
 2554                id: language_server_id,
 2555                project_roots: Default::default(),
 2556            });
 2557    }
 2558
 2559    fn register_buffer_with_language_servers(
 2560        &mut self,
 2561        buffer_handle: &Entity<Buffer>,
 2562        only_register_servers: HashSet<LanguageServerSelector>,
 2563        cx: &mut Context<LspStore>,
 2564    ) {
 2565        let buffer = buffer_handle.read(cx);
 2566        let buffer_id = buffer.remote_id();
 2567
 2568        let Some(file) = File::from_dyn(buffer.file()) else {
 2569            return;
 2570        };
 2571        if !file.is_local() {
 2572            return;
 2573        }
 2574
 2575        let abs_path = file.abs_path(cx);
 2576        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2577            return;
 2578        };
 2579        let initial_snapshot = buffer.text_snapshot();
 2580        let worktree_id = file.worktree_id(cx);
 2581
 2582        let Some(language) = buffer.language().cloned() else {
 2583            return;
 2584        };
 2585        let path: Arc<RelPath> = file
 2586            .path()
 2587            .parent()
 2588            .map(Arc::from)
 2589            .unwrap_or_else(|| file.path().clone());
 2590        let Some(worktree) = self
 2591            .worktree_store
 2592            .read(cx)
 2593            .worktree_for_id(worktree_id, cx)
 2594        else {
 2595            return;
 2596        };
 2597        let language_name = language.name();
 2598        let (reused, delegate, servers) = self
 2599            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2600            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2601            .unwrap_or_else(|| {
 2602                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2603                let delegate: Arc<dyn ManifestDelegate> =
 2604                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2605
 2606                let servers = self
 2607                    .lsp_tree
 2608                    .walk(
 2609                        ProjectPath { worktree_id, path },
 2610                        language.name(),
 2611                        language.manifest(),
 2612                        &delegate,
 2613                        cx,
 2614                    )
 2615                    .collect::<Vec<_>>();
 2616                (false, lsp_delegate, servers)
 2617            });
 2618        let servers_and_adapters = servers
 2619            .into_iter()
 2620            .filter_map(|server_node| {
 2621                if reused && server_node.server_id().is_none() {
 2622                    return None;
 2623                }
 2624                if !only_register_servers.is_empty() {
 2625                    if let Some(server_id) = server_node.server_id()
 2626                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2627                    {
 2628                        return None;
 2629                    }
 2630                    if let Some(name) = server_node.name()
 2631                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2632                    {
 2633                        return None;
 2634                    }
 2635                }
 2636
 2637                let server_id = server_node.server_id_or_init(|disposition| {
 2638                    let path = &disposition.path;
 2639
 2640                    {
 2641                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2642
 2643                        let server_id = self.get_or_insert_language_server(
 2644                            &worktree,
 2645                            delegate.clone(),
 2646                            disposition,
 2647                            &language_name,
 2648                            cx,
 2649                        );
 2650
 2651                        if let Some(state) = self.language_servers.get(&server_id)
 2652                            && let Ok(uri) = uri
 2653                        {
 2654                            state.add_workspace_folder(uri);
 2655                        };
 2656                        server_id
 2657                    }
 2658                })?;
 2659                let server_state = self.language_servers.get(&server_id)?;
 2660                if let LanguageServerState::Running {
 2661                    server, adapter, ..
 2662                } = server_state
 2663                {
 2664                    Some((server.clone(), adapter.clone()))
 2665                } else {
 2666                    None
 2667                }
 2668            })
 2669            .collect::<Vec<_>>();
 2670        for (server, adapter) in servers_and_adapters {
 2671            buffer_handle.update(cx, |buffer, cx| {
 2672                buffer.set_completion_triggers(
 2673                    server.server_id(),
 2674                    server
 2675                        .capabilities()
 2676                        .completion_provider
 2677                        .as_ref()
 2678                        .and_then(|provider| {
 2679                            provider
 2680                                .trigger_characters
 2681                                .as_ref()
 2682                                .map(|characters| characters.iter().cloned().collect())
 2683                        })
 2684                        .unwrap_or_default(),
 2685                    cx,
 2686                );
 2687            });
 2688
 2689            let snapshot = LspBufferSnapshot {
 2690                version: 0,
 2691                snapshot: initial_snapshot.clone(),
 2692            };
 2693
 2694            let mut registered = false;
 2695            self.buffer_snapshots
 2696                .entry(buffer_id)
 2697                .or_default()
 2698                .entry(server.server_id())
 2699                .or_insert_with(|| {
 2700                    registered = true;
 2701                    server.register_buffer(
 2702                        uri.clone(),
 2703                        adapter.language_id(&language.name()),
 2704                        0,
 2705                        initial_snapshot.text(),
 2706                    );
 2707
 2708                    vec![snapshot]
 2709                });
 2710
 2711            self.buffers_opened_in_servers
 2712                .entry(buffer_id)
 2713                .or_default()
 2714                .insert(server.server_id());
 2715            if registered {
 2716                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2717                    language_server_id: server.server_id(),
 2718                    name: None,
 2719                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2720                        proto::RegisteredForBuffer {
 2721                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2722                            buffer_id: buffer_id.to_proto(),
 2723                        },
 2724                    ),
 2725                });
 2726            }
 2727        }
 2728    }
 2729
 2730    fn reuse_existing_language_server<'lang_name>(
 2731        &self,
 2732        server_tree: &LanguageServerTree,
 2733        worktree: &Entity<Worktree>,
 2734        language_name: &'lang_name LanguageName,
 2735        cx: &mut App,
 2736    ) -> Option<(
 2737        Arc<LocalLspAdapterDelegate>,
 2738        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2739    )> {
 2740        if worktree.read(cx).is_visible() {
 2741            return None;
 2742        }
 2743
 2744        let worktree_store = self.worktree_store.read(cx);
 2745        let servers = server_tree
 2746            .instances
 2747            .iter()
 2748            .filter(|(worktree_id, _)| {
 2749                worktree_store
 2750                    .worktree_for_id(**worktree_id, cx)
 2751                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2752            })
 2753            .flat_map(|(worktree_id, servers)| {
 2754                servers
 2755                    .roots
 2756                    .iter()
 2757                    .flat_map(|(_, language_servers)| language_servers)
 2758                    .map(move |(_, (server_node, server_languages))| {
 2759                        (worktree_id, server_node, server_languages)
 2760                    })
 2761                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2762                    .map(|(worktree_id, server_node, _)| {
 2763                        (
 2764                            *worktree_id,
 2765                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2766                        )
 2767                    })
 2768            })
 2769            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2770                acc.entry(worktree_id)
 2771                    .or_insert_with(Vec::new)
 2772                    .push(server_node);
 2773                acc
 2774            })
 2775            .into_values()
 2776            .max_by_key(|servers| servers.len())?;
 2777
 2778        let worktree_id = worktree.read(cx).id();
 2779        let apply = move |tree: &mut LanguageServerTree| {
 2780            for server_node in &servers {
 2781                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2782            }
 2783            servers
 2784        };
 2785
 2786        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2787        Some((delegate, apply))
 2788    }
 2789
 2790    pub(crate) fn unregister_old_buffer_from_language_servers(
 2791        &mut self,
 2792        buffer: &Entity<Buffer>,
 2793        old_file: &File,
 2794        cx: &mut App,
 2795    ) {
 2796        let old_path = match old_file.as_local() {
 2797            Some(local) => local.abs_path(cx),
 2798            None => return,
 2799        };
 2800
 2801        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2802            debug_panic!("{old_path:?} is not parseable as an URI");
 2803            return;
 2804        };
 2805        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2806    }
 2807
 2808    pub(crate) fn unregister_buffer_from_language_servers(
 2809        &mut self,
 2810        buffer: &Entity<Buffer>,
 2811        file_url: &lsp::Uri,
 2812        cx: &mut App,
 2813    ) {
 2814        buffer.update(cx, |buffer, cx| {
 2815            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2816
 2817            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2818                if snapshots
 2819                    .as_mut()
 2820                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2821                {
 2822                    language_server.unregister_buffer(file_url.clone());
 2823                }
 2824            }
 2825        });
 2826    }
 2827
 2828    fn buffer_snapshot_for_lsp_version(
 2829        &mut self,
 2830        buffer: &Entity<Buffer>,
 2831        server_id: LanguageServerId,
 2832        version: Option<i32>,
 2833        cx: &App,
 2834    ) -> Result<TextBufferSnapshot> {
 2835        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2836
 2837        if let Some(version) = version {
 2838            let buffer_id = buffer.read(cx).remote_id();
 2839            let snapshots = if let Some(snapshots) = self
 2840                .buffer_snapshots
 2841                .get_mut(&buffer_id)
 2842                .and_then(|m| m.get_mut(&server_id))
 2843            {
 2844                snapshots
 2845            } else if version == 0 {
 2846                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2847                // We detect this case and treat it as if the version was `None`.
 2848                return Ok(buffer.read(cx).text_snapshot());
 2849            } else {
 2850                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2851            };
 2852
 2853            let found_snapshot = snapshots
 2854                    .binary_search_by_key(&version, |e| e.version)
 2855                    .map(|ix| snapshots[ix].snapshot.clone())
 2856                    .map_err(|_| {
 2857                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2858                    })?;
 2859
 2860            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2861            Ok(found_snapshot)
 2862        } else {
 2863            Ok((buffer.read(cx)).text_snapshot())
 2864        }
 2865    }
 2866
 2867    async fn get_server_code_actions_from_action_kinds(
 2868        lsp_store: &WeakEntity<LspStore>,
 2869        language_server_id: LanguageServerId,
 2870        code_action_kinds: Vec<lsp::CodeActionKind>,
 2871        buffer: &Entity<Buffer>,
 2872        cx: &mut AsyncApp,
 2873    ) -> Result<Vec<CodeAction>> {
 2874        let actions = lsp_store
 2875            .update(cx, move |this, cx| {
 2876                let request = GetCodeActions {
 2877                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 2878                    kinds: Some(code_action_kinds),
 2879                };
 2880                let server = LanguageServerToQuery::Other(language_server_id);
 2881                this.request_lsp(buffer.clone(), server, request, cx)
 2882            })?
 2883            .await?;
 2884        Ok(actions)
 2885    }
 2886
 2887    pub async fn execute_code_actions_on_server(
 2888        lsp_store: &WeakEntity<LspStore>,
 2889        language_server: &Arc<LanguageServer>,
 2890
 2891        actions: Vec<CodeAction>,
 2892        push_to_history: bool,
 2893        project_transaction: &mut ProjectTransaction,
 2894        cx: &mut AsyncApp,
 2895    ) -> anyhow::Result<()> {
 2896        for mut action in actions {
 2897            Self::try_resolve_code_action(language_server, &mut action)
 2898                .await
 2899                .context("resolving a formatting code action")?;
 2900
 2901            if let Some(edit) = action.lsp_action.edit() {
 2902                if edit.changes.is_none() && edit.document_changes.is_none() {
 2903                    continue;
 2904                }
 2905
 2906                let new = Self::deserialize_workspace_edit(
 2907                    lsp_store.upgrade().context("project dropped")?,
 2908                    edit.clone(),
 2909                    push_to_history,
 2910                    language_server.clone(),
 2911                    cx,
 2912                )
 2913                .await?;
 2914                project_transaction.0.extend(new.0);
 2915            }
 2916
 2917            if let Some(command) = action.lsp_action.command() {
 2918                let server_capabilities = language_server.capabilities();
 2919                let available_commands = server_capabilities
 2920                    .execute_command_provider
 2921                    .as_ref()
 2922                    .map(|options| options.commands.as_slice())
 2923                    .unwrap_or_default();
 2924                if available_commands.contains(&command.command) {
 2925                    lsp_store.update(cx, |lsp_store, _| {
 2926                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2927                            mode.last_workspace_edits_by_language_server
 2928                                .remove(&language_server.server_id());
 2929                        }
 2930                    })?;
 2931
 2932                    language_server
 2933                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2934                            command: command.command.clone(),
 2935                            arguments: command.arguments.clone().unwrap_or_default(),
 2936                            ..Default::default()
 2937                        })
 2938                        .await
 2939                        .into_response()
 2940                        .context("execute command")?;
 2941
 2942                    lsp_store.update(cx, |this, _| {
 2943                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2944                            project_transaction.0.extend(
 2945                                mode.last_workspace_edits_by_language_server
 2946                                    .remove(&language_server.server_id())
 2947                                    .unwrap_or_default()
 2948                                    .0,
 2949                            )
 2950                        }
 2951                    })?;
 2952                } else {
 2953                    log::warn!(
 2954                        "Cannot execute a command {} not listed in the language server capabilities",
 2955                        command.command
 2956                    )
 2957                }
 2958            }
 2959        }
 2960        Ok(())
 2961    }
 2962
 2963    pub async fn deserialize_text_edits(
 2964        this: Entity<LspStore>,
 2965        buffer_to_edit: Entity<Buffer>,
 2966        edits: Vec<lsp::TextEdit>,
 2967        push_to_history: bool,
 2968        _: Arc<CachedLspAdapter>,
 2969        language_server: Arc<LanguageServer>,
 2970        cx: &mut AsyncApp,
 2971    ) -> Result<Option<Transaction>> {
 2972        let edits = this
 2973            .update(cx, |this, cx| {
 2974                this.as_local_mut().unwrap().edits_from_lsp(
 2975                    &buffer_to_edit,
 2976                    edits,
 2977                    language_server.server_id(),
 2978                    None,
 2979                    cx,
 2980                )
 2981            })
 2982            .await?;
 2983
 2984        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2985            buffer.finalize_last_transaction();
 2986            buffer.start_transaction();
 2987            for (range, text) in edits {
 2988                buffer.edit([(range, text)], None, cx);
 2989            }
 2990
 2991            if buffer.end_transaction(cx).is_some() {
 2992                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2993                if !push_to_history {
 2994                    buffer.forget_transaction(transaction.id);
 2995                }
 2996                Some(transaction)
 2997            } else {
 2998                None
 2999            }
 3000        });
 3001
 3002        Ok(transaction)
 3003    }
 3004
 3005    #[allow(clippy::type_complexity)]
 3006    pub(crate) fn edits_from_lsp(
 3007        &mut self,
 3008        buffer: &Entity<Buffer>,
 3009        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3010        server_id: LanguageServerId,
 3011        version: Option<i32>,
 3012        cx: &mut Context<LspStore>,
 3013    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3014        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3015        cx.background_spawn(async move {
 3016            let snapshot = snapshot?;
 3017            let mut lsp_edits = lsp_edits
 3018                .into_iter()
 3019                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3020                .collect::<Vec<_>>();
 3021
 3022            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 3023
 3024            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3025            let mut edits = Vec::new();
 3026            while let Some((range, mut new_text)) = lsp_edits.next() {
 3027                // Clip invalid ranges provided by the language server.
 3028                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3029                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3030
 3031                // Combine any LSP edits that are adjacent.
 3032                //
 3033                // Also, combine LSP edits that are separated from each other by only
 3034                // a newline. This is important because for some code actions,
 3035                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3036                // are separated by unchanged newline characters.
 3037                //
 3038                // In order for the diffing logic below to work properly, any edits that
 3039                // cancel each other out must be combined into one.
 3040                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3041                    if next_range.start.0 > range.end {
 3042                        if next_range.start.0.row > range.end.row + 1
 3043                            || next_range.start.0.column > 0
 3044                            || snapshot.clip_point_utf16(
 3045                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3046                                Bias::Left,
 3047                            ) > range.end
 3048                        {
 3049                            break;
 3050                        }
 3051                        new_text.push('\n');
 3052                    }
 3053                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3054                    new_text.push_str(next_text);
 3055                    lsp_edits.next();
 3056                }
 3057
 3058                // For multiline edits, perform a diff of the old and new text so that
 3059                // we can identify the changes more precisely, preserving the locations
 3060                // of any anchors positioned in the unchanged regions.
 3061                if range.end.row > range.start.row {
 3062                    let offset = range.start.to_offset(&snapshot);
 3063                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3064                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3065                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3066                        (
 3067                            snapshot.anchor_after(offset + range.start)
 3068                                ..snapshot.anchor_before(offset + range.end),
 3069                            replacement,
 3070                        )
 3071                    }));
 3072                } else if range.end == range.start {
 3073                    let anchor = snapshot.anchor_after(range.start);
 3074                    edits.push((anchor..anchor, new_text.into()));
 3075                } else {
 3076                    let edit_start = snapshot.anchor_after(range.start);
 3077                    let edit_end = snapshot.anchor_before(range.end);
 3078                    edits.push((edit_start..edit_end, new_text.into()));
 3079                }
 3080            }
 3081
 3082            Ok(edits)
 3083        })
 3084    }
 3085
 3086    pub(crate) async fn deserialize_workspace_edit(
 3087        this: Entity<LspStore>,
 3088        edit: lsp::WorkspaceEdit,
 3089        push_to_history: bool,
 3090        language_server: Arc<LanguageServer>,
 3091        cx: &mut AsyncApp,
 3092    ) -> Result<ProjectTransaction> {
 3093        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3094
 3095        let mut operations = Vec::new();
 3096        if let Some(document_changes) = edit.document_changes {
 3097            match document_changes {
 3098                lsp::DocumentChanges::Edits(edits) => {
 3099                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3100                }
 3101                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3102            }
 3103        } else if let Some(changes) = edit.changes {
 3104            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3105                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3106                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3107                        uri,
 3108                        version: None,
 3109                    },
 3110                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3111                })
 3112            }));
 3113        }
 3114
 3115        let mut project_transaction = ProjectTransaction::default();
 3116        for operation in operations {
 3117            match operation {
 3118                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3119                    let abs_path = op
 3120                        .uri
 3121                        .to_file_path()
 3122                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3123
 3124                    if let Some(parent_path) = abs_path.parent() {
 3125                        fs.create_dir(parent_path).await?;
 3126                    }
 3127                    if abs_path.ends_with("/") {
 3128                        fs.create_dir(&abs_path).await?;
 3129                    } else {
 3130                        fs.create_file(
 3131                            &abs_path,
 3132                            op.options
 3133                                .map(|options| fs::CreateOptions {
 3134                                    overwrite: options.overwrite.unwrap_or(false),
 3135                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3136                                })
 3137                                .unwrap_or_default(),
 3138                        )
 3139                        .await?;
 3140                    }
 3141                }
 3142
 3143                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3144                    let source_abs_path = op
 3145                        .old_uri
 3146                        .to_file_path()
 3147                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3148                    let target_abs_path = op
 3149                        .new_uri
 3150                        .to_file_path()
 3151                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3152
 3153                    let options = fs::RenameOptions {
 3154                        overwrite: op
 3155                            .options
 3156                            .as_ref()
 3157                            .and_then(|options| options.overwrite)
 3158                            .unwrap_or(false),
 3159                        ignore_if_exists: op
 3160                            .options
 3161                            .as_ref()
 3162                            .and_then(|options| options.ignore_if_exists)
 3163                            .unwrap_or(false),
 3164                        create_parents: true,
 3165                    };
 3166
 3167                    fs.rename(&source_abs_path, &target_abs_path, options)
 3168                        .await?;
 3169                }
 3170
 3171                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3172                    let abs_path = op
 3173                        .uri
 3174                        .to_file_path()
 3175                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3176                    let options = op
 3177                        .options
 3178                        .map(|options| fs::RemoveOptions {
 3179                            recursive: options.recursive.unwrap_or(false),
 3180                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3181                        })
 3182                        .unwrap_or_default();
 3183                    if abs_path.ends_with("/") {
 3184                        fs.remove_dir(&abs_path, options).await?;
 3185                    } else {
 3186                        fs.remove_file(&abs_path, options).await?;
 3187                    }
 3188                }
 3189
 3190                lsp::DocumentChangeOperation::Edit(op) => {
 3191                    let buffer_to_edit = this
 3192                        .update(cx, |this, cx| {
 3193                            this.open_local_buffer_via_lsp(
 3194                                op.text_document.uri.clone(),
 3195                                language_server.server_id(),
 3196                                cx,
 3197                            )
 3198                        })
 3199                        .await?;
 3200
 3201                    let edits = this
 3202                        .update(cx, |this, cx| {
 3203                            let path = buffer_to_edit.read(cx).project_path(cx);
 3204                            let active_entry = this.active_entry;
 3205                            let is_active_entry = path.is_some_and(|project_path| {
 3206                                this.worktree_store
 3207                                    .read(cx)
 3208                                    .entry_for_path(&project_path, cx)
 3209                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3210                            });
 3211                            let local = this.as_local_mut().unwrap();
 3212
 3213                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3214                            for edit in op.edits {
 3215                                match edit {
 3216                                    Edit::Plain(edit) => {
 3217                                        if !edits.contains(&edit) {
 3218                                            edits.push(edit)
 3219                                        }
 3220                                    }
 3221                                    Edit::Annotated(edit) => {
 3222                                        if !edits.contains(&edit.text_edit) {
 3223                                            edits.push(edit.text_edit)
 3224                                        }
 3225                                    }
 3226                                    Edit::Snippet(edit) => {
 3227                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3228                                        else {
 3229                                            continue;
 3230                                        };
 3231
 3232                                        if is_active_entry {
 3233                                            snippet_edits.push((edit.range, snippet));
 3234                                        } else {
 3235                                            // Since this buffer is not focused, apply a normal edit.
 3236                                            let new_edit = TextEdit {
 3237                                                range: edit.range,
 3238                                                new_text: snippet.text,
 3239                                            };
 3240                                            if !edits.contains(&new_edit) {
 3241                                                edits.push(new_edit);
 3242                                            }
 3243                                        }
 3244                                    }
 3245                                }
 3246                            }
 3247                            if !snippet_edits.is_empty() {
 3248                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3249                                let version = if let Some(buffer_version) = op.text_document.version
 3250                                {
 3251                                    local
 3252                                        .buffer_snapshot_for_lsp_version(
 3253                                            &buffer_to_edit,
 3254                                            language_server.server_id(),
 3255                                            Some(buffer_version),
 3256                                            cx,
 3257                                        )
 3258                                        .ok()
 3259                                        .map(|snapshot| snapshot.version)
 3260                                } else {
 3261                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3262                                };
 3263
 3264                                let most_recent_edit =
 3265                                    version.and_then(|version| version.most_recent());
 3266                                // Check if the edit that triggered that edit has been made by this participant.
 3267
 3268                                if let Some(most_recent_edit) = most_recent_edit {
 3269                                    cx.emit(LspStoreEvent::SnippetEdit {
 3270                                        buffer_id,
 3271                                        edits: snippet_edits,
 3272                                        most_recent_edit,
 3273                                    });
 3274                                }
 3275                            }
 3276
 3277                            local.edits_from_lsp(
 3278                                &buffer_to_edit,
 3279                                edits,
 3280                                language_server.server_id(),
 3281                                op.text_document.version,
 3282                                cx,
 3283                            )
 3284                        })
 3285                        .await?;
 3286
 3287                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3288                        buffer.finalize_last_transaction();
 3289                        buffer.start_transaction();
 3290                        for (range, text) in edits {
 3291                            buffer.edit([(range, text)], None, cx);
 3292                        }
 3293
 3294                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3295                            if push_to_history {
 3296                                buffer.finalize_last_transaction();
 3297                                buffer.get_transaction(transaction_id).cloned()
 3298                            } else {
 3299                                buffer.forget_transaction(transaction_id)
 3300                            }
 3301                        })
 3302                    });
 3303                    if let Some(transaction) = transaction {
 3304                        project_transaction.0.insert(buffer_to_edit, transaction);
 3305                    }
 3306                }
 3307            }
 3308        }
 3309
 3310        Ok(project_transaction)
 3311    }
 3312
 3313    async fn on_lsp_workspace_edit(
 3314        this: WeakEntity<LspStore>,
 3315        params: lsp::ApplyWorkspaceEditParams,
 3316        server_id: LanguageServerId,
 3317        cx: &mut AsyncApp,
 3318    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3319        let this = this.upgrade().context("project project closed")?;
 3320        let language_server = this
 3321            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3322            .context("language server not found")?;
 3323        let transaction = Self::deserialize_workspace_edit(
 3324            this.clone(),
 3325            params.edit,
 3326            true,
 3327            language_server.clone(),
 3328            cx,
 3329        )
 3330        .await
 3331        .log_err();
 3332        this.update(cx, |this, cx| {
 3333            if let Some(transaction) = transaction {
 3334                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3335
 3336                this.as_local_mut()
 3337                    .unwrap()
 3338                    .last_workspace_edits_by_language_server
 3339                    .insert(server_id, transaction);
 3340            }
 3341        });
 3342        Ok(lsp::ApplyWorkspaceEditResponse {
 3343            applied: true,
 3344            failed_change: None,
 3345            failure_reason: None,
 3346        })
 3347    }
 3348
 3349    fn remove_worktree(
 3350        &mut self,
 3351        id_to_remove: WorktreeId,
 3352        cx: &mut Context<LspStore>,
 3353    ) -> Vec<LanguageServerId> {
 3354        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3355        self.diagnostics.remove(&id_to_remove);
 3356        self.prettier_store.update(cx, |prettier_store, cx| {
 3357            prettier_store.remove_worktree(id_to_remove, cx);
 3358        });
 3359
 3360        let mut servers_to_remove = BTreeSet::default();
 3361        let mut servers_to_preserve = HashSet::default();
 3362        for (seed, state) in &self.language_server_ids {
 3363            if seed.worktree_id == id_to_remove {
 3364                servers_to_remove.insert(state.id);
 3365            } else {
 3366                servers_to_preserve.insert(state.id);
 3367            }
 3368        }
 3369        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3370        self.language_server_ids
 3371            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3372        for server_id_to_remove in &servers_to_remove {
 3373            self.language_server_watched_paths
 3374                .remove(server_id_to_remove);
 3375            self.language_server_paths_watched_for_rename
 3376                .remove(server_id_to_remove);
 3377            self.last_workspace_edits_by_language_server
 3378                .remove(server_id_to_remove);
 3379            self.language_servers.remove(server_id_to_remove);
 3380            self.buffer_pull_diagnostics_result_ids
 3381                .remove(server_id_to_remove);
 3382            self.workspace_pull_diagnostics_result_ids
 3383                .remove(server_id_to_remove);
 3384            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3385                buffer_servers.remove(server_id_to_remove);
 3386            }
 3387            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3388        }
 3389        servers_to_remove.into_iter().collect()
 3390    }
 3391
 3392    fn rebuild_watched_paths_inner<'a>(
 3393        &'a self,
 3394        language_server_id: LanguageServerId,
 3395        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3396        cx: &mut Context<LspStore>,
 3397    ) -> LanguageServerWatchedPathsBuilder {
 3398        let worktrees = self
 3399            .worktree_store
 3400            .read(cx)
 3401            .worktrees()
 3402            .filter_map(|worktree| {
 3403                self.language_servers_for_worktree(worktree.read(cx).id())
 3404                    .find(|server| server.server_id() == language_server_id)
 3405                    .map(|_| worktree)
 3406            })
 3407            .collect::<Vec<_>>();
 3408
 3409        let mut worktree_globs = HashMap::default();
 3410        let mut abs_globs = HashMap::default();
 3411        log::trace!(
 3412            "Processing new watcher paths for language server with id {}",
 3413            language_server_id
 3414        );
 3415
 3416        for watcher in watchers {
 3417            if let Some((worktree, literal_prefix, pattern)) =
 3418                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3419            {
 3420                worktree.update(cx, |worktree, _| {
 3421                    if let Some((tree, glob)) =
 3422                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3423                    {
 3424                        tree.add_path_prefix_to_scan(literal_prefix);
 3425                        worktree_globs
 3426                            .entry(tree.id())
 3427                            .or_insert_with(GlobSetBuilder::new)
 3428                            .add(glob);
 3429                    }
 3430                });
 3431            } else {
 3432                let (path, pattern) = match &watcher.glob_pattern {
 3433                    lsp::GlobPattern::String(s) => {
 3434                        let watcher_path = SanitizedPath::new(s);
 3435                        let path = glob_literal_prefix(watcher_path.as_path());
 3436                        let pattern = watcher_path
 3437                            .as_path()
 3438                            .strip_prefix(&path)
 3439                            .map(|p| p.to_string_lossy().into_owned())
 3440                            .unwrap_or_else(|e| {
 3441                                debug_panic!(
 3442                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3443                                    s,
 3444                                    path.display(),
 3445                                    e
 3446                                );
 3447                                watcher_path.as_path().to_string_lossy().into_owned()
 3448                            });
 3449                        (path, pattern)
 3450                    }
 3451                    lsp::GlobPattern::Relative(rp) => {
 3452                        let Ok(mut base_uri) = match &rp.base_uri {
 3453                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3454                            lsp::OneOf::Right(base_uri) => base_uri,
 3455                        }
 3456                        .to_file_path() else {
 3457                            continue;
 3458                        };
 3459
 3460                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3461                        let pattern = Path::new(&rp.pattern)
 3462                            .strip_prefix(&path)
 3463                            .map(|p| p.to_string_lossy().into_owned())
 3464                            .unwrap_or_else(|e| {
 3465                                debug_panic!(
 3466                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3467                                    rp.pattern,
 3468                                    path.display(),
 3469                                    e
 3470                                );
 3471                                rp.pattern.clone()
 3472                            });
 3473                        base_uri.push(path);
 3474                        (base_uri, pattern)
 3475                    }
 3476                };
 3477
 3478                if let Some(glob) = Glob::new(&pattern).log_err() {
 3479                    if !path
 3480                        .components()
 3481                        .any(|c| matches!(c, path::Component::Normal(_)))
 3482                    {
 3483                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3484                        // rather than adding a new watcher for `/`.
 3485                        for worktree in &worktrees {
 3486                            worktree_globs
 3487                                .entry(worktree.read(cx).id())
 3488                                .or_insert_with(GlobSetBuilder::new)
 3489                                .add(glob.clone());
 3490                        }
 3491                    } else {
 3492                        abs_globs
 3493                            .entry(path.into())
 3494                            .or_insert_with(GlobSetBuilder::new)
 3495                            .add(glob);
 3496                    }
 3497                }
 3498            }
 3499        }
 3500
 3501        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3502        for (worktree_id, builder) in worktree_globs {
 3503            if let Ok(globset) = builder.build() {
 3504                watch_builder.watch_worktree(worktree_id, globset);
 3505            }
 3506        }
 3507        for (abs_path, builder) in abs_globs {
 3508            if let Ok(globset) = builder.build() {
 3509                watch_builder.watch_abs_path(abs_path, globset);
 3510            }
 3511        }
 3512        watch_builder
 3513    }
 3514
 3515    fn worktree_and_path_for_file_watcher(
 3516        worktrees: &[Entity<Worktree>],
 3517        watcher: &FileSystemWatcher,
 3518        cx: &App,
 3519    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3520        worktrees.iter().find_map(|worktree| {
 3521            let tree = worktree.read(cx);
 3522            let worktree_root_path = tree.abs_path();
 3523            let path_style = tree.path_style();
 3524            match &watcher.glob_pattern {
 3525                lsp::GlobPattern::String(s) => {
 3526                    let watcher_path = SanitizedPath::new(s);
 3527                    let relative = watcher_path
 3528                        .as_path()
 3529                        .strip_prefix(&worktree_root_path)
 3530                        .ok()?;
 3531                    let literal_prefix = glob_literal_prefix(relative);
 3532                    Some((
 3533                        worktree.clone(),
 3534                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3535                        relative.to_string_lossy().into_owned(),
 3536                    ))
 3537                }
 3538                lsp::GlobPattern::Relative(rp) => {
 3539                    let base_uri = match &rp.base_uri {
 3540                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3541                        lsp::OneOf::Right(base_uri) => base_uri,
 3542                    }
 3543                    .to_file_path()
 3544                    .ok()?;
 3545                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3546                    let mut literal_prefix = relative.to_owned();
 3547                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3548                    Some((
 3549                        worktree.clone(),
 3550                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3551                        rp.pattern.clone(),
 3552                    ))
 3553                }
 3554            }
 3555        })
 3556    }
 3557
 3558    fn rebuild_watched_paths(
 3559        &mut self,
 3560        language_server_id: LanguageServerId,
 3561        cx: &mut Context<LspStore>,
 3562    ) {
 3563        let Some(registrations) = self
 3564            .language_server_dynamic_registrations
 3565            .get(&language_server_id)
 3566        else {
 3567            return;
 3568        };
 3569
 3570        let watch_builder = self.rebuild_watched_paths_inner(
 3571            language_server_id,
 3572            registrations.did_change_watched_files.values().flatten(),
 3573            cx,
 3574        );
 3575        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3576        self.language_server_watched_paths
 3577            .insert(language_server_id, watcher);
 3578
 3579        cx.notify();
 3580    }
 3581
 3582    fn on_lsp_did_change_watched_files(
 3583        &mut self,
 3584        language_server_id: LanguageServerId,
 3585        registration_id: &str,
 3586        params: DidChangeWatchedFilesRegistrationOptions,
 3587        cx: &mut Context<LspStore>,
 3588    ) {
 3589        let registrations = self
 3590            .language_server_dynamic_registrations
 3591            .entry(language_server_id)
 3592            .or_default();
 3593
 3594        registrations
 3595            .did_change_watched_files
 3596            .insert(registration_id.to_string(), params.watchers);
 3597
 3598        self.rebuild_watched_paths(language_server_id, cx);
 3599    }
 3600
 3601    fn on_lsp_unregister_did_change_watched_files(
 3602        &mut self,
 3603        language_server_id: LanguageServerId,
 3604        registration_id: &str,
 3605        cx: &mut Context<LspStore>,
 3606    ) {
 3607        let registrations = self
 3608            .language_server_dynamic_registrations
 3609            .entry(language_server_id)
 3610            .or_default();
 3611
 3612        if registrations
 3613            .did_change_watched_files
 3614            .remove(registration_id)
 3615            .is_some()
 3616        {
 3617            log::info!(
 3618                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3619                language_server_id,
 3620                registration_id
 3621            );
 3622        } else {
 3623            log::warn!(
 3624                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3625                language_server_id,
 3626                registration_id
 3627            );
 3628        }
 3629
 3630        self.rebuild_watched_paths(language_server_id, cx);
 3631    }
 3632
 3633    async fn initialization_options_for_adapter(
 3634        adapter: Arc<dyn LspAdapter>,
 3635        delegate: &Arc<dyn LspAdapterDelegate>,
 3636    ) -> Result<Option<serde_json::Value>> {
 3637        let Some(mut initialization_config) =
 3638            adapter.clone().initialization_options(delegate).await?
 3639        else {
 3640            return Ok(None);
 3641        };
 3642
 3643        for other_adapter in delegate.registered_lsp_adapters() {
 3644            if other_adapter.name() == adapter.name() {
 3645                continue;
 3646            }
 3647            if let Ok(Some(target_config)) = other_adapter
 3648                .clone()
 3649                .additional_initialization_options(adapter.name(), delegate)
 3650                .await
 3651            {
 3652                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3653            }
 3654        }
 3655
 3656        Ok(Some(initialization_config))
 3657    }
 3658
 3659    async fn workspace_configuration_for_adapter(
 3660        adapter: Arc<dyn LspAdapter>,
 3661        delegate: &Arc<dyn LspAdapterDelegate>,
 3662        toolchain: Option<Toolchain>,
 3663        requested_uri: Option<Uri>,
 3664        cx: &mut AsyncApp,
 3665    ) -> Result<serde_json::Value> {
 3666        let mut workspace_config = adapter
 3667            .clone()
 3668            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3669            .await?;
 3670
 3671        for other_adapter in delegate.registered_lsp_adapters() {
 3672            if other_adapter.name() == adapter.name() {
 3673                continue;
 3674            }
 3675            if let Ok(Some(target_config)) = other_adapter
 3676                .clone()
 3677                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3678                .await
 3679            {
 3680                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3681            }
 3682        }
 3683
 3684        Ok(workspace_config)
 3685    }
 3686
 3687    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3688        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3689            Some(server.clone())
 3690        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3691            Some(Arc::clone(server))
 3692        } else {
 3693            None
 3694        }
 3695    }
 3696}
 3697
 3698fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3699    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3700        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3701            language_server_id: server.server_id(),
 3702            name: Some(server.name()),
 3703            message: proto::update_language_server::Variant::MetadataUpdated(
 3704                proto::ServerMetadataUpdated {
 3705                    capabilities: Some(capabilities),
 3706                    binary: Some(proto::LanguageServerBinaryInfo {
 3707                        path: server.binary().path.to_string_lossy().into_owned(),
 3708                        arguments: server
 3709                            .binary()
 3710                            .arguments
 3711                            .iter()
 3712                            .map(|arg| arg.to_string_lossy().into_owned())
 3713                            .collect(),
 3714                    }),
 3715                    configuration: serde_json::to_string(server.configuration()).ok(),
 3716                    workspace_folders: server
 3717                        .workspace_folders()
 3718                        .iter()
 3719                        .map(|uri| uri.to_string())
 3720                        .collect(),
 3721                },
 3722            ),
 3723        });
 3724    }
 3725}
 3726
 3727#[derive(Debug)]
 3728pub struct FormattableBuffer {
 3729    handle: Entity<Buffer>,
 3730    abs_path: Option<PathBuf>,
 3731    env: Option<HashMap<String, String>>,
 3732    ranges: Option<Vec<Range<Anchor>>>,
 3733}
 3734
 3735pub struct RemoteLspStore {
 3736    upstream_client: Option<AnyProtoClient>,
 3737    upstream_project_id: u64,
 3738}
 3739
 3740pub(crate) enum LspStoreMode {
 3741    Local(LocalLspStore),   // ssh host and collab host
 3742    Remote(RemoteLspStore), // collab guest
 3743}
 3744
 3745impl LspStoreMode {
 3746    fn is_local(&self) -> bool {
 3747        matches!(self, LspStoreMode::Local(_))
 3748    }
 3749}
 3750
 3751pub struct LspStore {
 3752    mode: LspStoreMode,
 3753    last_formatting_failure: Option<String>,
 3754    downstream_client: Option<(AnyProtoClient, u64)>,
 3755    nonce: u128,
 3756    buffer_store: Entity<BufferStore>,
 3757    worktree_store: Entity<WorktreeStore>,
 3758    pub languages: Arc<LanguageRegistry>,
 3759    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3760    active_entry: Option<ProjectEntryId>,
 3761    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3762    _maintain_buffer_languages: Task<()>,
 3763    diagnostic_summaries:
 3764        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3765    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3766    lsp_data: HashMap<BufferId, BufferLspData>,
 3767    next_hint_id: Arc<AtomicUsize>,
 3768}
 3769
 3770#[derive(Debug)]
 3771pub struct BufferLspData {
 3772    buffer_version: Global,
 3773    document_colors: Option<DocumentColorData>,
 3774    code_lens: Option<CodeLensData>,
 3775    inlay_hints: BufferInlayHints,
 3776    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3777    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3778}
 3779
 3780#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3781struct LspKey {
 3782    request_type: TypeId,
 3783    server_queried: Option<LanguageServerId>,
 3784}
 3785
 3786impl BufferLspData {
 3787    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3788        Self {
 3789            buffer_version: buffer.read(cx).version(),
 3790            document_colors: None,
 3791            code_lens: None,
 3792            inlay_hints: BufferInlayHints::new(buffer, cx),
 3793            lsp_requests: HashMap::default(),
 3794            chunk_lsp_requests: HashMap::default(),
 3795        }
 3796    }
 3797
 3798    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3799        if let Some(document_colors) = &mut self.document_colors {
 3800            document_colors.colors.remove(&for_server);
 3801            document_colors.cache_version += 1;
 3802        }
 3803
 3804        if let Some(code_lens) = &mut self.code_lens {
 3805            code_lens.lens.remove(&for_server);
 3806        }
 3807
 3808        self.inlay_hints.remove_server_data(for_server);
 3809    }
 3810
 3811    #[cfg(any(test, feature = "test-support"))]
 3812    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3813        &self.inlay_hints
 3814    }
 3815}
 3816
 3817#[derive(Debug, Default, Clone)]
 3818pub struct DocumentColors {
 3819    pub colors: HashSet<DocumentColor>,
 3820    pub cache_version: Option<usize>,
 3821}
 3822
 3823type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3824type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3825
 3826#[derive(Debug, Default)]
 3827struct DocumentColorData {
 3828    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3829    cache_version: usize,
 3830    colors_update: Option<(Global, DocumentColorTask)>,
 3831}
 3832
 3833#[derive(Debug, Default)]
 3834struct CodeLensData {
 3835    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3836    update: Option<(Global, CodeLensTask)>,
 3837}
 3838
 3839#[derive(Debug)]
 3840pub enum LspStoreEvent {
 3841    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3842    LanguageServerRemoved(LanguageServerId),
 3843    LanguageServerUpdate {
 3844        language_server_id: LanguageServerId,
 3845        name: Option<LanguageServerName>,
 3846        message: proto::update_language_server::Variant,
 3847    },
 3848    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3849    LanguageServerPrompt(LanguageServerPromptRequest),
 3850    LanguageDetected {
 3851        buffer: Entity<Buffer>,
 3852        new_language: Option<Arc<Language>>,
 3853    },
 3854    Notification(String),
 3855    RefreshInlayHints {
 3856        server_id: LanguageServerId,
 3857        request_id: Option<usize>,
 3858    },
 3859    RefreshCodeLens,
 3860    DiagnosticsUpdated {
 3861        server_id: LanguageServerId,
 3862        paths: Vec<ProjectPath>,
 3863    },
 3864    DiskBasedDiagnosticsStarted {
 3865        language_server_id: LanguageServerId,
 3866    },
 3867    DiskBasedDiagnosticsFinished {
 3868        language_server_id: LanguageServerId,
 3869    },
 3870    SnippetEdit {
 3871        buffer_id: BufferId,
 3872        edits: Vec<(lsp::Range, Snippet)>,
 3873        most_recent_edit: clock::Lamport,
 3874    },
 3875    WorkspaceEditApplied(ProjectTransaction),
 3876}
 3877
 3878#[derive(Clone, Debug, Serialize)]
 3879pub struct LanguageServerStatus {
 3880    pub name: LanguageServerName,
 3881    pub server_version: Option<SharedString>,
 3882    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3883    pub has_pending_diagnostic_updates: bool,
 3884    pub progress_tokens: HashSet<ProgressToken>,
 3885    pub worktree: Option<WorktreeId>,
 3886    pub binary: Option<LanguageServerBinary>,
 3887    pub configuration: Option<Value>,
 3888    pub workspace_folders: BTreeSet<Uri>,
 3889}
 3890
 3891#[derive(Clone, Debug)]
 3892struct CoreSymbol {
 3893    pub language_server_name: LanguageServerName,
 3894    pub source_worktree_id: WorktreeId,
 3895    pub source_language_server_id: LanguageServerId,
 3896    pub path: SymbolLocation,
 3897    pub name: String,
 3898    pub kind: lsp::SymbolKind,
 3899    pub range: Range<Unclipped<PointUtf16>>,
 3900}
 3901
 3902#[derive(Clone, Debug, PartialEq, Eq)]
 3903pub enum SymbolLocation {
 3904    InProject(ProjectPath),
 3905    OutsideProject {
 3906        abs_path: Arc<Path>,
 3907        signature: [u8; 32],
 3908    },
 3909}
 3910
 3911impl SymbolLocation {
 3912    fn file_name(&self) -> Option<&str> {
 3913        match self {
 3914            Self::InProject(path) => path.path.file_name(),
 3915            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3916        }
 3917    }
 3918}
 3919
 3920impl LspStore {
 3921    pub fn init(client: &AnyProtoClient) {
 3922        client.add_entity_request_handler(Self::handle_lsp_query);
 3923        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3924        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3925        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3926        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3927        client.add_entity_message_handler(Self::handle_start_language_server);
 3928        client.add_entity_message_handler(Self::handle_update_language_server);
 3929        client.add_entity_message_handler(Self::handle_language_server_log);
 3930        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3931        client.add_entity_request_handler(Self::handle_format_buffers);
 3932        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3933        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3934        client.add_entity_request_handler(Self::handle_apply_code_action);
 3935        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3936        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3937        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3938        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3939        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3940        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3941        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3942        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3943        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3944        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3945        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3946        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3947        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3948        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3949        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3950        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3951        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3952
 3953        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3954        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3955        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3956        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3957        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3958        client.add_entity_request_handler(
 3959            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3960        );
 3961        client.add_entity_request_handler(
 3962            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3963        );
 3964        client.add_entity_request_handler(
 3965            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3966        );
 3967    }
 3968
 3969    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3970        match &self.mode {
 3971            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3972            _ => None,
 3973        }
 3974    }
 3975
 3976    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3977        match &self.mode {
 3978            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3979            _ => None,
 3980        }
 3981    }
 3982
 3983    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3984        match &mut self.mode {
 3985            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3986            _ => None,
 3987        }
 3988    }
 3989
 3990    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3991        match &self.mode {
 3992            LspStoreMode::Remote(RemoteLspStore {
 3993                upstream_client: Some(upstream_client),
 3994                upstream_project_id,
 3995                ..
 3996            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3997
 3998            LspStoreMode::Remote(RemoteLspStore {
 3999                upstream_client: None,
 4000                ..
 4001            }) => None,
 4002            LspStoreMode::Local(_) => None,
 4003        }
 4004    }
 4005
 4006    pub fn new_local(
 4007        buffer_store: Entity<BufferStore>,
 4008        worktree_store: Entity<WorktreeStore>,
 4009        prettier_store: Entity<PrettierStore>,
 4010        toolchain_store: Entity<LocalToolchainStore>,
 4011        environment: Entity<ProjectEnvironment>,
 4012        manifest_tree: Entity<ManifestTree>,
 4013        languages: Arc<LanguageRegistry>,
 4014        http_client: Arc<dyn HttpClient>,
 4015        fs: Arc<dyn Fs>,
 4016        cx: &mut Context<Self>,
 4017    ) -> Self {
 4018        let yarn = YarnPathStore::new(fs.clone(), cx);
 4019        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4020            .detach();
 4021        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4022            .detach();
 4023        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4024            .detach();
 4025        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4026            .detach();
 4027        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4028            .detach();
 4029        subscribe_to_binary_statuses(&languages, cx).detach();
 4030
 4031        let _maintain_workspace_config = {
 4032            let (sender, receiver) = watch::channel();
 4033            (Self::maintain_workspace_config(receiver, cx), sender)
 4034        };
 4035
 4036        Self {
 4037            mode: LspStoreMode::Local(LocalLspStore {
 4038                weak: cx.weak_entity(),
 4039                worktree_store: worktree_store.clone(),
 4040
 4041                supplementary_language_servers: Default::default(),
 4042                languages: languages.clone(),
 4043                language_server_ids: Default::default(),
 4044                language_servers: Default::default(),
 4045                last_workspace_edits_by_language_server: Default::default(),
 4046                language_server_watched_paths: Default::default(),
 4047                language_server_paths_watched_for_rename: Default::default(),
 4048                language_server_dynamic_registrations: Default::default(),
 4049                buffers_being_formatted: Default::default(),
 4050                buffer_snapshots: Default::default(),
 4051                prettier_store,
 4052                environment,
 4053                http_client,
 4054                fs,
 4055                yarn,
 4056                next_diagnostic_group_id: Default::default(),
 4057                diagnostics: Default::default(),
 4058                _subscription: cx.on_app_quit(|this, cx| {
 4059                    this.as_local_mut()
 4060                        .unwrap()
 4061                        .shutdown_language_servers_on_quit(cx)
 4062                }),
 4063                lsp_tree: LanguageServerTree::new(
 4064                    manifest_tree,
 4065                    languages.clone(),
 4066                    toolchain_store.clone(),
 4067                ),
 4068                toolchain_store,
 4069                registered_buffers: HashMap::default(),
 4070                buffers_opened_in_servers: HashMap::default(),
 4071                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4072                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4073                restricted_worktrees_tasks: HashMap::default(),
 4074                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4075                    .manifest_file_names(),
 4076            }),
 4077            last_formatting_failure: None,
 4078            downstream_client: None,
 4079            buffer_store,
 4080            worktree_store,
 4081            languages: languages.clone(),
 4082            language_server_statuses: Default::default(),
 4083            nonce: StdRng::from_os_rng().random(),
 4084            diagnostic_summaries: HashMap::default(),
 4085            lsp_server_capabilities: HashMap::default(),
 4086            lsp_data: HashMap::default(),
 4087            next_hint_id: Arc::default(),
 4088            active_entry: None,
 4089            _maintain_workspace_config,
 4090            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4091        }
 4092    }
 4093
 4094    fn send_lsp_proto_request<R: LspCommand>(
 4095        &self,
 4096        buffer: Entity<Buffer>,
 4097        client: AnyProtoClient,
 4098        upstream_project_id: u64,
 4099        request: R,
 4100        cx: &mut Context<LspStore>,
 4101    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4102        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4103            return Task::ready(Ok(R::Response::default()));
 4104        }
 4105        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4106        cx.spawn(async move |this, cx| {
 4107            let response = client.request(message).await?;
 4108            let this = this.upgrade().context("project dropped")?;
 4109            request
 4110                .response_from_proto(response, this, buffer, cx.clone())
 4111                .await
 4112        })
 4113    }
 4114
 4115    pub(super) fn new_remote(
 4116        buffer_store: Entity<BufferStore>,
 4117        worktree_store: Entity<WorktreeStore>,
 4118        languages: Arc<LanguageRegistry>,
 4119        upstream_client: AnyProtoClient,
 4120        project_id: u64,
 4121        cx: &mut Context<Self>,
 4122    ) -> Self {
 4123        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4124            .detach();
 4125        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4126            .detach();
 4127        subscribe_to_binary_statuses(&languages, cx).detach();
 4128        let _maintain_workspace_config = {
 4129            let (sender, receiver) = watch::channel();
 4130            (Self::maintain_workspace_config(receiver, cx), sender)
 4131        };
 4132        Self {
 4133            mode: LspStoreMode::Remote(RemoteLspStore {
 4134                upstream_client: Some(upstream_client),
 4135                upstream_project_id: project_id,
 4136            }),
 4137            downstream_client: None,
 4138            last_formatting_failure: None,
 4139            buffer_store,
 4140            worktree_store,
 4141            languages: languages.clone(),
 4142            language_server_statuses: Default::default(),
 4143            nonce: StdRng::from_os_rng().random(),
 4144            diagnostic_summaries: HashMap::default(),
 4145            lsp_server_capabilities: HashMap::default(),
 4146            next_hint_id: Arc::default(),
 4147            lsp_data: HashMap::default(),
 4148            active_entry: None,
 4149
 4150            _maintain_workspace_config,
 4151            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4152        }
 4153    }
 4154
 4155    fn on_buffer_store_event(
 4156        &mut self,
 4157        _: Entity<BufferStore>,
 4158        event: &BufferStoreEvent,
 4159        cx: &mut Context<Self>,
 4160    ) {
 4161        match event {
 4162            BufferStoreEvent::BufferAdded(buffer) => {
 4163                self.on_buffer_added(buffer, cx).log_err();
 4164            }
 4165            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4166                let buffer_id = buffer.read(cx).remote_id();
 4167                if let Some(local) = self.as_local_mut()
 4168                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4169                {
 4170                    local.reset_buffer(buffer, old_file, cx);
 4171
 4172                    if local.registered_buffers.contains_key(&buffer_id) {
 4173                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4174                    }
 4175                }
 4176
 4177                self.detect_language_for_buffer(buffer, cx);
 4178                if let Some(local) = self.as_local_mut() {
 4179                    local.initialize_buffer(buffer, cx);
 4180                    if local.registered_buffers.contains_key(&buffer_id) {
 4181                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4182                    }
 4183                }
 4184            }
 4185            _ => {}
 4186        }
 4187    }
 4188
 4189    fn on_worktree_store_event(
 4190        &mut self,
 4191        _: Entity<WorktreeStore>,
 4192        event: &WorktreeStoreEvent,
 4193        cx: &mut Context<Self>,
 4194    ) {
 4195        match event {
 4196            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4197                if !worktree.read(cx).is_local() {
 4198                    return;
 4199                }
 4200                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4201                    worktree::Event::UpdatedEntries(changes) => {
 4202                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4203                    }
 4204                    worktree::Event::UpdatedGitRepositories(_)
 4205                    | worktree::Event::DeletedEntry(_) => {}
 4206                })
 4207                .detach()
 4208            }
 4209            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4210            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4211                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4212            }
 4213            WorktreeStoreEvent::WorktreeReleased(..)
 4214            | WorktreeStoreEvent::WorktreeOrderChanged
 4215            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4216            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4217            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4218        }
 4219    }
 4220
 4221    fn on_prettier_store_event(
 4222        &mut self,
 4223        _: Entity<PrettierStore>,
 4224        event: &PrettierStoreEvent,
 4225        cx: &mut Context<Self>,
 4226    ) {
 4227        match event {
 4228            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4229                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4230            }
 4231            PrettierStoreEvent::LanguageServerAdded {
 4232                new_server_id,
 4233                name,
 4234                prettier_server,
 4235            } => {
 4236                self.register_supplementary_language_server(
 4237                    *new_server_id,
 4238                    name.clone(),
 4239                    prettier_server.clone(),
 4240                    cx,
 4241                );
 4242            }
 4243        }
 4244    }
 4245
 4246    fn on_toolchain_store_event(
 4247        &mut self,
 4248        _: Entity<LocalToolchainStore>,
 4249        event: &ToolchainStoreEvent,
 4250        _: &mut Context<Self>,
 4251    ) {
 4252        if let ToolchainStoreEvent::ToolchainActivated = event {
 4253            self.request_workspace_config_refresh()
 4254        }
 4255    }
 4256
 4257    fn request_workspace_config_refresh(&mut self) {
 4258        *self._maintain_workspace_config.1.borrow_mut() = ();
 4259    }
 4260
 4261    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4262        self.as_local().map(|local| local.prettier_store.clone())
 4263    }
 4264
 4265    fn on_buffer_event(
 4266        &mut self,
 4267        buffer: Entity<Buffer>,
 4268        event: &language::BufferEvent,
 4269        cx: &mut Context<Self>,
 4270    ) {
 4271        match event {
 4272            language::BufferEvent::Edited => {
 4273                self.on_buffer_edited(buffer, cx);
 4274            }
 4275
 4276            language::BufferEvent::Saved => {
 4277                self.on_buffer_saved(buffer, cx);
 4278            }
 4279
 4280            _ => {}
 4281        }
 4282    }
 4283
 4284    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4285        buffer
 4286            .read(cx)
 4287            .set_language_registry(self.languages.clone());
 4288
 4289        cx.subscribe(buffer, |this, buffer, event, cx| {
 4290            this.on_buffer_event(buffer, event, cx);
 4291        })
 4292        .detach();
 4293
 4294        self.detect_language_for_buffer(buffer, cx);
 4295        if let Some(local) = self.as_local_mut() {
 4296            local.initialize_buffer(buffer, cx);
 4297        }
 4298
 4299        Ok(())
 4300    }
 4301
 4302    pub(crate) fn register_buffer_with_language_servers(
 4303        &mut self,
 4304        buffer: &Entity<Buffer>,
 4305        only_register_servers: HashSet<LanguageServerSelector>,
 4306        ignore_refcounts: bool,
 4307        cx: &mut Context<Self>,
 4308    ) -> OpenLspBufferHandle {
 4309        let buffer_id = buffer.read(cx).remote_id();
 4310        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4311        if let Some(local) = self.as_local_mut() {
 4312            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4313            if !ignore_refcounts {
 4314                *refcount += 1;
 4315            }
 4316
 4317            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4318            // 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
 4319            // 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
 4320            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4321            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4322                return handle;
 4323            };
 4324            if !file.is_local() {
 4325                return handle;
 4326            }
 4327
 4328            if ignore_refcounts || *refcount == 1 {
 4329                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4330            }
 4331            if !ignore_refcounts {
 4332                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4333                    let refcount = {
 4334                        let local = lsp_store.as_local_mut().unwrap();
 4335                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4336                            debug_panic!("bad refcounting");
 4337                            return;
 4338                        };
 4339
 4340                        *refcount -= 1;
 4341                        *refcount
 4342                    };
 4343                    if refcount == 0 {
 4344                        lsp_store.lsp_data.remove(&buffer_id);
 4345                        let local = lsp_store.as_local_mut().unwrap();
 4346                        local.registered_buffers.remove(&buffer_id);
 4347
 4348                        local.buffers_opened_in_servers.remove(&buffer_id);
 4349                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4350                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4351
 4352                            let buffer_abs_path = file.abs_path(cx);
 4353                            for (_, buffer_pull_diagnostics_result_ids) in
 4354                                &mut local.buffer_pull_diagnostics_result_ids
 4355                            {
 4356                                buffer_pull_diagnostics_result_ids.retain(
 4357                                    |_, buffer_result_ids| {
 4358                                        buffer_result_ids.remove(&buffer_abs_path);
 4359                                        !buffer_result_ids.is_empty()
 4360                                    },
 4361                                );
 4362                            }
 4363
 4364                            let diagnostic_updates = local
 4365                                .language_servers
 4366                                .keys()
 4367                                .cloned()
 4368                                .map(|server_id| DocumentDiagnosticsUpdate {
 4369                                    diagnostics: DocumentDiagnostics {
 4370                                        document_abs_path: buffer_abs_path.clone(),
 4371                                        version: None,
 4372                                        diagnostics: Vec::new(),
 4373                                    },
 4374                                    result_id: None,
 4375                                    registration_id: None,
 4376                                    server_id: server_id,
 4377                                    disk_based_sources: Cow::Borrowed(&[]),
 4378                                })
 4379                                .collect::<Vec<_>>();
 4380
 4381                            lsp_store
 4382                                .merge_diagnostic_entries(
 4383                                    diagnostic_updates,
 4384                                    |_, diagnostic, _| {
 4385                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4386                                    },
 4387                                    cx,
 4388                                )
 4389                                .context("Clearing diagnostics for the closed buffer")
 4390                                .log_err();
 4391                        }
 4392                    }
 4393                })
 4394                .detach();
 4395            }
 4396        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4397            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4398            cx.background_spawn(async move {
 4399                upstream_client
 4400                    .request(proto::RegisterBufferWithLanguageServers {
 4401                        project_id: upstream_project_id,
 4402                        buffer_id,
 4403                        only_servers: only_register_servers
 4404                            .into_iter()
 4405                            .map(|selector| {
 4406                                let selector = match selector {
 4407                                    LanguageServerSelector::Id(language_server_id) => {
 4408                                        proto::language_server_selector::Selector::ServerId(
 4409                                            language_server_id.to_proto(),
 4410                                        )
 4411                                    }
 4412                                    LanguageServerSelector::Name(language_server_name) => {
 4413                                        proto::language_server_selector::Selector::Name(
 4414                                            language_server_name.to_string(),
 4415                                        )
 4416                                    }
 4417                                };
 4418                                proto::LanguageServerSelector {
 4419                                    selector: Some(selector),
 4420                                }
 4421                            })
 4422                            .collect(),
 4423                    })
 4424                    .await
 4425            })
 4426            .detach();
 4427        } else {
 4428            // Our remote connection got closed
 4429        }
 4430        handle
 4431    }
 4432
 4433    fn maintain_buffer_languages(
 4434        languages: Arc<LanguageRegistry>,
 4435        cx: &mut Context<Self>,
 4436    ) -> Task<()> {
 4437        let mut subscription = languages.subscribe();
 4438        let mut prev_reload_count = languages.reload_count();
 4439        cx.spawn(async move |this, cx| {
 4440            while let Some(()) = subscription.next().await {
 4441                if let Some(this) = this.upgrade() {
 4442                    // If the language registry has been reloaded, then remove and
 4443                    // re-assign the languages on all open buffers.
 4444                    let reload_count = languages.reload_count();
 4445                    if reload_count > prev_reload_count {
 4446                        prev_reload_count = reload_count;
 4447                        this.update(cx, |this, cx| {
 4448                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4449                                for buffer in buffer_store.buffers() {
 4450                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4451                                    {
 4452                                        buffer.update(cx, |buffer, cx| {
 4453                                            buffer.set_language_async(None, cx)
 4454                                        });
 4455                                        if let Some(local) = this.as_local_mut() {
 4456                                            local.reset_buffer(&buffer, &f, cx);
 4457
 4458                                            if local
 4459                                                .registered_buffers
 4460                                                .contains_key(&buffer.read(cx).remote_id())
 4461                                                && let Some(file_url) =
 4462                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4463                                            {
 4464                                                local.unregister_buffer_from_language_servers(
 4465                                                    &buffer, &file_url, cx,
 4466                                                );
 4467                                            }
 4468                                        }
 4469                                    }
 4470                                }
 4471                            });
 4472                        });
 4473                    }
 4474
 4475                    this.update(cx, |this, cx| {
 4476                        let mut plain_text_buffers = Vec::new();
 4477                        let mut buffers_with_unknown_injections = Vec::new();
 4478                        for handle in this.buffer_store.read(cx).buffers() {
 4479                            let buffer = handle.read(cx);
 4480                            if buffer.language().is_none()
 4481                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4482                            {
 4483                                plain_text_buffers.push(handle);
 4484                            } else if buffer.contains_unknown_injections() {
 4485                                buffers_with_unknown_injections.push(handle);
 4486                            }
 4487                        }
 4488
 4489                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4490                        // and reused later in the invisible worktrees.
 4491                        plain_text_buffers.sort_by_key(|buffer| {
 4492                            Reverse(
 4493                                File::from_dyn(buffer.read(cx).file())
 4494                                    .map(|file| file.worktree.read(cx).is_visible()),
 4495                            )
 4496                        });
 4497
 4498                        for buffer in plain_text_buffers {
 4499                            this.detect_language_for_buffer(&buffer, cx);
 4500                            if let Some(local) = this.as_local_mut() {
 4501                                local.initialize_buffer(&buffer, cx);
 4502                                if local
 4503                                    .registered_buffers
 4504                                    .contains_key(&buffer.read(cx).remote_id())
 4505                                {
 4506                                    local.register_buffer_with_language_servers(
 4507                                        &buffer,
 4508                                        HashSet::default(),
 4509                                        cx,
 4510                                    );
 4511                                }
 4512                            }
 4513                        }
 4514
 4515                        for buffer in buffers_with_unknown_injections {
 4516                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4517                        }
 4518                    });
 4519                }
 4520            }
 4521        })
 4522    }
 4523
 4524    fn detect_language_for_buffer(
 4525        &mut self,
 4526        buffer_handle: &Entity<Buffer>,
 4527        cx: &mut Context<Self>,
 4528    ) -> Option<language::AvailableLanguage> {
 4529        // If the buffer has a language, set it and start the language server if we haven't already.
 4530        let buffer = buffer_handle.read(cx);
 4531        let file = buffer.file()?;
 4532
 4533        let content = buffer.as_rope();
 4534        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4535        if let Some(available_language) = &available_language {
 4536            if let Some(Ok(Ok(new_language))) = self
 4537                .languages
 4538                .load_language(available_language)
 4539                .now_or_never()
 4540            {
 4541                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4542            }
 4543        } else {
 4544            cx.emit(LspStoreEvent::LanguageDetected {
 4545                buffer: buffer_handle.clone(),
 4546                new_language: None,
 4547            });
 4548        }
 4549
 4550        available_language
 4551    }
 4552
 4553    pub(crate) fn set_language_for_buffer(
 4554        &mut self,
 4555        buffer_entity: &Entity<Buffer>,
 4556        new_language: Arc<Language>,
 4557        cx: &mut Context<Self>,
 4558    ) {
 4559        let buffer = buffer_entity.read(cx);
 4560        let buffer_file = buffer.file().cloned();
 4561        let buffer_id = buffer.remote_id();
 4562        if let Some(local_store) = self.as_local_mut()
 4563            && local_store.registered_buffers.contains_key(&buffer_id)
 4564            && let Some(abs_path) =
 4565                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4566            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4567        {
 4568            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4569        }
 4570        buffer_entity.update(cx, |buffer, cx| {
 4571            if buffer
 4572                .language()
 4573                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4574            {
 4575                buffer.set_language_async(Some(new_language.clone()), cx);
 4576            }
 4577        });
 4578
 4579        let settings =
 4580            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4581        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4582
 4583        let worktree_id = if let Some(file) = buffer_file {
 4584            let worktree = file.worktree.clone();
 4585
 4586            if let Some(local) = self.as_local_mut()
 4587                && local.registered_buffers.contains_key(&buffer_id)
 4588            {
 4589                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4590            }
 4591            Some(worktree.read(cx).id())
 4592        } else {
 4593            None
 4594        };
 4595
 4596        if settings.prettier.allowed
 4597            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4598        {
 4599            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4600            if let Some(prettier_store) = prettier_store {
 4601                prettier_store.update(cx, |prettier_store, cx| {
 4602                    prettier_store.install_default_prettier(
 4603                        worktree_id,
 4604                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4605                        cx,
 4606                    )
 4607                })
 4608            }
 4609        }
 4610
 4611        cx.emit(LspStoreEvent::LanguageDetected {
 4612            buffer: buffer_entity.clone(),
 4613            new_language: Some(new_language),
 4614        })
 4615    }
 4616
 4617    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4618        self.buffer_store.clone()
 4619    }
 4620
 4621    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4622        self.active_entry = active_entry;
 4623    }
 4624
 4625    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4626        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4627            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4628        {
 4629            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4630                summaries
 4631                    .iter()
 4632                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4633            });
 4634            if let Some(summary) = summaries.next() {
 4635                client
 4636                    .send(proto::UpdateDiagnosticSummary {
 4637                        project_id: downstream_project_id,
 4638                        worktree_id: worktree.id().to_proto(),
 4639                        summary: Some(summary),
 4640                        more_summaries: summaries.collect(),
 4641                    })
 4642                    .log_err();
 4643            }
 4644        }
 4645    }
 4646
 4647    fn is_capable_for_proto_request<R>(
 4648        &self,
 4649        buffer: &Entity<Buffer>,
 4650        request: &R,
 4651        cx: &App,
 4652    ) -> bool
 4653    where
 4654        R: LspCommand,
 4655    {
 4656        self.check_if_capable_for_proto_request(
 4657            buffer,
 4658            |capabilities| {
 4659                request.check_capabilities(AdapterServerCapabilities {
 4660                    server_capabilities: capabilities.clone(),
 4661                    code_action_kinds: None,
 4662                })
 4663            },
 4664            cx,
 4665        )
 4666    }
 4667
 4668    fn check_if_capable_for_proto_request<F>(
 4669        &self,
 4670        buffer: &Entity<Buffer>,
 4671        check: F,
 4672        cx: &App,
 4673    ) -> bool
 4674    where
 4675        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4676    {
 4677        let Some(language) = buffer.read(cx).language().cloned() else {
 4678            return false;
 4679        };
 4680        let registered_language_servers = self
 4681            .languages
 4682            .lsp_adapters(&language.name())
 4683            .into_iter()
 4684            .map(|lsp_adapter| lsp_adapter.name())
 4685            .collect::<HashSet<_>>();
 4686        self.language_server_statuses
 4687            .iter()
 4688            .filter_map(|(server_id, server_status)| {
 4689                // Include servers that are either registered for this language OR
 4690                // available to be loaded (for SSH remote mode where adapters like
 4691                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4692                // but only loaded on the server side)
 4693                let is_relevant = registered_language_servers.contains(&server_status.name)
 4694                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4695                is_relevant.then_some(server_id)
 4696            })
 4697            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4698            .any(check)
 4699    }
 4700
 4701    fn all_capable_for_proto_request<F>(
 4702        &self,
 4703        buffer: &Entity<Buffer>,
 4704        mut check: F,
 4705        cx: &App,
 4706    ) -> Vec<lsp::LanguageServerId>
 4707    where
 4708        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4709    {
 4710        let Some(language) = buffer.read(cx).language().cloned() else {
 4711            return Vec::default();
 4712        };
 4713        let registered_language_servers = self
 4714            .languages
 4715            .lsp_adapters(&language.name())
 4716            .into_iter()
 4717            .map(|lsp_adapter| lsp_adapter.name())
 4718            .collect::<HashSet<_>>();
 4719        self.language_server_statuses
 4720            .iter()
 4721            .filter_map(|(server_id, server_status)| {
 4722                // Include servers that are either registered for this language OR
 4723                // available to be loaded (for SSH remote mode where adapters like
 4724                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4725                // but only loaded on the server side)
 4726                let is_relevant = registered_language_servers.contains(&server_status.name)
 4727                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4728                is_relevant.then_some((server_id, &server_status.name))
 4729            })
 4730            .filter_map(|(server_id, server_name)| {
 4731                self.lsp_server_capabilities
 4732                    .get(server_id)
 4733                    .map(|c| (server_id, server_name, c))
 4734            })
 4735            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4736            .map(|(server_id, _, _)| *server_id)
 4737            .collect()
 4738    }
 4739
 4740    pub fn request_lsp<R>(
 4741        &mut self,
 4742        buffer: Entity<Buffer>,
 4743        server: LanguageServerToQuery,
 4744        request: R,
 4745        cx: &mut Context<Self>,
 4746    ) -> Task<Result<R::Response>>
 4747    where
 4748        R: LspCommand,
 4749        <R::LspRequest as lsp::request::Request>::Result: Send,
 4750        <R::LspRequest as lsp::request::Request>::Params: Send,
 4751    {
 4752        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4753            return self.send_lsp_proto_request(
 4754                buffer,
 4755                upstream_client,
 4756                upstream_project_id,
 4757                request,
 4758                cx,
 4759            );
 4760        }
 4761
 4762        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4763            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4764                local
 4765                    .language_servers_for_buffer(buffer, cx)
 4766                    .find(|(_, server)| {
 4767                        request.check_capabilities(server.adapter_server_capabilities())
 4768                    })
 4769                    .map(|(_, server)| server.clone())
 4770            }),
 4771            LanguageServerToQuery::Other(id) => self
 4772                .language_server_for_local_buffer(buffer, id, cx)
 4773                .and_then(|(_, server)| {
 4774                    request
 4775                        .check_capabilities(server.adapter_server_capabilities())
 4776                        .then(|| Arc::clone(server))
 4777                }),
 4778        }) else {
 4779            return Task::ready(Ok(Default::default()));
 4780        };
 4781
 4782        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4783
 4784        let Some(file) = file else {
 4785            return Task::ready(Ok(Default::default()));
 4786        };
 4787
 4788        let lsp_params = match request.to_lsp_params_or_response(
 4789            &file.abs_path(cx),
 4790            buffer.read(cx),
 4791            &language_server,
 4792            cx,
 4793        ) {
 4794            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4795            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4796            Err(err) => {
 4797                let message = format!(
 4798                    "{} via {} failed: {}",
 4799                    request.display_name(),
 4800                    language_server.name(),
 4801                    err
 4802                );
 4803                // rust-analyzer likes to error with this when its still loading up
 4804                if !message.ends_with("content modified") {
 4805                    log::warn!("{message}");
 4806                }
 4807                return Task::ready(Err(anyhow!(message)));
 4808            }
 4809        };
 4810
 4811        let status = request.status();
 4812        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4813            return Task::ready(Ok(Default::default()));
 4814        }
 4815        cx.spawn(async move |this, cx| {
 4816            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4817
 4818            let id = lsp_request.id();
 4819            let _cleanup = if status.is_some() {
 4820                cx.update(|cx| {
 4821                    this.update(cx, |this, cx| {
 4822                        this.on_lsp_work_start(
 4823                            language_server.server_id(),
 4824                            ProgressToken::Number(id),
 4825                            LanguageServerProgress {
 4826                                is_disk_based_diagnostics_progress: false,
 4827                                is_cancellable: false,
 4828                                title: None,
 4829                                message: status.clone(),
 4830                                percentage: None,
 4831                                last_update_at: cx.background_executor().now(),
 4832                            },
 4833                            cx,
 4834                        );
 4835                    })
 4836                })
 4837                .log_err();
 4838
 4839                Some(defer(|| {
 4840                    cx.update(|cx| {
 4841                        this.update(cx, |this, cx| {
 4842                            this.on_lsp_work_end(
 4843                                language_server.server_id(),
 4844                                ProgressToken::Number(id),
 4845                                cx,
 4846                            );
 4847                        })
 4848                    })
 4849                    .log_err();
 4850                }))
 4851            } else {
 4852                None
 4853            };
 4854
 4855            let result = lsp_request.await.into_response();
 4856
 4857            let response = result.map_err(|err| {
 4858                let message = format!(
 4859                    "{} via {} failed: {}",
 4860                    request.display_name(),
 4861                    language_server.name(),
 4862                    err
 4863                );
 4864                // rust-analyzer likes to error with this when its still loading up
 4865                if !message.ends_with("content modified") {
 4866                    log::warn!("{message}");
 4867                }
 4868                anyhow::anyhow!(message)
 4869            })?;
 4870
 4871            request
 4872                .response_from_lsp(
 4873                    response,
 4874                    this.upgrade().context("no app context")?,
 4875                    buffer,
 4876                    language_server.server_id(),
 4877                    cx.clone(),
 4878                )
 4879                .await
 4880        })
 4881    }
 4882
 4883    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4884        let mut language_formatters_to_check = Vec::new();
 4885        for buffer in self.buffer_store.read(cx).buffers() {
 4886            let buffer = buffer.read(cx);
 4887            let buffer_file = File::from_dyn(buffer.file());
 4888            let buffer_language = buffer.language();
 4889            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4890            if buffer_language.is_some() {
 4891                language_formatters_to_check.push((
 4892                    buffer_file.map(|f| f.worktree_id(cx)),
 4893                    settings.into_owned(),
 4894                ));
 4895            }
 4896        }
 4897
 4898        self.request_workspace_config_refresh();
 4899
 4900        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4901            prettier_store.update(cx, |prettier_store, cx| {
 4902                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4903            })
 4904        }
 4905
 4906        cx.notify();
 4907    }
 4908
 4909    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4910        let buffer_store = self.buffer_store.clone();
 4911        let Some(local) = self.as_local_mut() else {
 4912            return;
 4913        };
 4914        let mut adapters = BTreeMap::default();
 4915        let get_adapter = {
 4916            let languages = local.languages.clone();
 4917            let environment = local.environment.clone();
 4918            let weak = local.weak.clone();
 4919            let worktree_store = local.worktree_store.clone();
 4920            let http_client = local.http_client.clone();
 4921            let fs = local.fs.clone();
 4922            move |worktree_id, cx: &mut App| {
 4923                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4924                Some(LocalLspAdapterDelegate::new(
 4925                    languages.clone(),
 4926                    &environment,
 4927                    weak.clone(),
 4928                    &worktree,
 4929                    http_client.clone(),
 4930                    fs.clone(),
 4931                    cx,
 4932                ))
 4933            }
 4934        };
 4935
 4936        let mut messages_to_report = Vec::new();
 4937        let (new_tree, to_stop) = {
 4938            let mut rebase = local.lsp_tree.rebase();
 4939            let buffers = buffer_store
 4940                .read(cx)
 4941                .buffers()
 4942                .filter_map(|buffer| {
 4943                    let raw_buffer = buffer.read(cx);
 4944                    if !local
 4945                        .registered_buffers
 4946                        .contains_key(&raw_buffer.remote_id())
 4947                    {
 4948                        return None;
 4949                    }
 4950                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4951                    let language = raw_buffer.language().cloned()?;
 4952                    Some((file, language, raw_buffer.remote_id()))
 4953                })
 4954                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4955            for (file, language, buffer_id) in buffers {
 4956                let worktree_id = file.worktree_id(cx);
 4957                let Some(worktree) = local
 4958                    .worktree_store
 4959                    .read(cx)
 4960                    .worktree_for_id(worktree_id, cx)
 4961                else {
 4962                    continue;
 4963                };
 4964
 4965                if let Some((_, apply)) = local.reuse_existing_language_server(
 4966                    rebase.server_tree(),
 4967                    &worktree,
 4968                    &language.name(),
 4969                    cx,
 4970                ) {
 4971                    (apply)(rebase.server_tree());
 4972                } else if let Some(lsp_delegate) = adapters
 4973                    .entry(worktree_id)
 4974                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4975                    .clone()
 4976                {
 4977                    let delegate =
 4978                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4979                    let path = file
 4980                        .path()
 4981                        .parent()
 4982                        .map(Arc::from)
 4983                        .unwrap_or_else(|| file.path().clone());
 4984                    let worktree_path = ProjectPath { worktree_id, path };
 4985                    let abs_path = file.abs_path(cx);
 4986                    let nodes = rebase
 4987                        .walk(
 4988                            worktree_path,
 4989                            language.name(),
 4990                            language.manifest(),
 4991                            delegate.clone(),
 4992                            cx,
 4993                        )
 4994                        .collect::<Vec<_>>();
 4995                    for node in nodes {
 4996                        let server_id = node.server_id_or_init(|disposition| {
 4997                            let path = &disposition.path;
 4998                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4999                            let key = LanguageServerSeed {
 5000                                worktree_id,
 5001                                name: disposition.server_name.clone(),
 5002                                settings: disposition.settings.clone(),
 5003                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5004                                    path.worktree_id,
 5005                                    &path.path,
 5006                                    language.name(),
 5007                                ),
 5008                            };
 5009                            local.language_server_ids.remove(&key);
 5010
 5011                            let server_id = local.get_or_insert_language_server(
 5012                                &worktree,
 5013                                lsp_delegate.clone(),
 5014                                disposition,
 5015                                &language.name(),
 5016                                cx,
 5017                            );
 5018                            if let Some(state) = local.language_servers.get(&server_id)
 5019                                && let Ok(uri) = uri
 5020                            {
 5021                                state.add_workspace_folder(uri);
 5022                            };
 5023                            server_id
 5024                        });
 5025
 5026                        if let Some(language_server_id) = server_id {
 5027                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5028                                language_server_id,
 5029                                name: node.name(),
 5030                                message:
 5031                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5032                                        proto::RegisteredForBuffer {
 5033                                            buffer_abs_path: abs_path
 5034                                                .to_string_lossy()
 5035                                                .into_owned(),
 5036                                            buffer_id: buffer_id.to_proto(),
 5037                                        },
 5038                                    ),
 5039                            });
 5040                        }
 5041                    }
 5042                } else {
 5043                    continue;
 5044                }
 5045            }
 5046            rebase.finish()
 5047        };
 5048        for message in messages_to_report {
 5049            cx.emit(message);
 5050        }
 5051        local.lsp_tree = new_tree;
 5052        for (id, _) in to_stop {
 5053            self.stop_local_language_server(id, cx).detach();
 5054        }
 5055    }
 5056
 5057    pub fn apply_code_action(
 5058        &self,
 5059        buffer_handle: Entity<Buffer>,
 5060        mut action: CodeAction,
 5061        push_to_history: bool,
 5062        cx: &mut Context<Self>,
 5063    ) -> Task<Result<ProjectTransaction>> {
 5064        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5065            let request = proto::ApplyCodeAction {
 5066                project_id,
 5067                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5068                action: Some(Self::serialize_code_action(&action)),
 5069            };
 5070            let buffer_store = self.buffer_store();
 5071            cx.spawn(async move |_, cx| {
 5072                let response = upstream_client
 5073                    .request(request)
 5074                    .await?
 5075                    .transaction
 5076                    .context("missing transaction")?;
 5077
 5078                buffer_store
 5079                    .update(cx, |buffer_store, cx| {
 5080                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5081                    })
 5082                    .await
 5083            })
 5084        } else if self.mode.is_local() {
 5085            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 5086                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5087                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 5088            }) else {
 5089                return Task::ready(Ok(ProjectTransaction::default()));
 5090            };
 5091            cx.spawn(async move |this,  cx| {
 5092                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 5093                    .await
 5094                    .context("resolving a code action")?;
 5095                if let Some(edit) = action.lsp_action.edit()
 5096                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5097                        return LocalLspStore::deserialize_workspace_edit(
 5098                            this.upgrade().context("no app present")?,
 5099                            edit.clone(),
 5100                            push_to_history,
 5101
 5102                            lang_server.clone(),
 5103                            cx,
 5104                        )
 5105                        .await;
 5106                    }
 5107
 5108                if let Some(command) = action.lsp_action.command() {
 5109                    let server_capabilities = lang_server.capabilities();
 5110                    let available_commands = server_capabilities
 5111                        .execute_command_provider
 5112                        .as_ref()
 5113                        .map(|options| options.commands.as_slice())
 5114                        .unwrap_or_default();
 5115                    if available_commands.contains(&command.command) {
 5116                        this.update(cx, |this, _| {
 5117                            this.as_local_mut()
 5118                                .unwrap()
 5119                                .last_workspace_edits_by_language_server
 5120                                .remove(&lang_server.server_id());
 5121                        })?;
 5122
 5123                        let _result = lang_server
 5124                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5125                                command: command.command.clone(),
 5126                                arguments: command.arguments.clone().unwrap_or_default(),
 5127                                ..lsp::ExecuteCommandParams::default()
 5128                            })
 5129                            .await.into_response()
 5130                            .context("execute command")?;
 5131
 5132                        return this.update(cx, |this, _| {
 5133                            this.as_local_mut()
 5134                                .unwrap()
 5135                                .last_workspace_edits_by_language_server
 5136                                .remove(&lang_server.server_id())
 5137                                .unwrap_or_default()
 5138                        });
 5139                    } else {
 5140                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5141                    }
 5142                }
 5143
 5144                Ok(ProjectTransaction::default())
 5145            })
 5146        } else {
 5147            Task::ready(Err(anyhow!("no upstream client and not local")))
 5148        }
 5149    }
 5150
 5151    pub fn apply_code_action_kind(
 5152        &mut self,
 5153        buffers: HashSet<Entity<Buffer>>,
 5154        kind: CodeActionKind,
 5155        push_to_history: bool,
 5156        cx: &mut Context<Self>,
 5157    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5158        if self.as_local().is_some() {
 5159            cx.spawn(async move |lsp_store, cx| {
 5160                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5161                let result = LocalLspStore::execute_code_action_kind_locally(
 5162                    lsp_store.clone(),
 5163                    buffers,
 5164                    kind,
 5165                    push_to_history,
 5166                    cx,
 5167                )
 5168                .await;
 5169                lsp_store.update(cx, |lsp_store, _| {
 5170                    lsp_store.update_last_formatting_failure(&result);
 5171                })?;
 5172                result
 5173            })
 5174        } else if let Some((client, project_id)) = self.upstream_client() {
 5175            let buffer_store = self.buffer_store();
 5176            cx.spawn(async move |lsp_store, cx| {
 5177                let result = client
 5178                    .request(proto::ApplyCodeActionKind {
 5179                        project_id,
 5180                        kind: kind.as_str().to_owned(),
 5181                        buffer_ids: buffers
 5182                            .iter()
 5183                            .map(|buffer| {
 5184                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5185                            })
 5186                            .collect(),
 5187                    })
 5188                    .await
 5189                    .and_then(|result| result.transaction.context("missing transaction"));
 5190                lsp_store.update(cx, |lsp_store, _| {
 5191                    lsp_store.update_last_formatting_failure(&result);
 5192                })?;
 5193
 5194                let transaction_response = result?;
 5195                buffer_store
 5196                    .update(cx, |buffer_store, cx| {
 5197                        buffer_store.deserialize_project_transaction(
 5198                            transaction_response,
 5199                            push_to_history,
 5200                            cx,
 5201                        )
 5202                    })
 5203                    .await
 5204            })
 5205        } else {
 5206            Task::ready(Ok(ProjectTransaction::default()))
 5207        }
 5208    }
 5209
 5210    pub fn resolved_hint(
 5211        &mut self,
 5212        buffer_id: BufferId,
 5213        id: InlayId,
 5214        cx: &mut Context<Self>,
 5215    ) -> Option<ResolvedHint> {
 5216        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5217
 5218        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5219        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5220        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5221        let (server_id, resolve_data) = match &hint.resolve_state {
 5222            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5223            ResolveState::Resolving => {
 5224                return Some(ResolvedHint::Resolving(
 5225                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5226                ));
 5227            }
 5228            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5229        };
 5230
 5231        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5232        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5233        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5234            id,
 5235            cx.spawn(async move |lsp_store, cx| {
 5236                let resolved_hint = resolve_task.await;
 5237                lsp_store
 5238                    .update(cx, |lsp_store, _| {
 5239                        if let Some(old_inlay_hint) = lsp_store
 5240                            .lsp_data
 5241                            .get_mut(&buffer_id)
 5242                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5243                        {
 5244                            match resolved_hint {
 5245                                Ok(resolved_hint) => {
 5246                                    *old_inlay_hint = resolved_hint;
 5247                                }
 5248                                Err(e) => {
 5249                                    old_inlay_hint.resolve_state =
 5250                                        ResolveState::CanResolve(server_id, resolve_data);
 5251                                    log::error!("Inlay hint resolve failed: {e:#}");
 5252                                }
 5253                            }
 5254                        }
 5255                    })
 5256                    .ok();
 5257            })
 5258            .shared(),
 5259        );
 5260        debug_assert!(
 5261            previous_task.is_none(),
 5262            "Did not change hint's resolve state after spawning its resolve"
 5263        );
 5264        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5265        None
 5266    }
 5267
 5268    fn resolve_inlay_hint(
 5269        &self,
 5270        mut hint: InlayHint,
 5271        buffer: Entity<Buffer>,
 5272        server_id: LanguageServerId,
 5273        cx: &mut Context<Self>,
 5274    ) -> Task<anyhow::Result<InlayHint>> {
 5275        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5276            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5277            {
 5278                hint.resolve_state = ResolveState::Resolved;
 5279                return Task::ready(Ok(hint));
 5280            }
 5281            let request = proto::ResolveInlayHint {
 5282                project_id,
 5283                buffer_id: buffer.read(cx).remote_id().into(),
 5284                language_server_id: server_id.0 as u64,
 5285                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5286            };
 5287            cx.background_spawn(async move {
 5288                let response = upstream_client
 5289                    .request(request)
 5290                    .await
 5291                    .context("inlay hints proto request")?;
 5292                match response.hint {
 5293                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5294                        .context("inlay hints proto resolve response conversion"),
 5295                    None => Ok(hint),
 5296                }
 5297            })
 5298        } else {
 5299            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5300                self.language_server_for_local_buffer(buffer, server_id, cx)
 5301                    .map(|(_, server)| server.clone())
 5302            }) else {
 5303                return Task::ready(Ok(hint));
 5304            };
 5305            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5306                return Task::ready(Ok(hint));
 5307            }
 5308            let buffer_snapshot = buffer.read(cx).snapshot();
 5309            cx.spawn(async move |_, cx| {
 5310                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5311                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5312                );
 5313                let resolved_hint = resolve_task
 5314                    .await
 5315                    .into_response()
 5316                    .context("inlay hint resolve LSP request")?;
 5317                let resolved_hint = InlayHints::lsp_to_project_hint(
 5318                    resolved_hint,
 5319                    &buffer,
 5320                    server_id,
 5321                    ResolveState::Resolved,
 5322                    false,
 5323                    cx,
 5324                )
 5325                .await?;
 5326                Ok(resolved_hint)
 5327            })
 5328        }
 5329    }
 5330
 5331    pub fn resolve_color_presentation(
 5332        &mut self,
 5333        mut color: DocumentColor,
 5334        buffer: Entity<Buffer>,
 5335        server_id: LanguageServerId,
 5336        cx: &mut Context<Self>,
 5337    ) -> Task<Result<DocumentColor>> {
 5338        if color.resolved {
 5339            return Task::ready(Ok(color));
 5340        }
 5341
 5342        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5343            let start = color.lsp_range.start;
 5344            let end = color.lsp_range.end;
 5345            let request = proto::GetColorPresentation {
 5346                project_id,
 5347                server_id: server_id.to_proto(),
 5348                buffer_id: buffer.read(cx).remote_id().into(),
 5349                color: Some(proto::ColorInformation {
 5350                    red: color.color.red,
 5351                    green: color.color.green,
 5352                    blue: color.color.blue,
 5353                    alpha: color.color.alpha,
 5354                    lsp_range_start: Some(proto::PointUtf16 {
 5355                        row: start.line,
 5356                        column: start.character,
 5357                    }),
 5358                    lsp_range_end: Some(proto::PointUtf16 {
 5359                        row: end.line,
 5360                        column: end.character,
 5361                    }),
 5362                }),
 5363            };
 5364            cx.background_spawn(async move {
 5365                let response = upstream_client
 5366                    .request(request)
 5367                    .await
 5368                    .context("color presentation proto request")?;
 5369                color.resolved = true;
 5370                color.color_presentations = response
 5371                    .presentations
 5372                    .into_iter()
 5373                    .map(|presentation| ColorPresentation {
 5374                        label: SharedString::from(presentation.label),
 5375                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5376                        additional_text_edits: presentation
 5377                            .additional_text_edits
 5378                            .into_iter()
 5379                            .filter_map(deserialize_lsp_edit)
 5380                            .collect(),
 5381                    })
 5382                    .collect();
 5383                Ok(color)
 5384            })
 5385        } else {
 5386            let path = match buffer
 5387                .update(cx, |buffer, cx| {
 5388                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5389                })
 5390                .context("buffer with the missing path")
 5391            {
 5392                Ok(path) => path,
 5393                Err(e) => return Task::ready(Err(e)),
 5394            };
 5395            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5396                self.language_server_for_local_buffer(buffer, server_id, cx)
 5397                    .map(|(_, server)| server.clone())
 5398            }) else {
 5399                return Task::ready(Ok(color));
 5400            };
 5401            cx.background_spawn(async move {
 5402                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5403                    lsp::ColorPresentationParams {
 5404                        text_document: make_text_document_identifier(&path)?,
 5405                        color: color.color,
 5406                        range: color.lsp_range,
 5407                        work_done_progress_params: Default::default(),
 5408                        partial_result_params: Default::default(),
 5409                    },
 5410                );
 5411                color.color_presentations = resolve_task
 5412                    .await
 5413                    .into_response()
 5414                    .context("color presentation resolve LSP request")?
 5415                    .into_iter()
 5416                    .map(|presentation| ColorPresentation {
 5417                        label: SharedString::from(presentation.label),
 5418                        text_edit: presentation.text_edit,
 5419                        additional_text_edits: presentation
 5420                            .additional_text_edits
 5421                            .unwrap_or_default(),
 5422                    })
 5423                    .collect();
 5424                color.resolved = true;
 5425                Ok(color)
 5426            })
 5427        }
 5428    }
 5429
 5430    pub(crate) fn linked_edits(
 5431        &mut self,
 5432        buffer: &Entity<Buffer>,
 5433        position: Anchor,
 5434        cx: &mut Context<Self>,
 5435    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5436        let snapshot = buffer.read(cx).snapshot();
 5437        let scope = snapshot.language_scope_at(position);
 5438        let Some(server_id) = self
 5439            .as_local()
 5440            .and_then(|local| {
 5441                buffer.update(cx, |buffer, cx| {
 5442                    local
 5443                        .language_servers_for_buffer(buffer, cx)
 5444                        .filter(|(_, server)| {
 5445                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5446                        })
 5447                        .filter(|(adapter, _)| {
 5448                            scope
 5449                                .as_ref()
 5450                                .map(|scope| scope.language_allowed(&adapter.name))
 5451                                .unwrap_or(true)
 5452                        })
 5453                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5454                        .next()
 5455                })
 5456            })
 5457            .or_else(|| {
 5458                self.upstream_client()
 5459                    .is_some()
 5460                    .then_some(LanguageServerToQuery::FirstCapable)
 5461            })
 5462            .filter(|_| {
 5463                maybe!({
 5464                    let language = buffer.read(cx).language_at(position)?;
 5465                    Some(
 5466                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5467                            .linked_edits,
 5468                    )
 5469                }) == Some(true)
 5470            })
 5471        else {
 5472            return Task::ready(Ok(Vec::new()));
 5473        };
 5474
 5475        self.request_lsp(
 5476            buffer.clone(),
 5477            server_id,
 5478            LinkedEditingRange { position },
 5479            cx,
 5480        )
 5481    }
 5482
 5483    fn apply_on_type_formatting(
 5484        &mut self,
 5485        buffer: Entity<Buffer>,
 5486        position: Anchor,
 5487        trigger: String,
 5488        cx: &mut Context<Self>,
 5489    ) -> Task<Result<Option<Transaction>>> {
 5490        if let Some((client, project_id)) = self.upstream_client() {
 5491            if !self.check_if_capable_for_proto_request(
 5492                &buffer,
 5493                |capabilities| {
 5494                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5495                },
 5496                cx,
 5497            ) {
 5498                return Task::ready(Ok(None));
 5499            }
 5500            let request = proto::OnTypeFormatting {
 5501                project_id,
 5502                buffer_id: buffer.read(cx).remote_id().into(),
 5503                position: Some(serialize_anchor(&position)),
 5504                trigger,
 5505                version: serialize_version(&buffer.read(cx).version()),
 5506            };
 5507            cx.background_spawn(async move {
 5508                client
 5509                    .request(request)
 5510                    .await?
 5511                    .transaction
 5512                    .map(language::proto::deserialize_transaction)
 5513                    .transpose()
 5514            })
 5515        } else if let Some(local) = self.as_local_mut() {
 5516            let buffer_id = buffer.read(cx).remote_id();
 5517            local.buffers_being_formatted.insert(buffer_id);
 5518            cx.spawn(async move |this, cx| {
 5519                let _cleanup = defer({
 5520                    let this = this.clone();
 5521                    let mut cx = cx.clone();
 5522                    move || {
 5523                        this.update(&mut cx, |this, _| {
 5524                            if let Some(local) = this.as_local_mut() {
 5525                                local.buffers_being_formatted.remove(&buffer_id);
 5526                            }
 5527                        })
 5528                        .ok();
 5529                    }
 5530                });
 5531
 5532                buffer
 5533                    .update(cx, |buffer, _| {
 5534                        buffer.wait_for_edits(Some(position.timestamp))
 5535                    })
 5536                    .await?;
 5537                this.update(cx, |this, cx| {
 5538                    let position = position.to_point_utf16(buffer.read(cx));
 5539                    this.on_type_format(buffer, position, trigger, false, cx)
 5540                })?
 5541                .await
 5542            })
 5543        } else {
 5544            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5545        }
 5546    }
 5547
 5548    pub fn on_type_format<T: ToPointUtf16>(
 5549        &mut self,
 5550        buffer: Entity<Buffer>,
 5551        position: T,
 5552        trigger: String,
 5553        push_to_history: bool,
 5554        cx: &mut Context<Self>,
 5555    ) -> Task<Result<Option<Transaction>>> {
 5556        let position = position.to_point_utf16(buffer.read(cx));
 5557        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5558    }
 5559
 5560    fn on_type_format_impl(
 5561        &mut self,
 5562        buffer: Entity<Buffer>,
 5563        position: PointUtf16,
 5564        trigger: String,
 5565        push_to_history: bool,
 5566        cx: &mut Context<Self>,
 5567    ) -> Task<Result<Option<Transaction>>> {
 5568        let options = buffer.update(cx, |buffer, cx| {
 5569            lsp_command::lsp_formatting_options(
 5570                language_settings(
 5571                    buffer.language_at(position).map(|l| l.name()),
 5572                    buffer.file(),
 5573                    cx,
 5574                )
 5575                .as_ref(),
 5576            )
 5577        });
 5578
 5579        cx.spawn(async move |this, cx| {
 5580            if let Some(waiter) =
 5581                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5582            {
 5583                waiter.await?;
 5584            }
 5585            cx.update(|cx| {
 5586                this.update(cx, |this, cx| {
 5587                    this.request_lsp(
 5588                        buffer.clone(),
 5589                        LanguageServerToQuery::FirstCapable,
 5590                        OnTypeFormatting {
 5591                            position,
 5592                            trigger,
 5593                            options,
 5594                            push_to_history,
 5595                        },
 5596                        cx,
 5597                    )
 5598                })
 5599            })?
 5600            .await
 5601        })
 5602    }
 5603
 5604    pub fn definitions(
 5605        &mut self,
 5606        buffer: &Entity<Buffer>,
 5607        position: PointUtf16,
 5608        cx: &mut Context<Self>,
 5609    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5610        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5611            let request = GetDefinitions { position };
 5612            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5613                return Task::ready(Ok(None));
 5614            }
 5615            let request_task = upstream_client.request_lsp(
 5616                project_id,
 5617                None,
 5618                LSP_REQUEST_TIMEOUT,
 5619                cx.background_executor().clone(),
 5620                request.to_proto(project_id, buffer.read(cx)),
 5621            );
 5622            let buffer = buffer.clone();
 5623            cx.spawn(async move |weak_lsp_store, cx| {
 5624                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5625                    return Ok(None);
 5626                };
 5627                let Some(responses) = request_task.await? else {
 5628                    return Ok(None);
 5629                };
 5630                let actions = join_all(responses.payload.into_iter().map(|response| {
 5631                    GetDefinitions { position }.response_from_proto(
 5632                        response.response,
 5633                        lsp_store.clone(),
 5634                        buffer.clone(),
 5635                        cx.clone(),
 5636                    )
 5637                }))
 5638                .await;
 5639
 5640                Ok(Some(
 5641                    actions
 5642                        .into_iter()
 5643                        .collect::<Result<Vec<Vec<_>>>>()?
 5644                        .into_iter()
 5645                        .flatten()
 5646                        .dedup()
 5647                        .collect(),
 5648                ))
 5649            })
 5650        } else {
 5651            let definitions_task = self.request_multiple_lsp_locally(
 5652                buffer,
 5653                Some(position),
 5654                GetDefinitions { position },
 5655                cx,
 5656            );
 5657            cx.background_spawn(async move {
 5658                Ok(Some(
 5659                    definitions_task
 5660                        .await
 5661                        .into_iter()
 5662                        .flat_map(|(_, definitions)| definitions)
 5663                        .dedup()
 5664                        .collect(),
 5665                ))
 5666            })
 5667        }
 5668    }
 5669
 5670    pub fn declarations(
 5671        &mut self,
 5672        buffer: &Entity<Buffer>,
 5673        position: PointUtf16,
 5674        cx: &mut Context<Self>,
 5675    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5676        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5677            let request = GetDeclarations { position };
 5678            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5679                return Task::ready(Ok(None));
 5680            }
 5681            let request_task = upstream_client.request_lsp(
 5682                project_id,
 5683                None,
 5684                LSP_REQUEST_TIMEOUT,
 5685                cx.background_executor().clone(),
 5686                request.to_proto(project_id, buffer.read(cx)),
 5687            );
 5688            let buffer = buffer.clone();
 5689            cx.spawn(async move |weak_lsp_store, cx| {
 5690                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5691                    return Ok(None);
 5692                };
 5693                let Some(responses) = request_task.await? else {
 5694                    return Ok(None);
 5695                };
 5696                let actions = join_all(responses.payload.into_iter().map(|response| {
 5697                    GetDeclarations { position }.response_from_proto(
 5698                        response.response,
 5699                        lsp_store.clone(),
 5700                        buffer.clone(),
 5701                        cx.clone(),
 5702                    )
 5703                }))
 5704                .await;
 5705
 5706                Ok(Some(
 5707                    actions
 5708                        .into_iter()
 5709                        .collect::<Result<Vec<Vec<_>>>>()?
 5710                        .into_iter()
 5711                        .flatten()
 5712                        .dedup()
 5713                        .collect(),
 5714                ))
 5715            })
 5716        } else {
 5717            let declarations_task = self.request_multiple_lsp_locally(
 5718                buffer,
 5719                Some(position),
 5720                GetDeclarations { position },
 5721                cx,
 5722            );
 5723            cx.background_spawn(async move {
 5724                Ok(Some(
 5725                    declarations_task
 5726                        .await
 5727                        .into_iter()
 5728                        .flat_map(|(_, declarations)| declarations)
 5729                        .dedup()
 5730                        .collect(),
 5731                ))
 5732            })
 5733        }
 5734    }
 5735
 5736    pub fn type_definitions(
 5737        &mut self,
 5738        buffer: &Entity<Buffer>,
 5739        position: PointUtf16,
 5740        cx: &mut Context<Self>,
 5741    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5742        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5743            let request = GetTypeDefinitions { position };
 5744            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5745                return Task::ready(Ok(None));
 5746            }
 5747            let request_task = upstream_client.request_lsp(
 5748                project_id,
 5749                None,
 5750                LSP_REQUEST_TIMEOUT,
 5751                cx.background_executor().clone(),
 5752                request.to_proto(project_id, buffer.read(cx)),
 5753            );
 5754            let buffer = buffer.clone();
 5755            cx.spawn(async move |weak_lsp_store, cx| {
 5756                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5757                    return Ok(None);
 5758                };
 5759                let Some(responses) = request_task.await? else {
 5760                    return Ok(None);
 5761                };
 5762                let actions = join_all(responses.payload.into_iter().map(|response| {
 5763                    GetTypeDefinitions { position }.response_from_proto(
 5764                        response.response,
 5765                        lsp_store.clone(),
 5766                        buffer.clone(),
 5767                        cx.clone(),
 5768                    )
 5769                }))
 5770                .await;
 5771
 5772                Ok(Some(
 5773                    actions
 5774                        .into_iter()
 5775                        .collect::<Result<Vec<Vec<_>>>>()?
 5776                        .into_iter()
 5777                        .flatten()
 5778                        .dedup()
 5779                        .collect(),
 5780                ))
 5781            })
 5782        } else {
 5783            let type_definitions_task = self.request_multiple_lsp_locally(
 5784                buffer,
 5785                Some(position),
 5786                GetTypeDefinitions { position },
 5787                cx,
 5788            );
 5789            cx.background_spawn(async move {
 5790                Ok(Some(
 5791                    type_definitions_task
 5792                        .await
 5793                        .into_iter()
 5794                        .flat_map(|(_, type_definitions)| type_definitions)
 5795                        .dedup()
 5796                        .collect(),
 5797                ))
 5798            })
 5799        }
 5800    }
 5801
 5802    pub fn implementations(
 5803        &mut self,
 5804        buffer: &Entity<Buffer>,
 5805        position: PointUtf16,
 5806        cx: &mut Context<Self>,
 5807    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5808        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5809            let request = GetImplementations { position };
 5810            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5811                return Task::ready(Ok(None));
 5812            }
 5813            let request_task = upstream_client.request_lsp(
 5814                project_id,
 5815                None,
 5816                LSP_REQUEST_TIMEOUT,
 5817                cx.background_executor().clone(),
 5818                request.to_proto(project_id, buffer.read(cx)),
 5819            );
 5820            let buffer = buffer.clone();
 5821            cx.spawn(async move |weak_lsp_store, cx| {
 5822                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5823                    return Ok(None);
 5824                };
 5825                let Some(responses) = request_task.await? else {
 5826                    return Ok(None);
 5827                };
 5828                let actions = join_all(responses.payload.into_iter().map(|response| {
 5829                    GetImplementations { position }.response_from_proto(
 5830                        response.response,
 5831                        lsp_store.clone(),
 5832                        buffer.clone(),
 5833                        cx.clone(),
 5834                    )
 5835                }))
 5836                .await;
 5837
 5838                Ok(Some(
 5839                    actions
 5840                        .into_iter()
 5841                        .collect::<Result<Vec<Vec<_>>>>()?
 5842                        .into_iter()
 5843                        .flatten()
 5844                        .dedup()
 5845                        .collect(),
 5846                ))
 5847            })
 5848        } else {
 5849            let implementations_task = self.request_multiple_lsp_locally(
 5850                buffer,
 5851                Some(position),
 5852                GetImplementations { position },
 5853                cx,
 5854            );
 5855            cx.background_spawn(async move {
 5856                Ok(Some(
 5857                    implementations_task
 5858                        .await
 5859                        .into_iter()
 5860                        .flat_map(|(_, implementations)| implementations)
 5861                        .dedup()
 5862                        .collect(),
 5863                ))
 5864            })
 5865        }
 5866    }
 5867
 5868    pub fn references(
 5869        &mut self,
 5870        buffer: &Entity<Buffer>,
 5871        position: PointUtf16,
 5872        cx: &mut Context<Self>,
 5873    ) -> Task<Result<Option<Vec<Location>>>> {
 5874        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5875            let request = GetReferences { position };
 5876            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5877                return Task::ready(Ok(None));
 5878            }
 5879
 5880            let request_task = upstream_client.request_lsp(
 5881                project_id,
 5882                None,
 5883                LSP_REQUEST_TIMEOUT,
 5884                cx.background_executor().clone(),
 5885                request.to_proto(project_id, buffer.read(cx)),
 5886            );
 5887            let buffer = buffer.clone();
 5888            cx.spawn(async move |weak_lsp_store, cx| {
 5889                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5890                    return Ok(None);
 5891                };
 5892                let Some(responses) = request_task.await? else {
 5893                    return Ok(None);
 5894                };
 5895
 5896                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5897                    GetReferences { position }.response_from_proto(
 5898                        lsp_response.response,
 5899                        lsp_store.clone(),
 5900                        buffer.clone(),
 5901                        cx.clone(),
 5902                    )
 5903                }))
 5904                .await
 5905                .into_iter()
 5906                .collect::<Result<Vec<Vec<_>>>>()?
 5907                .into_iter()
 5908                .flatten()
 5909                .dedup()
 5910                .collect();
 5911                Ok(Some(locations))
 5912            })
 5913        } else {
 5914            let references_task = self.request_multiple_lsp_locally(
 5915                buffer,
 5916                Some(position),
 5917                GetReferences { position },
 5918                cx,
 5919            );
 5920            cx.background_spawn(async move {
 5921                Ok(Some(
 5922                    references_task
 5923                        .await
 5924                        .into_iter()
 5925                        .flat_map(|(_, references)| references)
 5926                        .dedup()
 5927                        .collect(),
 5928                ))
 5929            })
 5930        }
 5931    }
 5932
 5933    pub fn code_actions(
 5934        &mut self,
 5935        buffer: &Entity<Buffer>,
 5936        range: Range<Anchor>,
 5937        kinds: Option<Vec<CodeActionKind>>,
 5938        cx: &mut Context<Self>,
 5939    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5940        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5941            let request = GetCodeActions {
 5942                range: range.clone(),
 5943                kinds: kinds.clone(),
 5944            };
 5945            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5946                return Task::ready(Ok(None));
 5947            }
 5948            let request_task = upstream_client.request_lsp(
 5949                project_id,
 5950                None,
 5951                LSP_REQUEST_TIMEOUT,
 5952                cx.background_executor().clone(),
 5953                request.to_proto(project_id, buffer.read(cx)),
 5954            );
 5955            let buffer = buffer.clone();
 5956            cx.spawn(async move |weak_lsp_store, cx| {
 5957                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5958                    return Ok(None);
 5959                };
 5960                let Some(responses) = request_task.await? else {
 5961                    return Ok(None);
 5962                };
 5963                let actions = join_all(responses.payload.into_iter().map(|response| {
 5964                    GetCodeActions {
 5965                        range: range.clone(),
 5966                        kinds: kinds.clone(),
 5967                    }
 5968                    .response_from_proto(
 5969                        response.response,
 5970                        lsp_store.clone(),
 5971                        buffer.clone(),
 5972                        cx.clone(),
 5973                    )
 5974                }))
 5975                .await;
 5976
 5977                Ok(Some(
 5978                    actions
 5979                        .into_iter()
 5980                        .collect::<Result<Vec<Vec<_>>>>()?
 5981                        .into_iter()
 5982                        .flatten()
 5983                        .collect(),
 5984                ))
 5985            })
 5986        } else {
 5987            let all_actions_task = self.request_multiple_lsp_locally(
 5988                buffer,
 5989                Some(range.start),
 5990                GetCodeActions { range, kinds },
 5991                cx,
 5992            );
 5993            cx.background_spawn(async move {
 5994                Ok(Some(
 5995                    all_actions_task
 5996                        .await
 5997                        .into_iter()
 5998                        .flat_map(|(_, actions)| actions)
 5999                        .collect(),
 6000                ))
 6001            })
 6002        }
 6003    }
 6004
 6005    pub fn code_lens_actions(
 6006        &mut self,
 6007        buffer: &Entity<Buffer>,
 6008        cx: &mut Context<Self>,
 6009    ) -> CodeLensTask {
 6010        let version_queried_for = buffer.read(cx).version();
 6011        let buffer_id = buffer.read(cx).remote_id();
 6012        let existing_servers = self.as_local().map(|local| {
 6013            local
 6014                .buffers_opened_in_servers
 6015                .get(&buffer_id)
 6016                .cloned()
 6017                .unwrap_or_default()
 6018        });
 6019
 6020        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 6021            if let Some(cached_lens) = &lsp_data.code_lens {
 6022                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 6023                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 6024                        existing_servers != cached_lens.lens.keys().copied().collect()
 6025                    });
 6026                    if !has_different_servers {
 6027                        return Task::ready(Ok(Some(
 6028                            cached_lens.lens.values().flatten().cloned().collect(),
 6029                        )))
 6030                        .shared();
 6031                    }
 6032                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 6033                    if !version_queried_for.changed_since(updating_for) {
 6034                        return running_update.clone();
 6035                    }
 6036                }
 6037            }
 6038        }
 6039
 6040        let lens_lsp_data = self
 6041            .latest_lsp_data(buffer, cx)
 6042            .code_lens
 6043            .get_or_insert_default();
 6044        let buffer = buffer.clone();
 6045        let query_version_queried_for = version_queried_for.clone();
 6046        let new_task = cx
 6047            .spawn(async move |lsp_store, cx| {
 6048                cx.background_executor()
 6049                    .timer(Duration::from_millis(30))
 6050                    .await;
 6051                let fetched_lens = lsp_store
 6052                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 6053                    .map_err(Arc::new)?
 6054                    .await
 6055                    .context("fetching code lens")
 6056                    .map_err(Arc::new);
 6057                let fetched_lens = match fetched_lens {
 6058                    Ok(fetched_lens) => fetched_lens,
 6059                    Err(e) => {
 6060                        lsp_store
 6061                            .update(cx, |lsp_store, _| {
 6062                                if let Some(lens_lsp_data) = lsp_store
 6063                                    .lsp_data
 6064                                    .get_mut(&buffer_id)
 6065                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 6066                                {
 6067                                    lens_lsp_data.update = None;
 6068                                }
 6069                            })
 6070                            .ok();
 6071                        return Err(e);
 6072                    }
 6073                };
 6074
 6075                lsp_store
 6076                    .update(cx, |lsp_store, _| {
 6077                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 6078                        let code_lens = lsp_data.code_lens.as_mut()?;
 6079                        if let Some(fetched_lens) = fetched_lens {
 6080                            if lsp_data.buffer_version == query_version_queried_for {
 6081                                code_lens.lens.extend(fetched_lens);
 6082                            } else if !lsp_data
 6083                                .buffer_version
 6084                                .changed_since(&query_version_queried_for)
 6085                            {
 6086                                lsp_data.buffer_version = query_version_queried_for;
 6087                                code_lens.lens = fetched_lens;
 6088                            }
 6089                        }
 6090                        code_lens.update = None;
 6091                        Some(code_lens.lens.values().flatten().cloned().collect())
 6092                    })
 6093                    .map_err(Arc::new)
 6094            })
 6095            .shared();
 6096        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 6097        new_task
 6098    }
 6099
 6100    fn fetch_code_lens(
 6101        &mut self,
 6102        buffer: &Entity<Buffer>,
 6103        cx: &mut Context<Self>,
 6104    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 6105        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6106            let request = GetCodeLens;
 6107            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6108                return Task::ready(Ok(None));
 6109            }
 6110            let request_task = upstream_client.request_lsp(
 6111                project_id,
 6112                None,
 6113                LSP_REQUEST_TIMEOUT,
 6114                cx.background_executor().clone(),
 6115                request.to_proto(project_id, buffer.read(cx)),
 6116            );
 6117            let buffer = buffer.clone();
 6118            cx.spawn(async move |weak_lsp_store, cx| {
 6119                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6120                    return Ok(None);
 6121                };
 6122                let Some(responses) = request_task.await? else {
 6123                    return Ok(None);
 6124                };
 6125
 6126                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 6127                    let lsp_store = lsp_store.clone();
 6128                    let buffer = buffer.clone();
 6129                    let cx = cx.clone();
 6130                    async move {
 6131                        (
 6132                            LanguageServerId::from_proto(response.server_id),
 6133                            GetCodeLens
 6134                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6135                                .await,
 6136                        )
 6137                    }
 6138                }))
 6139                .await;
 6140
 6141                let mut has_errors = false;
 6142                let code_lens_actions = code_lens_actions
 6143                    .into_iter()
 6144                    .filter_map(|(server_id, code_lens)| match code_lens {
 6145                        Ok(code_lens) => Some((server_id, code_lens)),
 6146                        Err(e) => {
 6147                            has_errors = true;
 6148                            log::error!("{e:#}");
 6149                            None
 6150                        }
 6151                    })
 6152                    .collect::<HashMap<_, _>>();
 6153                anyhow::ensure!(
 6154                    !has_errors || !code_lens_actions.is_empty(),
 6155                    "Failed to fetch code lens"
 6156                );
 6157                Ok(Some(code_lens_actions))
 6158            })
 6159        } else {
 6160            let code_lens_actions_task =
 6161                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 6162            cx.background_spawn(async move {
 6163                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 6164            })
 6165        }
 6166    }
 6167
 6168    #[inline(never)]
 6169    pub fn completions(
 6170        &self,
 6171        buffer: &Entity<Buffer>,
 6172        position: PointUtf16,
 6173        context: CompletionContext,
 6174        cx: &mut Context<Self>,
 6175    ) -> Task<Result<Vec<CompletionResponse>>> {
 6176        let language_registry = self.languages.clone();
 6177
 6178        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6179            let snapshot = buffer.read(cx).snapshot();
 6180            let offset = position.to_offset(&snapshot);
 6181            let scope = snapshot.language_scope_at(offset);
 6182            let capable_lsps = self.all_capable_for_proto_request(
 6183                buffer,
 6184                |server_name, capabilities| {
 6185                    capabilities.completion_provider.is_some()
 6186                        && scope
 6187                            .as_ref()
 6188                            .map(|scope| scope.language_allowed(server_name))
 6189                            .unwrap_or(true)
 6190                },
 6191                cx,
 6192            );
 6193            if capable_lsps.is_empty() {
 6194                return Task::ready(Ok(Vec::new()));
 6195            }
 6196
 6197            let language = buffer.read(cx).language().cloned();
 6198
 6199            // In the future, we should provide project guests with the names of LSP adapters,
 6200            // so that they can use the correct LSP adapter when computing labels. For now,
 6201            // guests just use the first LSP adapter associated with the buffer's language.
 6202            let lsp_adapter = language.as_ref().and_then(|language| {
 6203                language_registry
 6204                    .lsp_adapters(&language.name())
 6205                    .first()
 6206                    .cloned()
 6207            });
 6208
 6209            let buffer = buffer.clone();
 6210
 6211            cx.spawn(async move |this, cx| {
 6212                let requests = join_all(
 6213                    capable_lsps
 6214                        .into_iter()
 6215                        .map(|id| {
 6216                            let request = GetCompletions {
 6217                                position,
 6218                                context: context.clone(),
 6219                                server_id: Some(id),
 6220                            };
 6221                            let buffer = buffer.clone();
 6222                            let language = language.clone();
 6223                            let lsp_adapter = lsp_adapter.clone();
 6224                            let upstream_client = upstream_client.clone();
 6225                            let response = this
 6226                                .update(cx, |this, cx| {
 6227                                    this.send_lsp_proto_request(
 6228                                        buffer,
 6229                                        upstream_client,
 6230                                        project_id,
 6231                                        request,
 6232                                        cx,
 6233                                    )
 6234                                })
 6235                                .log_err();
 6236                            async move {
 6237                                let response = response?.await.log_err()?;
 6238
 6239                                let completions = populate_labels_for_completions(
 6240                                    response.completions,
 6241                                    language,
 6242                                    lsp_adapter,
 6243                                )
 6244                                .await;
 6245
 6246                                Some(CompletionResponse {
 6247                                    completions,
 6248                                    display_options: CompletionDisplayOptions::default(),
 6249                                    is_incomplete: response.is_incomplete,
 6250                                })
 6251                            }
 6252                        })
 6253                        .collect::<Vec<_>>(),
 6254                );
 6255                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6256            })
 6257        } else if let Some(local) = self.as_local() {
 6258            let snapshot = buffer.read(cx).snapshot();
 6259            let offset = position.to_offset(&snapshot);
 6260            let scope = snapshot.language_scope_at(offset);
 6261            let language = snapshot.language().cloned();
 6262            let completion_settings = language_settings(
 6263                language.as_ref().map(|language| language.name()),
 6264                buffer.read(cx).file(),
 6265                cx,
 6266            )
 6267            .completions
 6268            .clone();
 6269            if !completion_settings.lsp {
 6270                return Task::ready(Ok(Vec::new()));
 6271            }
 6272
 6273            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6274                local
 6275                    .language_servers_for_buffer(buffer, cx)
 6276                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6277                    .filter(|(adapter, _)| {
 6278                        scope
 6279                            .as_ref()
 6280                            .map(|scope| scope.language_allowed(&adapter.name))
 6281                            .unwrap_or(true)
 6282                    })
 6283                    .map(|(_, server)| server.server_id())
 6284                    .collect()
 6285            });
 6286
 6287            let buffer = buffer.clone();
 6288            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6289            let lsp_timeout = if lsp_timeout > 0 {
 6290                Some(Duration::from_millis(lsp_timeout))
 6291            } else {
 6292                None
 6293            };
 6294            cx.spawn(async move |this,  cx| {
 6295                let mut tasks = Vec::with_capacity(server_ids.len());
 6296                this.update(cx, |lsp_store, cx| {
 6297                    for server_id in server_ids {
 6298                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6299                        let lsp_timeout = lsp_timeout
 6300                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6301                        let mut timeout = cx.background_spawn(async move {
 6302                            match lsp_timeout {
 6303                                Some(lsp_timeout) => {
 6304                                    lsp_timeout.await;
 6305                                    true
 6306                                },
 6307                                None => false,
 6308                            }
 6309                        }).fuse();
 6310                        let mut lsp_request = lsp_store.request_lsp(
 6311                            buffer.clone(),
 6312                            LanguageServerToQuery::Other(server_id),
 6313                            GetCompletions {
 6314                                position,
 6315                                context: context.clone(),
 6316                                server_id: Some(server_id),
 6317                            },
 6318                            cx,
 6319                        ).fuse();
 6320                        let new_task = cx.background_spawn(async move {
 6321                            select_biased! {
 6322                                response = lsp_request => anyhow::Ok(Some(response?)),
 6323                                timeout_happened = timeout => {
 6324                                    if timeout_happened {
 6325                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6326                                        Ok(None)
 6327                                    } else {
 6328                                        let completions = lsp_request.await?;
 6329                                        Ok(Some(completions))
 6330                                    }
 6331                                },
 6332                            }
 6333                        });
 6334                        tasks.push((lsp_adapter, new_task));
 6335                    }
 6336                })?;
 6337
 6338                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6339                    let completion_response = task.await.ok()??;
 6340                    let completions = populate_labels_for_completions(
 6341                            completion_response.completions,
 6342                            language.clone(),
 6343                            lsp_adapter,
 6344                        )
 6345                        .await;
 6346                    Some(CompletionResponse {
 6347                        completions,
 6348                        display_options: CompletionDisplayOptions::default(),
 6349                        is_incomplete: completion_response.is_incomplete,
 6350                    })
 6351                });
 6352
 6353                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6354
 6355                Ok(responses.into_iter().flatten().collect())
 6356            })
 6357        } else {
 6358            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6359        }
 6360    }
 6361
 6362    pub fn resolve_completions(
 6363        &self,
 6364        buffer: Entity<Buffer>,
 6365        completion_indices: Vec<usize>,
 6366        completions: Rc<RefCell<Box<[Completion]>>>,
 6367        cx: &mut Context<Self>,
 6368    ) -> Task<Result<bool>> {
 6369        let client = self.upstream_client();
 6370        let buffer_id = buffer.read(cx).remote_id();
 6371        let buffer_snapshot = buffer.read(cx).snapshot();
 6372
 6373        if !self.check_if_capable_for_proto_request(
 6374            &buffer,
 6375            GetCompletions::can_resolve_completions,
 6376            cx,
 6377        ) {
 6378            return Task::ready(Ok(false));
 6379        }
 6380        cx.spawn(async move |lsp_store, cx| {
 6381            let mut did_resolve = false;
 6382            if let Some((client, project_id)) = client {
 6383                for completion_index in completion_indices {
 6384                    let server_id = {
 6385                        let completion = &completions.borrow()[completion_index];
 6386                        completion.source.server_id()
 6387                    };
 6388                    if let Some(server_id) = server_id {
 6389                        if Self::resolve_completion_remote(
 6390                            project_id,
 6391                            server_id,
 6392                            buffer_id,
 6393                            completions.clone(),
 6394                            completion_index,
 6395                            client.clone(),
 6396                        )
 6397                        .await
 6398                        .log_err()
 6399                        .is_some()
 6400                        {
 6401                            did_resolve = true;
 6402                        }
 6403                    } else {
 6404                        resolve_word_completion(
 6405                            &buffer_snapshot,
 6406                            &mut completions.borrow_mut()[completion_index],
 6407                        );
 6408                    }
 6409                }
 6410            } else {
 6411                for completion_index in completion_indices {
 6412                    let server_id = {
 6413                        let completion = &completions.borrow()[completion_index];
 6414                        completion.source.server_id()
 6415                    };
 6416                    if let Some(server_id) = server_id {
 6417                        let server_and_adapter = lsp_store
 6418                            .read_with(cx, |lsp_store, _| {
 6419                                let server = lsp_store.language_server_for_id(server_id)?;
 6420                                let adapter =
 6421                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6422                                Some((server, adapter))
 6423                            })
 6424                            .ok()
 6425                            .flatten();
 6426                        let Some((server, adapter)) = server_and_adapter else {
 6427                            continue;
 6428                        };
 6429
 6430                        let resolved = Self::resolve_completion_local(
 6431                            server,
 6432                            completions.clone(),
 6433                            completion_index,
 6434                        )
 6435                        .await
 6436                        .log_err()
 6437                        .is_some();
 6438                        if resolved {
 6439                            Self::regenerate_completion_labels(
 6440                                adapter,
 6441                                &buffer_snapshot,
 6442                                completions.clone(),
 6443                                completion_index,
 6444                            )
 6445                            .await
 6446                            .log_err();
 6447                            did_resolve = true;
 6448                        }
 6449                    } else {
 6450                        resolve_word_completion(
 6451                            &buffer_snapshot,
 6452                            &mut completions.borrow_mut()[completion_index],
 6453                        );
 6454                    }
 6455                }
 6456            }
 6457
 6458            Ok(did_resolve)
 6459        })
 6460    }
 6461
 6462    async fn resolve_completion_local(
 6463        server: Arc<lsp::LanguageServer>,
 6464        completions: Rc<RefCell<Box<[Completion]>>>,
 6465        completion_index: usize,
 6466    ) -> Result<()> {
 6467        let server_id = server.server_id();
 6468        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6469            return Ok(());
 6470        }
 6471
 6472        let request = {
 6473            let completion = &completions.borrow()[completion_index];
 6474            match &completion.source {
 6475                CompletionSource::Lsp {
 6476                    lsp_completion,
 6477                    resolved,
 6478                    server_id: completion_server_id,
 6479                    ..
 6480                } => {
 6481                    if *resolved {
 6482                        return Ok(());
 6483                    }
 6484                    anyhow::ensure!(
 6485                        server_id == *completion_server_id,
 6486                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6487                    );
 6488                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6489                }
 6490                CompletionSource::BufferWord { .. }
 6491                | CompletionSource::Dap { .. }
 6492                | CompletionSource::Custom => {
 6493                    return Ok(());
 6494                }
 6495            }
 6496        };
 6497        let resolved_completion = request
 6498            .await
 6499            .into_response()
 6500            .context("resolve completion")?;
 6501
 6502        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6503        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6504
 6505        let mut completions = completions.borrow_mut();
 6506        let completion = &mut completions[completion_index];
 6507        if let CompletionSource::Lsp {
 6508            lsp_completion,
 6509            resolved,
 6510            server_id: completion_server_id,
 6511            ..
 6512        } = &mut completion.source
 6513        {
 6514            if *resolved {
 6515                return Ok(());
 6516            }
 6517            anyhow::ensure!(
 6518                server_id == *completion_server_id,
 6519                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6520            );
 6521            **lsp_completion = resolved_completion;
 6522            *resolved = true;
 6523        }
 6524        Ok(())
 6525    }
 6526
 6527    async fn regenerate_completion_labels(
 6528        adapter: Arc<CachedLspAdapter>,
 6529        snapshot: &BufferSnapshot,
 6530        completions: Rc<RefCell<Box<[Completion]>>>,
 6531        completion_index: usize,
 6532    ) -> Result<()> {
 6533        let completion_item = completions.borrow()[completion_index]
 6534            .source
 6535            .lsp_completion(true)
 6536            .map(Cow::into_owned);
 6537        if let Some(lsp_documentation) = completion_item
 6538            .as_ref()
 6539            .and_then(|completion_item| completion_item.documentation.clone())
 6540        {
 6541            let mut completions = completions.borrow_mut();
 6542            let completion = &mut completions[completion_index];
 6543            completion.documentation = Some(lsp_documentation.into());
 6544        } else {
 6545            let mut completions = completions.borrow_mut();
 6546            let completion = &mut completions[completion_index];
 6547            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6548        }
 6549
 6550        let mut new_label = match completion_item {
 6551            Some(completion_item) => {
 6552                // Some language servers always return `detail` lazily via resolve, regardless of
 6553                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6554                // See: https://github.com/yioneko/vtsls/issues/213
 6555                let language = snapshot.language();
 6556                match language {
 6557                    Some(language) => {
 6558                        adapter
 6559                            .labels_for_completions(
 6560                                std::slice::from_ref(&completion_item),
 6561                                language,
 6562                            )
 6563                            .await?
 6564                    }
 6565                    None => Vec::new(),
 6566                }
 6567                .pop()
 6568                .flatten()
 6569                .unwrap_or_else(|| {
 6570                    CodeLabel::fallback_for_completion(
 6571                        &completion_item,
 6572                        language.map(|language| language.as_ref()),
 6573                    )
 6574                })
 6575            }
 6576            None => CodeLabel::plain(
 6577                completions.borrow()[completion_index].new_text.clone(),
 6578                None,
 6579            ),
 6580        };
 6581        ensure_uniform_list_compatible_label(&mut new_label);
 6582
 6583        let mut completions = completions.borrow_mut();
 6584        let completion = &mut completions[completion_index];
 6585        if completion.label.filter_text() == new_label.filter_text() {
 6586            completion.label = new_label;
 6587        } else {
 6588            log::error!(
 6589                "Resolved completion changed display label from {} to {}. \
 6590                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6591                completion.label.text(),
 6592                new_label.text(),
 6593                completion.label.filter_text(),
 6594                new_label.filter_text()
 6595            );
 6596        }
 6597
 6598        Ok(())
 6599    }
 6600
 6601    async fn resolve_completion_remote(
 6602        project_id: u64,
 6603        server_id: LanguageServerId,
 6604        buffer_id: BufferId,
 6605        completions: Rc<RefCell<Box<[Completion]>>>,
 6606        completion_index: usize,
 6607        client: AnyProtoClient,
 6608    ) -> Result<()> {
 6609        let lsp_completion = {
 6610            let completion = &completions.borrow()[completion_index];
 6611            match &completion.source {
 6612                CompletionSource::Lsp {
 6613                    lsp_completion,
 6614                    resolved,
 6615                    server_id: completion_server_id,
 6616                    ..
 6617                } => {
 6618                    anyhow::ensure!(
 6619                        server_id == *completion_server_id,
 6620                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6621                    );
 6622                    if *resolved {
 6623                        return Ok(());
 6624                    }
 6625                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6626                }
 6627                CompletionSource::Custom
 6628                | CompletionSource::Dap { .. }
 6629                | CompletionSource::BufferWord { .. } => {
 6630                    return Ok(());
 6631                }
 6632            }
 6633        };
 6634        let request = proto::ResolveCompletionDocumentation {
 6635            project_id,
 6636            language_server_id: server_id.0 as u64,
 6637            lsp_completion,
 6638            buffer_id: buffer_id.into(),
 6639        };
 6640
 6641        let response = client
 6642            .request(request)
 6643            .await
 6644            .context("completion documentation resolve proto request")?;
 6645        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6646
 6647        let documentation = if response.documentation.is_empty() {
 6648            CompletionDocumentation::Undocumented
 6649        } else if response.documentation_is_markdown {
 6650            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6651        } else if response.documentation.lines().count() <= 1 {
 6652            CompletionDocumentation::SingleLine(response.documentation.into())
 6653        } else {
 6654            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6655        };
 6656
 6657        let mut completions = completions.borrow_mut();
 6658        let completion = &mut completions[completion_index];
 6659        completion.documentation = Some(documentation);
 6660        if let CompletionSource::Lsp {
 6661            insert_range,
 6662            lsp_completion,
 6663            resolved,
 6664            server_id: completion_server_id,
 6665            lsp_defaults: _,
 6666        } = &mut completion.source
 6667        {
 6668            let completion_insert_range = response
 6669                .old_insert_start
 6670                .and_then(deserialize_anchor)
 6671                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6672            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6673
 6674            if *resolved {
 6675                return Ok(());
 6676            }
 6677            anyhow::ensure!(
 6678                server_id == *completion_server_id,
 6679                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6680            );
 6681            **lsp_completion = resolved_lsp_completion;
 6682            *resolved = true;
 6683        }
 6684
 6685        let replace_range = response
 6686            .old_replace_start
 6687            .and_then(deserialize_anchor)
 6688            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6689        if let Some((old_replace_start, old_replace_end)) = replace_range
 6690            && !response.new_text.is_empty()
 6691        {
 6692            completion.new_text = response.new_text;
 6693            completion.replace_range = old_replace_start..old_replace_end;
 6694        }
 6695
 6696        Ok(())
 6697    }
 6698
 6699    pub fn apply_additional_edits_for_completion(
 6700        &self,
 6701        buffer_handle: Entity<Buffer>,
 6702        completions: Rc<RefCell<Box<[Completion]>>>,
 6703        completion_index: usize,
 6704        push_to_history: bool,
 6705        cx: &mut Context<Self>,
 6706    ) -> Task<Result<Option<Transaction>>> {
 6707        if let Some((client, project_id)) = self.upstream_client() {
 6708            let buffer = buffer_handle.read(cx);
 6709            let buffer_id = buffer.remote_id();
 6710            cx.spawn(async move |_, cx| {
 6711                let request = {
 6712                    let completion = completions.borrow()[completion_index].clone();
 6713                    proto::ApplyCompletionAdditionalEdits {
 6714                        project_id,
 6715                        buffer_id: buffer_id.into(),
 6716                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6717                            replace_range: completion.replace_range,
 6718                            new_text: completion.new_text,
 6719                            source: completion.source,
 6720                        })),
 6721                    }
 6722                };
 6723
 6724                if let Some(transaction) = client.request(request).await?.transaction {
 6725                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6726                    buffer_handle
 6727                        .update(cx, |buffer, _| {
 6728                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6729                        })
 6730                        .await?;
 6731                    if push_to_history {
 6732                        buffer_handle.update(cx, |buffer, _| {
 6733                            buffer.push_transaction(transaction.clone(), Instant::now());
 6734                            buffer.finalize_last_transaction();
 6735                        });
 6736                    }
 6737                    Ok(Some(transaction))
 6738                } else {
 6739                    Ok(None)
 6740                }
 6741            })
 6742        } else {
 6743            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6744                let completion = &completions.borrow()[completion_index];
 6745                let server_id = completion.source.server_id()?;
 6746                Some(
 6747                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6748                        .1
 6749                        .clone(),
 6750                )
 6751            }) else {
 6752                return Task::ready(Ok(None));
 6753            };
 6754
 6755            cx.spawn(async move |this, cx| {
 6756                Self::resolve_completion_local(
 6757                    server.clone(),
 6758                    completions.clone(),
 6759                    completion_index,
 6760                )
 6761                .await
 6762                .context("resolving completion")?;
 6763                let completion = completions.borrow()[completion_index].clone();
 6764                let additional_text_edits = completion
 6765                    .source
 6766                    .lsp_completion(true)
 6767                    .as_ref()
 6768                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6769                if let Some(edits) = additional_text_edits {
 6770                    let edits = this
 6771                        .update(cx, |this, cx| {
 6772                            this.as_local_mut().unwrap().edits_from_lsp(
 6773                                &buffer_handle,
 6774                                edits,
 6775                                server.server_id(),
 6776                                None,
 6777                                cx,
 6778                            )
 6779                        })?
 6780                        .await?;
 6781
 6782                    buffer_handle.update(cx, |buffer, cx| {
 6783                        buffer.finalize_last_transaction();
 6784                        buffer.start_transaction();
 6785
 6786                        for (range, text) in edits {
 6787                            let primary = &completion.replace_range;
 6788
 6789                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6790                            // and the primary completion is just an insertion (empty range), then this is likely
 6791                            // an auto-import scenario and should not be considered overlapping
 6792                            // https://github.com/zed-industries/zed/issues/26136
 6793                            let is_file_start_auto_import = {
 6794                                let snapshot = buffer.snapshot();
 6795                                let primary_start_point = primary.start.to_point(&snapshot);
 6796                                let range_start_point = range.start.to_point(&snapshot);
 6797
 6798                                let result = primary_start_point.row == 0
 6799                                    && primary_start_point.column == 0
 6800                                    && range_start_point.row == 0
 6801                                    && range_start_point.column == 0;
 6802
 6803                                result
 6804                            };
 6805
 6806                            let has_overlap = if is_file_start_auto_import {
 6807                                false
 6808                            } else {
 6809                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6810                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6811                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6812                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6813                                let result = start_within || end_within;
 6814                                result
 6815                            };
 6816
 6817                            //Skip additional edits which overlap with the primary completion edit
 6818                            //https://github.com/zed-industries/zed/pull/1871
 6819                            if !has_overlap {
 6820                                buffer.edit([(range, text)], None, cx);
 6821                            }
 6822                        }
 6823
 6824                        let transaction = if buffer.end_transaction(cx).is_some() {
 6825                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6826                            if !push_to_history {
 6827                                buffer.forget_transaction(transaction.id);
 6828                            }
 6829                            Some(transaction)
 6830                        } else {
 6831                            None
 6832                        };
 6833                        Ok(transaction)
 6834                    })
 6835                } else {
 6836                    Ok(None)
 6837                }
 6838            })
 6839        }
 6840    }
 6841
 6842    pub fn pull_diagnostics(
 6843        &mut self,
 6844        buffer: Entity<Buffer>,
 6845        cx: &mut Context<Self>,
 6846    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6847        let buffer_id = buffer.read(cx).remote_id();
 6848
 6849        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6850            let mut suitable_capabilities = None;
 6851            // Are we capable for proto request?
 6852            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6853                &buffer,
 6854                |capabilities| {
 6855                    if let Some(caps) = &capabilities.diagnostic_provider {
 6856                        suitable_capabilities = Some(caps.clone());
 6857                        true
 6858                    } else {
 6859                        false
 6860                    }
 6861                },
 6862                cx,
 6863            );
 6864            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6865            let Some(dynamic_caps) = suitable_capabilities else {
 6866                return Task::ready(Ok(None));
 6867            };
 6868            assert!(any_server_has_diagnostics_provider);
 6869
 6870            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6871            let request = GetDocumentDiagnostics {
 6872                previous_result_id: None,
 6873                identifier,
 6874                registration_id: None,
 6875            };
 6876            let request_task = client.request_lsp(
 6877                upstream_project_id,
 6878                None,
 6879                LSP_REQUEST_TIMEOUT,
 6880                cx.background_executor().clone(),
 6881                request.to_proto(upstream_project_id, buffer.read(cx)),
 6882            );
 6883            cx.background_spawn(async move {
 6884                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6885                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6886                // Do not attempt to further process the dummy responses here.
 6887                let _response = request_task.await?;
 6888                Ok(None)
 6889            })
 6890        } else {
 6891            let servers = buffer.update(cx, |buffer, cx| {
 6892                self.running_language_servers_for_local_buffer(buffer, cx)
 6893                    .map(|(_, server)| server.clone())
 6894                    .collect::<Vec<_>>()
 6895            });
 6896
 6897            let pull_diagnostics = servers
 6898                .into_iter()
 6899                .flat_map(|server| {
 6900                    let result = maybe!({
 6901                        let local = self.as_local()?;
 6902                        let server_id = server.server_id();
 6903                        let providers_with_identifiers = local
 6904                            .language_server_dynamic_registrations
 6905                            .get(&server_id)
 6906                            .into_iter()
 6907                            .flat_map(|registrations| registrations.diagnostics.clone())
 6908                            .collect::<Vec<_>>();
 6909                        Some(
 6910                            providers_with_identifiers
 6911                                .into_iter()
 6912                                .map(|(registration_id, dynamic_caps)| {
 6913                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6914                                    let registration_id = registration_id.map(SharedString::from);
 6915                                    let result_id = self.result_id_for_buffer_pull(
 6916                                        server_id,
 6917                                        buffer_id,
 6918                                        &registration_id,
 6919                                        cx,
 6920                                    );
 6921                                    self.request_lsp(
 6922                                        buffer.clone(),
 6923                                        LanguageServerToQuery::Other(server_id),
 6924                                        GetDocumentDiagnostics {
 6925                                            previous_result_id: result_id,
 6926                                            registration_id,
 6927                                            identifier,
 6928                                        },
 6929                                        cx,
 6930                                    )
 6931                                })
 6932                                .collect::<Vec<_>>(),
 6933                        )
 6934                    });
 6935
 6936                    result.unwrap_or_default()
 6937                })
 6938                .collect::<Vec<_>>();
 6939
 6940            cx.background_spawn(async move {
 6941                let mut responses = Vec::new();
 6942                for diagnostics in join_all(pull_diagnostics).await {
 6943                    responses.extend(diagnostics?);
 6944                }
 6945                Ok(Some(responses))
 6946            })
 6947        }
 6948    }
 6949
 6950    pub fn applicable_inlay_chunks(
 6951        &mut self,
 6952        buffer: &Entity<Buffer>,
 6953        ranges: &[Range<text::Anchor>],
 6954        cx: &mut Context<Self>,
 6955    ) -> Vec<Range<BufferRow>> {
 6956        let buffer_snapshot = buffer.read(cx).snapshot();
 6957        let ranges = ranges
 6958            .iter()
 6959            .map(|range| range.to_point(&buffer_snapshot))
 6960            .collect::<Vec<_>>();
 6961
 6962        self.latest_lsp_data(buffer, cx)
 6963            .inlay_hints
 6964            .applicable_chunks(ranges.as_slice())
 6965            .map(|chunk| chunk.row_range())
 6966            .collect()
 6967    }
 6968
 6969    pub fn invalidate_inlay_hints<'a>(
 6970        &'a mut self,
 6971        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6972    ) {
 6973        for buffer_id in for_buffers {
 6974            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6975                lsp_data.inlay_hints.clear();
 6976            }
 6977        }
 6978    }
 6979
 6980    pub fn inlay_hints(
 6981        &mut self,
 6982        invalidate: InvalidationStrategy,
 6983        buffer: Entity<Buffer>,
 6984        ranges: Vec<Range<text::Anchor>>,
 6985        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6986        cx: &mut Context<Self>,
 6987    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6988        let next_hint_id = self.next_hint_id.clone();
 6989        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6990        let query_version = lsp_data.buffer_version.clone();
 6991        let mut lsp_refresh_requested = false;
 6992        let for_server = if let InvalidationStrategy::RefreshRequested {
 6993            server_id,
 6994            request_id,
 6995        } = invalidate
 6996        {
 6997            let invalidated = lsp_data
 6998                .inlay_hints
 6999                .invalidate_for_server_refresh(server_id, request_id);
 7000            lsp_refresh_requested = invalidated;
 7001            Some(server_id)
 7002        } else {
 7003            None
 7004        };
 7005        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 7006        let known_chunks = known_chunks
 7007            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 7008            .map(|(_, known_chunks)| known_chunks)
 7009            .unwrap_or_default();
 7010
 7011        let buffer_snapshot = buffer.read(cx).snapshot();
 7012        let ranges = ranges
 7013            .iter()
 7014            .map(|range| range.to_point(&buffer_snapshot))
 7015            .collect::<Vec<_>>();
 7016
 7017        let mut hint_fetch_tasks = Vec::new();
 7018        let mut cached_inlay_hints = None;
 7019        let mut ranges_to_query = None;
 7020        let applicable_chunks = existing_inlay_hints
 7021            .applicable_chunks(ranges.as_slice())
 7022            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7023            .collect::<Vec<_>>();
 7024        if applicable_chunks.is_empty() {
 7025            return HashMap::default();
 7026        }
 7027
 7028        for row_chunk in applicable_chunks {
 7029            match (
 7030                existing_inlay_hints
 7031                    .cached_hints(&row_chunk)
 7032                    .filter(|_| !lsp_refresh_requested)
 7033                    .cloned(),
 7034                existing_inlay_hints
 7035                    .fetched_hints(&row_chunk)
 7036                    .as_ref()
 7037                    .filter(|_| !lsp_refresh_requested)
 7038                    .cloned(),
 7039            ) {
 7040                (None, None) => {
 7041                    let chunk_range = row_chunk.anchor_range();
 7042                    ranges_to_query
 7043                        .get_or_insert_with(Vec::new)
 7044                        .push((row_chunk, chunk_range));
 7045                }
 7046                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7047                (Some(cached_hints), None) => {
 7048                    for (server_id, cached_hints) in cached_hints {
 7049                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7050                            cached_inlay_hints
 7051                                .get_or_insert_with(HashMap::default)
 7052                                .entry(row_chunk.row_range())
 7053                                .or_insert_with(HashMap::default)
 7054                                .entry(server_id)
 7055                                .or_insert_with(Vec::new)
 7056                                .extend(cached_hints);
 7057                        }
 7058                    }
 7059                }
 7060                (Some(cached_hints), Some(fetched_hints)) => {
 7061                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7062                    for (server_id, cached_hints) in cached_hints {
 7063                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7064                            cached_inlay_hints
 7065                                .get_or_insert_with(HashMap::default)
 7066                                .entry(row_chunk.row_range())
 7067                                .or_insert_with(HashMap::default)
 7068                                .entry(server_id)
 7069                                .or_insert_with(Vec::new)
 7070                                .extend(cached_hints);
 7071                        }
 7072                    }
 7073                }
 7074            }
 7075        }
 7076
 7077        if hint_fetch_tasks.is_empty()
 7078            && ranges_to_query
 7079                .as_ref()
 7080                .is_none_or(|ranges| ranges.is_empty())
 7081            && let Some(cached_inlay_hints) = cached_inlay_hints
 7082        {
 7083            cached_inlay_hints
 7084                .into_iter()
 7085                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7086                .collect()
 7087        } else {
 7088            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7089                let next_hint_id = next_hint_id.clone();
 7090                let buffer = buffer.clone();
 7091                let query_version = query_version.clone();
 7092                let new_inlay_hints = cx
 7093                    .spawn(async move |lsp_store, cx| {
 7094                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7095                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7096                        })?;
 7097                        new_fetch_task
 7098                            .await
 7099                            .and_then(|new_hints_by_server| {
 7100                                lsp_store.update(cx, |lsp_store, cx| {
 7101                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7102                                    let update_cache = lsp_data.buffer_version == query_version;
 7103                                    if new_hints_by_server.is_empty() {
 7104                                        if update_cache {
 7105                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7106                                        }
 7107                                        HashMap::default()
 7108                                    } else {
 7109                                        new_hints_by_server
 7110                                            .into_iter()
 7111                                            .map(|(server_id, new_hints)| {
 7112                                                let new_hints = new_hints
 7113                                                    .into_iter()
 7114                                                    .map(|new_hint| {
 7115                                                        (
 7116                                                            InlayId::Hint(next_hint_id.fetch_add(
 7117                                                                1,
 7118                                                                atomic::Ordering::AcqRel,
 7119                                                            )),
 7120                                                            new_hint,
 7121                                                        )
 7122                                                    })
 7123                                                    .collect::<Vec<_>>();
 7124                                                if update_cache {
 7125                                                    lsp_data.inlay_hints.insert_new_hints(
 7126                                                        chunk,
 7127                                                        server_id,
 7128                                                        new_hints.clone(),
 7129                                                    );
 7130                                                }
 7131                                                (server_id, new_hints)
 7132                                            })
 7133                                            .collect()
 7134                                    }
 7135                                })
 7136                            })
 7137                            .map_err(Arc::new)
 7138                    })
 7139                    .shared();
 7140
 7141                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7142                *fetch_task = Some(new_inlay_hints.clone());
 7143                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7144            }
 7145
 7146            cached_inlay_hints
 7147                .unwrap_or_default()
 7148                .into_iter()
 7149                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7150                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7151                    (
 7152                        chunk.row_range(),
 7153                        cx.spawn(async move |_, _| {
 7154                            hints_fetch.await.map_err(|e| {
 7155                                if e.error_code() != ErrorCode::Internal {
 7156                                    anyhow!(e.error_code())
 7157                                } else {
 7158                                    anyhow!("{e:#}")
 7159                                }
 7160                            })
 7161                        }),
 7162                    )
 7163                }))
 7164                .collect()
 7165        }
 7166    }
 7167
 7168    fn fetch_inlay_hints(
 7169        &mut self,
 7170        for_server: Option<LanguageServerId>,
 7171        buffer: &Entity<Buffer>,
 7172        range: Range<Anchor>,
 7173        cx: &mut Context<Self>,
 7174    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7175        let request = InlayHints {
 7176            range: range.clone(),
 7177        };
 7178        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7179            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7180                return Task::ready(Ok(HashMap::default()));
 7181            }
 7182            let request_task = upstream_client.request_lsp(
 7183                project_id,
 7184                for_server.map(|id| id.to_proto()),
 7185                LSP_REQUEST_TIMEOUT,
 7186                cx.background_executor().clone(),
 7187                request.to_proto(project_id, buffer.read(cx)),
 7188            );
 7189            let buffer = buffer.clone();
 7190            cx.spawn(async move |weak_lsp_store, cx| {
 7191                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7192                    return Ok(HashMap::default());
 7193                };
 7194                let Some(responses) = request_task.await? else {
 7195                    return Ok(HashMap::default());
 7196                };
 7197
 7198                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7199                    let lsp_store = lsp_store.clone();
 7200                    let buffer = buffer.clone();
 7201                    let cx = cx.clone();
 7202                    let request = request.clone();
 7203                    async move {
 7204                        (
 7205                            LanguageServerId::from_proto(response.server_id),
 7206                            request
 7207                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7208                                .await,
 7209                        )
 7210                    }
 7211                }))
 7212                .await;
 7213
 7214                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7215                let mut has_errors = false;
 7216                let inlay_hints = inlay_hints
 7217                    .into_iter()
 7218                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7219                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7220                        Err(e) => {
 7221                            has_errors = true;
 7222                            log::error!("{e:#}");
 7223                            None
 7224                        }
 7225                    })
 7226                    .map(|(server_id, mut new_hints)| {
 7227                        new_hints.retain(|hint| {
 7228                            hint.position.is_valid(&buffer_snapshot)
 7229                                && range.start.is_valid(&buffer_snapshot)
 7230                                && range.end.is_valid(&buffer_snapshot)
 7231                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7232                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7233                        });
 7234                        (server_id, new_hints)
 7235                    })
 7236                    .collect::<HashMap<_, _>>();
 7237                anyhow::ensure!(
 7238                    !has_errors || !inlay_hints.is_empty(),
 7239                    "Failed to fetch inlay hints"
 7240                );
 7241                Ok(inlay_hints)
 7242            })
 7243        } else {
 7244            let inlay_hints_task = match for_server {
 7245                Some(server_id) => {
 7246                    let server_task = self.request_lsp(
 7247                        buffer.clone(),
 7248                        LanguageServerToQuery::Other(server_id),
 7249                        request,
 7250                        cx,
 7251                    );
 7252                    cx.background_spawn(async move {
 7253                        let mut responses = Vec::new();
 7254                        match server_task.await {
 7255                            Ok(response) => responses.push((server_id, response)),
 7256                            // rust-analyzer likes to error with this when its still loading up
 7257                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7258                            Err(e) => log::error!(
 7259                                "Error handling response for inlay hints request: {e:#}"
 7260                            ),
 7261                        }
 7262                        responses
 7263                    })
 7264                }
 7265                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7266            };
 7267            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7268            cx.background_spawn(async move {
 7269                Ok(inlay_hints_task
 7270                    .await
 7271                    .into_iter()
 7272                    .map(|(server_id, mut new_hints)| {
 7273                        new_hints.retain(|hint| {
 7274                            hint.position.is_valid(&buffer_snapshot)
 7275                                && range.start.is_valid(&buffer_snapshot)
 7276                                && range.end.is_valid(&buffer_snapshot)
 7277                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7278                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7279                        });
 7280                        (server_id, new_hints)
 7281                    })
 7282                    .collect())
 7283            })
 7284        }
 7285    }
 7286
 7287    fn diagnostic_registration_exists(
 7288        &self,
 7289        server_id: LanguageServerId,
 7290        registration_id: &Option<SharedString>,
 7291    ) -> bool {
 7292        let Some(local) = self.as_local() else {
 7293            return false;
 7294        };
 7295        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7296        else {
 7297            return false;
 7298        };
 7299        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7300        registrations.diagnostics.contains_key(&registration_key)
 7301    }
 7302
 7303    pub fn pull_diagnostics_for_buffer(
 7304        &mut self,
 7305        buffer: Entity<Buffer>,
 7306        cx: &mut Context<Self>,
 7307    ) -> Task<anyhow::Result<()>> {
 7308        let diagnostics = self.pull_diagnostics(buffer, cx);
 7309        cx.spawn(async move |lsp_store, cx| {
 7310            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7311                return Ok(());
 7312            };
 7313            lsp_store.update(cx, |lsp_store, cx| {
 7314                if lsp_store.as_local().is_none() {
 7315                    return;
 7316                }
 7317
 7318                let mut unchanged_buffers = HashMap::default();
 7319                let server_diagnostics_updates = diagnostics
 7320                    .into_iter()
 7321                    .filter_map(|diagnostics_set| match diagnostics_set {
 7322                        LspPullDiagnostics::Response {
 7323                            server_id,
 7324                            uri,
 7325                            diagnostics,
 7326                            registration_id,
 7327                        } => Some((server_id, uri, diagnostics, registration_id)),
 7328                        LspPullDiagnostics::Default => None,
 7329                    })
 7330                    .filter(|(server_id, _, _, registration_id)| {
 7331                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7332                    })
 7333                    .fold(
 7334                        HashMap::default(),
 7335                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7336                            let (result_id, diagnostics) = match diagnostics {
 7337                                PulledDiagnostics::Unchanged { result_id } => {
 7338                                    unchanged_buffers
 7339                                        .entry(new_registration_id.clone())
 7340                                        .or_insert_with(HashSet::default)
 7341                                        .insert(uri.clone());
 7342                                    (Some(result_id), Vec::new())
 7343                                }
 7344                                PulledDiagnostics::Changed {
 7345                                    result_id,
 7346                                    diagnostics,
 7347                                } => (result_id, diagnostics),
 7348                            };
 7349                            let disk_based_sources = Cow::Owned(
 7350                                lsp_store
 7351                                    .language_server_adapter_for_id(server_id)
 7352                                    .as_ref()
 7353                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7354                                    .unwrap_or(&[])
 7355                                    .to_vec(),
 7356                            );
 7357                            acc.entry(server_id)
 7358                                .or_insert_with(HashMap::default)
 7359                                .entry(new_registration_id.clone())
 7360                                .or_insert_with(Vec::new)
 7361                                .push(DocumentDiagnosticsUpdate {
 7362                                    server_id,
 7363                                    diagnostics: lsp::PublishDiagnosticsParams {
 7364                                        uri,
 7365                                        diagnostics,
 7366                                        version: None,
 7367                                    },
 7368                                    result_id,
 7369                                    disk_based_sources,
 7370                                    registration_id: new_registration_id,
 7371                                });
 7372                            acc
 7373                        },
 7374                    );
 7375
 7376                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7377                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7378                        lsp_store
 7379                            .merge_lsp_diagnostics(
 7380                                DiagnosticSourceKind::Pulled,
 7381                                diagnostic_updates,
 7382                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7383                                    DiagnosticSourceKind::Pulled => {
 7384                                        old_diagnostic.registration_id != registration_id
 7385                                            || unchanged_buffers
 7386                                                .get(&old_diagnostic.registration_id)
 7387                                                .is_some_and(|unchanged_buffers| {
 7388                                                    unchanged_buffers.contains(&document_uri)
 7389                                                })
 7390                                    }
 7391                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7392                                        true
 7393                                    }
 7394                                },
 7395                                cx,
 7396                            )
 7397                            .log_err();
 7398                    }
 7399                }
 7400            })
 7401        })
 7402    }
 7403
 7404    pub fn document_colors(
 7405        &mut self,
 7406        known_cache_version: Option<usize>,
 7407        buffer: Entity<Buffer>,
 7408        cx: &mut Context<Self>,
 7409    ) -> Option<DocumentColorTask> {
 7410        let version_queried_for = buffer.read(cx).version();
 7411        let buffer_id = buffer.read(cx).remote_id();
 7412
 7413        let current_language_servers = self.as_local().map(|local| {
 7414            local
 7415                .buffers_opened_in_servers
 7416                .get(&buffer_id)
 7417                .cloned()
 7418                .unwrap_or_default()
 7419        });
 7420
 7421        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7422            if let Some(cached_colors) = &lsp_data.document_colors {
 7423                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7424                    let has_different_servers =
 7425                        current_language_servers.is_some_and(|current_language_servers| {
 7426                            current_language_servers
 7427                                != cached_colors.colors.keys().copied().collect()
 7428                        });
 7429                    if !has_different_servers {
 7430                        let cache_version = cached_colors.cache_version;
 7431                        if Some(cache_version) == known_cache_version {
 7432                            return None;
 7433                        } else {
 7434                            return Some(
 7435                                Task::ready(Ok(DocumentColors {
 7436                                    colors: cached_colors
 7437                                        .colors
 7438                                        .values()
 7439                                        .flatten()
 7440                                        .cloned()
 7441                                        .collect(),
 7442                                    cache_version: Some(cache_version),
 7443                                }))
 7444                                .shared(),
 7445                            );
 7446                        }
 7447                    }
 7448                }
 7449            }
 7450        }
 7451
 7452        let color_lsp_data = self
 7453            .latest_lsp_data(&buffer, cx)
 7454            .document_colors
 7455            .get_or_insert_default();
 7456        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7457            && !version_queried_for.changed_since(updating_for)
 7458        {
 7459            return Some(running_update.clone());
 7460        }
 7461        let buffer_version_queried_for = version_queried_for.clone();
 7462        let new_task = cx
 7463            .spawn(async move |lsp_store, cx| {
 7464                cx.background_executor()
 7465                    .timer(Duration::from_millis(30))
 7466                    .await;
 7467                let fetched_colors = lsp_store
 7468                    .update(cx, |lsp_store, cx| {
 7469                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7470                    })?
 7471                    .await
 7472                    .context("fetching document colors")
 7473                    .map_err(Arc::new);
 7474                let fetched_colors = match fetched_colors {
 7475                    Ok(fetched_colors) => {
 7476                        if buffer.update(cx, |buffer, _| {
 7477                            buffer.version() != buffer_version_queried_for
 7478                        }) {
 7479                            return Ok(DocumentColors::default());
 7480                        }
 7481                        fetched_colors
 7482                    }
 7483                    Err(e) => {
 7484                        lsp_store
 7485                            .update(cx, |lsp_store, _| {
 7486                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7487                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7488                                        document_colors.colors_update = None;
 7489                                    }
 7490                                }
 7491                            })
 7492                            .ok();
 7493                        return Err(e);
 7494                    }
 7495                };
 7496
 7497                lsp_store
 7498                    .update(cx, |lsp_store, cx| {
 7499                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7500                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7501
 7502                        if let Some(fetched_colors) = fetched_colors {
 7503                            if lsp_data.buffer_version == buffer_version_queried_for {
 7504                                lsp_colors.colors.extend(fetched_colors);
 7505                                lsp_colors.cache_version += 1;
 7506                            } else if !lsp_data
 7507                                .buffer_version
 7508                                .changed_since(&buffer_version_queried_for)
 7509                            {
 7510                                lsp_data.buffer_version = buffer_version_queried_for;
 7511                                lsp_colors.colors = fetched_colors;
 7512                                lsp_colors.cache_version += 1;
 7513                            }
 7514                        }
 7515                        lsp_colors.colors_update = None;
 7516                        let colors = lsp_colors
 7517                            .colors
 7518                            .values()
 7519                            .flatten()
 7520                            .cloned()
 7521                            .collect::<HashSet<_>>();
 7522                        DocumentColors {
 7523                            colors,
 7524                            cache_version: Some(lsp_colors.cache_version),
 7525                        }
 7526                    })
 7527                    .map_err(Arc::new)
 7528            })
 7529            .shared();
 7530        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7531        Some(new_task)
 7532    }
 7533
 7534    fn fetch_document_colors_for_buffer(
 7535        &mut self,
 7536        buffer: &Entity<Buffer>,
 7537        cx: &mut Context<Self>,
 7538    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7539        if let Some((client, project_id)) = self.upstream_client() {
 7540            let request = GetDocumentColor {};
 7541            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7542                return Task::ready(Ok(None));
 7543            }
 7544
 7545            let request_task = client.request_lsp(
 7546                project_id,
 7547                None,
 7548                LSP_REQUEST_TIMEOUT,
 7549                cx.background_executor().clone(),
 7550                request.to_proto(project_id, buffer.read(cx)),
 7551            );
 7552            let buffer = buffer.clone();
 7553            cx.spawn(async move |lsp_store, cx| {
 7554                let Some(lsp_store) = lsp_store.upgrade() else {
 7555                    return Ok(None);
 7556                };
 7557                let colors = join_all(
 7558                    request_task
 7559                        .await
 7560                        .log_err()
 7561                        .flatten()
 7562                        .map(|response| response.payload)
 7563                        .unwrap_or_default()
 7564                        .into_iter()
 7565                        .map(|color_response| {
 7566                            let response = request.response_from_proto(
 7567                                color_response.response,
 7568                                lsp_store.clone(),
 7569                                buffer.clone(),
 7570                                cx.clone(),
 7571                            );
 7572                            async move {
 7573                                (
 7574                                    LanguageServerId::from_proto(color_response.server_id),
 7575                                    response.await.log_err().unwrap_or_default(),
 7576                                )
 7577                            }
 7578                        }),
 7579                )
 7580                .await
 7581                .into_iter()
 7582                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7583                    acc.entry(server_id)
 7584                        .or_insert_with(HashSet::default)
 7585                        .extend(colors);
 7586                    acc
 7587                });
 7588                Ok(Some(colors))
 7589            })
 7590        } else {
 7591            let document_colors_task =
 7592                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7593            cx.background_spawn(async move {
 7594                Ok(Some(
 7595                    document_colors_task
 7596                        .await
 7597                        .into_iter()
 7598                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7599                            acc.entry(server_id)
 7600                                .or_insert_with(HashSet::default)
 7601                                .extend(colors);
 7602                            acc
 7603                        })
 7604                        .into_iter()
 7605                        .collect(),
 7606                ))
 7607            })
 7608        }
 7609    }
 7610
 7611    pub fn signature_help<T: ToPointUtf16>(
 7612        &mut self,
 7613        buffer: &Entity<Buffer>,
 7614        position: T,
 7615        cx: &mut Context<Self>,
 7616    ) -> Task<Option<Vec<SignatureHelp>>> {
 7617        let position = position.to_point_utf16(buffer.read(cx));
 7618
 7619        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7620            let request = GetSignatureHelp { position };
 7621            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7622                return Task::ready(None);
 7623            }
 7624            let request_task = client.request_lsp(
 7625                upstream_project_id,
 7626                None,
 7627                LSP_REQUEST_TIMEOUT,
 7628                cx.background_executor().clone(),
 7629                request.to_proto(upstream_project_id, buffer.read(cx)),
 7630            );
 7631            let buffer = buffer.clone();
 7632            cx.spawn(async move |weak_lsp_store, cx| {
 7633                let lsp_store = weak_lsp_store.upgrade()?;
 7634                let signatures = join_all(
 7635                    request_task
 7636                        .await
 7637                        .log_err()
 7638                        .flatten()
 7639                        .map(|response| response.payload)
 7640                        .unwrap_or_default()
 7641                        .into_iter()
 7642                        .map(|response| {
 7643                            let response = GetSignatureHelp { position }.response_from_proto(
 7644                                response.response,
 7645                                lsp_store.clone(),
 7646                                buffer.clone(),
 7647                                cx.clone(),
 7648                            );
 7649                            async move { response.await.log_err().flatten() }
 7650                        }),
 7651                )
 7652                .await
 7653                .into_iter()
 7654                .flatten()
 7655                .collect();
 7656                Some(signatures)
 7657            })
 7658        } else {
 7659            let all_actions_task = self.request_multiple_lsp_locally(
 7660                buffer,
 7661                Some(position),
 7662                GetSignatureHelp { position },
 7663                cx,
 7664            );
 7665            cx.background_spawn(async move {
 7666                Some(
 7667                    all_actions_task
 7668                        .await
 7669                        .into_iter()
 7670                        .flat_map(|(_, actions)| actions)
 7671                        .collect::<Vec<_>>(),
 7672                )
 7673            })
 7674        }
 7675    }
 7676
 7677    pub fn hover(
 7678        &mut self,
 7679        buffer: &Entity<Buffer>,
 7680        position: PointUtf16,
 7681        cx: &mut Context<Self>,
 7682    ) -> Task<Option<Vec<Hover>>> {
 7683        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7684            let request = GetHover { position };
 7685            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7686                return Task::ready(None);
 7687            }
 7688            let request_task = client.request_lsp(
 7689                upstream_project_id,
 7690                None,
 7691                LSP_REQUEST_TIMEOUT,
 7692                cx.background_executor().clone(),
 7693                request.to_proto(upstream_project_id, buffer.read(cx)),
 7694            );
 7695            let buffer = buffer.clone();
 7696            cx.spawn(async move |weak_lsp_store, cx| {
 7697                let lsp_store = weak_lsp_store.upgrade()?;
 7698                let hovers = join_all(
 7699                    request_task
 7700                        .await
 7701                        .log_err()
 7702                        .flatten()
 7703                        .map(|response| response.payload)
 7704                        .unwrap_or_default()
 7705                        .into_iter()
 7706                        .map(|response| {
 7707                            let response = GetHover { position }.response_from_proto(
 7708                                response.response,
 7709                                lsp_store.clone(),
 7710                                buffer.clone(),
 7711                                cx.clone(),
 7712                            );
 7713                            async move {
 7714                                response
 7715                                    .await
 7716                                    .log_err()
 7717                                    .flatten()
 7718                                    .and_then(remove_empty_hover_blocks)
 7719                            }
 7720                        }),
 7721                )
 7722                .await
 7723                .into_iter()
 7724                .flatten()
 7725                .collect();
 7726                Some(hovers)
 7727            })
 7728        } else {
 7729            let all_actions_task = self.request_multiple_lsp_locally(
 7730                buffer,
 7731                Some(position),
 7732                GetHover { position },
 7733                cx,
 7734            );
 7735            cx.background_spawn(async move {
 7736                Some(
 7737                    all_actions_task
 7738                        .await
 7739                        .into_iter()
 7740                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7741                        .collect::<Vec<Hover>>(),
 7742                )
 7743            })
 7744        }
 7745    }
 7746
 7747    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7748        let language_registry = self.languages.clone();
 7749
 7750        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7751            let request = upstream_client.request(proto::GetProjectSymbols {
 7752                project_id: *project_id,
 7753                query: query.to_string(),
 7754            });
 7755            cx.foreground_executor().spawn(async move {
 7756                let response = request.await?;
 7757                let mut symbols = Vec::new();
 7758                let core_symbols = response
 7759                    .symbols
 7760                    .into_iter()
 7761                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7762                    .collect::<Vec<_>>();
 7763                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7764                    .await;
 7765                Ok(symbols)
 7766            })
 7767        } else if let Some(local) = self.as_local() {
 7768            struct WorkspaceSymbolsResult {
 7769                server_id: LanguageServerId,
 7770                lsp_adapter: Arc<CachedLspAdapter>,
 7771                worktree: WeakEntity<Worktree>,
 7772                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7773            }
 7774
 7775            let mut requests = Vec::new();
 7776            let mut requested_servers = BTreeSet::new();
 7777            for (seed, state) in local.language_server_ids.iter() {
 7778                let Some(worktree_handle) = self
 7779                    .worktree_store
 7780                    .read(cx)
 7781                    .worktree_for_id(seed.worktree_id, cx)
 7782                else {
 7783                    continue;
 7784                };
 7785                let worktree = worktree_handle.read(cx);
 7786                if !worktree.is_visible() {
 7787                    continue;
 7788                }
 7789
 7790                if !requested_servers.insert(state.id) {
 7791                    continue;
 7792                }
 7793
 7794                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7795                    Some(LanguageServerState::Running {
 7796                        adapter, server, ..
 7797                    }) => (adapter.clone(), server),
 7798
 7799                    _ => continue,
 7800                };
 7801                let supports_workspace_symbol_request =
 7802                    match server.capabilities().workspace_symbol_provider {
 7803                        Some(OneOf::Left(supported)) => supported,
 7804                        Some(OneOf::Right(_)) => true,
 7805                        None => false,
 7806                    };
 7807                if !supports_workspace_symbol_request {
 7808                    continue;
 7809                }
 7810                let worktree_handle = worktree_handle.clone();
 7811                let server_id = server.server_id();
 7812                requests.push(
 7813                        server
 7814                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7815                                lsp::WorkspaceSymbolParams {
 7816                                    query: query.to_string(),
 7817                                    ..Default::default()
 7818                                },
 7819                            )
 7820                            .map(move |response| {
 7821                                let lsp_symbols = response.into_response()
 7822                                    .context("workspace symbols request")
 7823                                    .log_err()
 7824                                    .flatten()
 7825                                    .map(|symbol_response| match symbol_response {
 7826                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7827                                            flat_responses.into_iter().map(|lsp_symbol| {
 7828                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7829                                            }).collect::<Vec<_>>()
 7830                                        }
 7831                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7832                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7833                                                let location = match lsp_symbol.location {
 7834                                                    OneOf::Left(location) => location,
 7835                                                    OneOf::Right(_) => {
 7836                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7837                                                        return None
 7838                                                    }
 7839                                                };
 7840                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7841                                            }).collect::<Vec<_>>()
 7842                                        }
 7843                                    }).unwrap_or_default();
 7844
 7845                                WorkspaceSymbolsResult {
 7846                                    server_id,
 7847                                    lsp_adapter,
 7848                                    worktree: worktree_handle.downgrade(),
 7849                                    lsp_symbols,
 7850                                }
 7851                            }),
 7852                    );
 7853            }
 7854
 7855            cx.spawn(async move |this, cx| {
 7856                let responses = futures::future::join_all(requests).await;
 7857                let this = match this.upgrade() {
 7858                    Some(this) => this,
 7859                    None => return Ok(Vec::new()),
 7860                };
 7861
 7862                let mut symbols = Vec::new();
 7863                for result in responses {
 7864                    let core_symbols = this.update(cx, |this, cx| {
 7865                        result
 7866                            .lsp_symbols
 7867                            .into_iter()
 7868                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7869                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7870                                let source_worktree = result.worktree.upgrade()?;
 7871                                let source_worktree_id = source_worktree.read(cx).id();
 7872
 7873                                let path = if let Some((tree, rel_path)) =
 7874                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7875                                {
 7876                                    let worktree_id = tree.read(cx).id();
 7877                                    SymbolLocation::InProject(ProjectPath {
 7878                                        worktree_id,
 7879                                        path: rel_path,
 7880                                    })
 7881                                } else {
 7882                                    SymbolLocation::OutsideProject {
 7883                                        signature: this.symbol_signature(&abs_path),
 7884                                        abs_path: abs_path.into(),
 7885                                    }
 7886                                };
 7887
 7888                                Some(CoreSymbol {
 7889                                    source_language_server_id: result.server_id,
 7890                                    language_server_name: result.lsp_adapter.name.clone(),
 7891                                    source_worktree_id,
 7892                                    path,
 7893                                    kind: symbol_kind,
 7894                                    name: symbol_name,
 7895                                    range: range_from_lsp(symbol_location.range),
 7896                                })
 7897                            })
 7898                            .collect::<Vec<_>>()
 7899                    });
 7900
 7901                    populate_labels_for_symbols(
 7902                        core_symbols,
 7903                        &language_registry,
 7904                        Some(result.lsp_adapter),
 7905                        &mut symbols,
 7906                    )
 7907                    .await;
 7908                }
 7909
 7910                Ok(symbols)
 7911            })
 7912        } else {
 7913            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7914        }
 7915    }
 7916
 7917    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7918        let mut summary = DiagnosticSummary::default();
 7919        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7920            summary.error_count += path_summary.error_count;
 7921            summary.warning_count += path_summary.warning_count;
 7922        }
 7923        summary
 7924    }
 7925
 7926    /// Returns the diagnostic summary for a specific project path.
 7927    pub fn diagnostic_summary_for_path(
 7928        &self,
 7929        project_path: &ProjectPath,
 7930        _: &App,
 7931    ) -> DiagnosticSummary {
 7932        if let Some(summaries) = self
 7933            .diagnostic_summaries
 7934            .get(&project_path.worktree_id)
 7935            .and_then(|map| map.get(&project_path.path))
 7936        {
 7937            let (error_count, warning_count) = summaries.iter().fold(
 7938                (0, 0),
 7939                |(error_count, warning_count), (_language_server_id, summary)| {
 7940                    (
 7941                        error_count + summary.error_count,
 7942                        warning_count + summary.warning_count,
 7943                    )
 7944                },
 7945            );
 7946
 7947            DiagnosticSummary {
 7948                error_count,
 7949                warning_count,
 7950            }
 7951        } else {
 7952            DiagnosticSummary::default()
 7953        }
 7954    }
 7955
 7956    pub fn diagnostic_summaries<'a>(
 7957        &'a self,
 7958        include_ignored: bool,
 7959        cx: &'a App,
 7960    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7961        self.worktree_store
 7962            .read(cx)
 7963            .visible_worktrees(cx)
 7964            .filter_map(|worktree| {
 7965                let worktree = worktree.read(cx);
 7966                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7967            })
 7968            .flat_map(move |(worktree, summaries)| {
 7969                let worktree_id = worktree.id();
 7970                summaries
 7971                    .iter()
 7972                    .filter(move |(path, _)| {
 7973                        include_ignored
 7974                            || worktree
 7975                                .entry_for_path(path.as_ref())
 7976                                .is_some_and(|entry| !entry.is_ignored)
 7977                    })
 7978                    .flat_map(move |(path, summaries)| {
 7979                        summaries.iter().map(move |(server_id, summary)| {
 7980                            (
 7981                                ProjectPath {
 7982                                    worktree_id,
 7983                                    path: path.clone(),
 7984                                },
 7985                                *server_id,
 7986                                *summary,
 7987                            )
 7988                        })
 7989                    })
 7990            })
 7991    }
 7992
 7993    pub fn on_buffer_edited(
 7994        &mut self,
 7995        buffer: Entity<Buffer>,
 7996        cx: &mut Context<Self>,
 7997    ) -> Option<()> {
 7998        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7999            Some(
 8000                self.as_local()?
 8001                    .language_servers_for_buffer(buffer, cx)
 8002                    .map(|i| i.1.clone())
 8003                    .collect(),
 8004            )
 8005        })?;
 8006
 8007        let buffer = buffer.read(cx);
 8008        let file = File::from_dyn(buffer.file())?;
 8009        let abs_path = file.as_local()?.abs_path(cx);
 8010        let uri = lsp::Uri::from_file_path(&abs_path)
 8011            .ok()
 8012            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 8013            .log_err()?;
 8014        let next_snapshot = buffer.text_snapshot();
 8015        for language_server in language_servers {
 8016            let language_server = language_server.clone();
 8017
 8018            let buffer_snapshots = self
 8019                .as_local_mut()?
 8020                .buffer_snapshots
 8021                .get_mut(&buffer.remote_id())
 8022                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 8023            let previous_snapshot = buffer_snapshots.last()?;
 8024
 8025            let build_incremental_change = || {
 8026                buffer
 8027                    .edits_since::<Dimensions<PointUtf16, usize>>(
 8028                        previous_snapshot.snapshot.version(),
 8029                    )
 8030                    .map(|edit| {
 8031                        let edit_start = edit.new.start.0;
 8032                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 8033                        let new_text = next_snapshot
 8034                            .text_for_range(edit.new.start.1..edit.new.end.1)
 8035                            .collect();
 8036                        lsp::TextDocumentContentChangeEvent {
 8037                            range: Some(lsp::Range::new(
 8038                                point_to_lsp(edit_start),
 8039                                point_to_lsp(edit_end),
 8040                            )),
 8041                            range_length: None,
 8042                            text: new_text,
 8043                        }
 8044                    })
 8045                    .collect()
 8046            };
 8047
 8048            let document_sync_kind = language_server
 8049                .capabilities()
 8050                .text_document_sync
 8051                .as_ref()
 8052                .and_then(|sync| match sync {
 8053                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 8054                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 8055                });
 8056
 8057            let content_changes: Vec<_> = match document_sync_kind {
 8058                Some(lsp::TextDocumentSyncKind::FULL) => {
 8059                    vec![lsp::TextDocumentContentChangeEvent {
 8060                        range: None,
 8061                        range_length: None,
 8062                        text: next_snapshot.text(),
 8063                    }]
 8064                }
 8065                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8066                _ => {
 8067                    #[cfg(any(test, feature = "test-support"))]
 8068                    {
 8069                        build_incremental_change()
 8070                    }
 8071
 8072                    #[cfg(not(any(test, feature = "test-support")))]
 8073                    {
 8074                        continue;
 8075                    }
 8076                }
 8077            };
 8078
 8079            let next_version = previous_snapshot.version + 1;
 8080            buffer_snapshots.push(LspBufferSnapshot {
 8081                version: next_version,
 8082                snapshot: next_snapshot.clone(),
 8083            });
 8084
 8085            language_server
 8086                .notify::<lsp::notification::DidChangeTextDocument>(
 8087                    lsp::DidChangeTextDocumentParams {
 8088                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8089                            uri.clone(),
 8090                            next_version,
 8091                        ),
 8092                        content_changes,
 8093                    },
 8094                )
 8095                .ok();
 8096            self.pull_workspace_diagnostics(language_server.server_id());
 8097        }
 8098
 8099        None
 8100    }
 8101
 8102    pub fn on_buffer_saved(
 8103        &mut self,
 8104        buffer: Entity<Buffer>,
 8105        cx: &mut Context<Self>,
 8106    ) -> Option<()> {
 8107        let file = File::from_dyn(buffer.read(cx).file())?;
 8108        let worktree_id = file.worktree_id(cx);
 8109        let abs_path = file.as_local()?.abs_path(cx);
 8110        let text_document = lsp::TextDocumentIdentifier {
 8111            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8112        };
 8113        let local = self.as_local()?;
 8114
 8115        for server in local.language_servers_for_worktree(worktree_id) {
 8116            if let Some(include_text) = include_text(server.as_ref()) {
 8117                let text = if include_text {
 8118                    Some(buffer.read(cx).text())
 8119                } else {
 8120                    None
 8121                };
 8122                server
 8123                    .notify::<lsp::notification::DidSaveTextDocument>(
 8124                        lsp::DidSaveTextDocumentParams {
 8125                            text_document: text_document.clone(),
 8126                            text,
 8127                        },
 8128                    )
 8129                    .ok();
 8130            }
 8131        }
 8132
 8133        let language_servers = buffer.update(cx, |buffer, cx| {
 8134            local.language_server_ids_for_buffer(buffer, cx)
 8135        });
 8136        for language_server_id in language_servers {
 8137            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8138        }
 8139
 8140        None
 8141    }
 8142
 8143    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8144        maybe!(async move {
 8145            let mut refreshed_servers = HashSet::default();
 8146            let servers = lsp_store
 8147                .update(cx, |lsp_store, cx| {
 8148                    let local = lsp_store.as_local()?;
 8149
 8150                    let servers = local
 8151                        .language_server_ids
 8152                        .iter()
 8153                        .filter_map(|(seed, state)| {
 8154                            let worktree = lsp_store
 8155                                .worktree_store
 8156                                .read(cx)
 8157                                .worktree_for_id(seed.worktree_id, cx);
 8158                            let delegate: Arc<dyn LspAdapterDelegate> =
 8159                                worktree.map(|worktree| {
 8160                                    LocalLspAdapterDelegate::new(
 8161                                        local.languages.clone(),
 8162                                        &local.environment,
 8163                                        cx.weak_entity(),
 8164                                        &worktree,
 8165                                        local.http_client.clone(),
 8166                                        local.fs.clone(),
 8167                                        cx,
 8168                                    )
 8169                                })?;
 8170                            let server_id = state.id;
 8171
 8172                            let states = local.language_servers.get(&server_id)?;
 8173
 8174                            match states {
 8175                                LanguageServerState::Starting { .. } => None,
 8176                                LanguageServerState::Running {
 8177                                    adapter, server, ..
 8178                                } => {
 8179                                    let adapter = adapter.clone();
 8180                                    let server = server.clone();
 8181                                    refreshed_servers.insert(server.name());
 8182                                    let toolchain = seed.toolchain.clone();
 8183                                    Some(cx.spawn(async move |_, cx| {
 8184                                        let settings =
 8185                                            LocalLspStore::workspace_configuration_for_adapter(
 8186                                                adapter.adapter.clone(),
 8187                                                &delegate,
 8188                                                toolchain,
 8189                                                None,
 8190                                                cx,
 8191                                            )
 8192                                            .await
 8193                                            .ok()?;
 8194                                        server
 8195                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8196                                                lsp::DidChangeConfigurationParams { settings },
 8197                                            )
 8198                                            .ok()?;
 8199                                        Some(())
 8200                                    }))
 8201                                }
 8202                            }
 8203                        })
 8204                        .collect::<Vec<_>>();
 8205
 8206                    Some(servers)
 8207                })
 8208                .ok()
 8209                .flatten()?;
 8210
 8211            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8212            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8213            // to stop and unregister its language server wrapper.
 8214            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8215            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8216            let _: Vec<Option<()>> = join_all(servers).await;
 8217
 8218            Some(())
 8219        })
 8220        .await;
 8221    }
 8222
 8223    fn maintain_workspace_config(
 8224        external_refresh_requests: watch::Receiver<()>,
 8225        cx: &mut Context<Self>,
 8226    ) -> Task<Result<()>> {
 8227        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8228        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8229
 8230        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8231            *settings_changed_tx.borrow_mut() = ();
 8232        });
 8233
 8234        let mut joint_future =
 8235            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8236        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8237        // - 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).
 8238        // - 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.
 8239        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8240        // - 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,
 8241        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8242        cx.spawn(async move |this, cx| {
 8243            while let Some(()) = joint_future.next().await {
 8244                this.update(cx, |this, cx| {
 8245                    this.refresh_server_tree(cx);
 8246                })
 8247                .ok();
 8248
 8249                Self::refresh_workspace_configurations(&this, cx).await;
 8250            }
 8251
 8252            drop(settings_observation);
 8253            anyhow::Ok(())
 8254        })
 8255    }
 8256
 8257    pub fn running_language_servers_for_local_buffer<'a>(
 8258        &'a self,
 8259        buffer: &Buffer,
 8260        cx: &mut App,
 8261    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8262        let local = self.as_local();
 8263        let language_server_ids = local
 8264            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8265            .unwrap_or_default();
 8266
 8267        language_server_ids
 8268            .into_iter()
 8269            .filter_map(
 8270                move |server_id| match local?.language_servers.get(&server_id)? {
 8271                    LanguageServerState::Running {
 8272                        adapter, server, ..
 8273                    } => Some((adapter, server)),
 8274                    _ => None,
 8275                },
 8276            )
 8277    }
 8278
 8279    pub fn language_servers_for_local_buffer(
 8280        &self,
 8281        buffer: &Buffer,
 8282        cx: &mut App,
 8283    ) -> Vec<LanguageServerId> {
 8284        let local = self.as_local();
 8285        local
 8286            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8287            .unwrap_or_default()
 8288    }
 8289
 8290    pub fn language_server_for_local_buffer<'a>(
 8291        &'a self,
 8292        buffer: &'a Buffer,
 8293        server_id: LanguageServerId,
 8294        cx: &'a mut App,
 8295    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8296        self.as_local()?
 8297            .language_servers_for_buffer(buffer, cx)
 8298            .find(|(_, s)| s.server_id() == server_id)
 8299    }
 8300
 8301    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8302        self.diagnostic_summaries.remove(&id_to_remove);
 8303        if let Some(local) = self.as_local_mut() {
 8304            let to_remove = local.remove_worktree(id_to_remove, cx);
 8305            for server in to_remove {
 8306                self.language_server_statuses.remove(&server);
 8307            }
 8308        }
 8309    }
 8310
 8311    pub fn shared(
 8312        &mut self,
 8313        project_id: u64,
 8314        downstream_client: AnyProtoClient,
 8315        _: &mut Context<Self>,
 8316    ) {
 8317        self.downstream_client = Some((downstream_client.clone(), project_id));
 8318
 8319        for (server_id, status) in &self.language_server_statuses {
 8320            if let Some(server) = self.language_server_for_id(*server_id) {
 8321                downstream_client
 8322                    .send(proto::StartLanguageServer {
 8323                        project_id,
 8324                        server: Some(proto::LanguageServer {
 8325                            id: server_id.to_proto(),
 8326                            name: status.name.to_string(),
 8327                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8328                        }),
 8329                        capabilities: serde_json::to_string(&server.capabilities())
 8330                            .expect("serializing server LSP capabilities"),
 8331                    })
 8332                    .log_err();
 8333            }
 8334        }
 8335    }
 8336
 8337    pub fn disconnected_from_host(&mut self) {
 8338        self.downstream_client.take();
 8339    }
 8340
 8341    pub fn disconnected_from_ssh_remote(&mut self) {
 8342        if let LspStoreMode::Remote(RemoteLspStore {
 8343            upstream_client, ..
 8344        }) = &mut self.mode
 8345        {
 8346            upstream_client.take();
 8347        }
 8348    }
 8349
 8350    pub(crate) fn set_language_server_statuses_from_proto(
 8351        &mut self,
 8352        project: WeakEntity<Project>,
 8353        language_servers: Vec<proto::LanguageServer>,
 8354        server_capabilities: Vec<String>,
 8355        cx: &mut Context<Self>,
 8356    ) {
 8357        let lsp_logs = cx
 8358            .try_global::<GlobalLogStore>()
 8359            .map(|lsp_store| lsp_store.0.clone());
 8360
 8361        self.language_server_statuses = language_servers
 8362            .into_iter()
 8363            .zip(server_capabilities)
 8364            .map(|(server, server_capabilities)| {
 8365                let server_id = LanguageServerId(server.id as usize);
 8366                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8367                    self.lsp_server_capabilities
 8368                        .insert(server_id, server_capabilities);
 8369                }
 8370
 8371                let name = LanguageServerName::from_proto(server.name);
 8372                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8373
 8374                if let Some(lsp_logs) = &lsp_logs {
 8375                    lsp_logs.update(cx, |lsp_logs, cx| {
 8376                        lsp_logs.add_language_server(
 8377                            // Only remote clients get their language servers set from proto
 8378                            LanguageServerKind::Remote {
 8379                                project: project.clone(),
 8380                            },
 8381                            server_id,
 8382                            Some(name.clone()),
 8383                            worktree,
 8384                            None,
 8385                            cx,
 8386                        );
 8387                    });
 8388                }
 8389
 8390                (
 8391                    server_id,
 8392                    LanguageServerStatus {
 8393                        name,
 8394                        server_version: None,
 8395                        pending_work: Default::default(),
 8396                        has_pending_diagnostic_updates: false,
 8397                        progress_tokens: Default::default(),
 8398                        worktree,
 8399                        binary: None,
 8400                        configuration: None,
 8401                        workspace_folders: BTreeSet::new(),
 8402                    },
 8403                )
 8404            })
 8405            .collect();
 8406    }
 8407
 8408    #[cfg(test)]
 8409    pub fn update_diagnostic_entries(
 8410        &mut self,
 8411        server_id: LanguageServerId,
 8412        abs_path: PathBuf,
 8413        result_id: Option<SharedString>,
 8414        version: Option<i32>,
 8415        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8416        cx: &mut Context<Self>,
 8417    ) -> anyhow::Result<()> {
 8418        self.merge_diagnostic_entries(
 8419            vec![DocumentDiagnosticsUpdate {
 8420                diagnostics: DocumentDiagnostics {
 8421                    diagnostics,
 8422                    document_abs_path: abs_path,
 8423                    version,
 8424                },
 8425                result_id,
 8426                server_id,
 8427                disk_based_sources: Cow::Borrowed(&[]),
 8428                registration_id: None,
 8429            }],
 8430            |_, _, _| false,
 8431            cx,
 8432        )?;
 8433        Ok(())
 8434    }
 8435
 8436    pub fn merge_diagnostic_entries<'a>(
 8437        &mut self,
 8438        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8439        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8440        cx: &mut Context<Self>,
 8441    ) -> anyhow::Result<()> {
 8442        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8443        let mut updated_diagnostics_paths = HashMap::default();
 8444        for mut update in diagnostic_updates {
 8445            let abs_path = &update.diagnostics.document_abs_path;
 8446            let server_id = update.server_id;
 8447            let Some((worktree, relative_path)) =
 8448                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8449            else {
 8450                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8451                return Ok(());
 8452            };
 8453
 8454            let worktree_id = worktree.read(cx).id();
 8455            let project_path = ProjectPath {
 8456                worktree_id,
 8457                path: relative_path,
 8458            };
 8459
 8460            let document_uri = lsp::Uri::from_file_path(abs_path)
 8461                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8462            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8463                let snapshot = buffer_handle.read(cx).snapshot();
 8464                let buffer = buffer_handle.read(cx);
 8465                let reused_diagnostics = buffer
 8466                    .buffer_diagnostics(Some(server_id))
 8467                    .iter()
 8468                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8469                    .map(|v| {
 8470                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8471                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8472                        DiagnosticEntry {
 8473                            range: start..end,
 8474                            diagnostic: v.diagnostic.clone(),
 8475                        }
 8476                    })
 8477                    .collect::<Vec<_>>();
 8478
 8479                self.as_local_mut()
 8480                    .context("cannot merge diagnostics on a remote LspStore")?
 8481                    .update_buffer_diagnostics(
 8482                        &buffer_handle,
 8483                        server_id,
 8484                        Some(update.registration_id),
 8485                        update.result_id,
 8486                        update.diagnostics.version,
 8487                        update.diagnostics.diagnostics.clone(),
 8488                        reused_diagnostics.clone(),
 8489                        cx,
 8490                    )?;
 8491
 8492                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8493            } else if let Some(local) = self.as_local() {
 8494                let reused_diagnostics = local
 8495                    .diagnostics
 8496                    .get(&worktree_id)
 8497                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8498                    .and_then(|diagnostics_by_server_id| {
 8499                        diagnostics_by_server_id
 8500                            .binary_search_by_key(&server_id, |e| e.0)
 8501                            .ok()
 8502                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8503                    })
 8504                    .into_iter()
 8505                    .flatten()
 8506                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8507
 8508                update
 8509                    .diagnostics
 8510                    .diagnostics
 8511                    .extend(reused_diagnostics.cloned());
 8512            }
 8513
 8514            let updated = worktree.update(cx, |worktree, cx| {
 8515                self.update_worktree_diagnostics(
 8516                    worktree.id(),
 8517                    server_id,
 8518                    project_path.path.clone(),
 8519                    update.diagnostics.diagnostics,
 8520                    cx,
 8521                )
 8522            })?;
 8523            match updated {
 8524                ControlFlow::Continue(new_summary) => {
 8525                    if let Some((project_id, new_summary)) = new_summary {
 8526                        match &mut diagnostics_summary {
 8527                            Some(diagnostics_summary) => {
 8528                                diagnostics_summary
 8529                                    .more_summaries
 8530                                    .push(proto::DiagnosticSummary {
 8531                                        path: project_path.path.as_ref().to_proto(),
 8532                                        language_server_id: server_id.0 as u64,
 8533                                        error_count: new_summary.error_count,
 8534                                        warning_count: new_summary.warning_count,
 8535                                    })
 8536                            }
 8537                            None => {
 8538                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8539                                    project_id,
 8540                                    worktree_id: worktree_id.to_proto(),
 8541                                    summary: Some(proto::DiagnosticSummary {
 8542                                        path: project_path.path.as_ref().to_proto(),
 8543                                        language_server_id: server_id.0 as u64,
 8544                                        error_count: new_summary.error_count,
 8545                                        warning_count: new_summary.warning_count,
 8546                                    }),
 8547                                    more_summaries: Vec::new(),
 8548                                })
 8549                            }
 8550                        }
 8551                    }
 8552                    updated_diagnostics_paths
 8553                        .entry(server_id)
 8554                        .or_insert_with(Vec::new)
 8555                        .push(project_path);
 8556                }
 8557                ControlFlow::Break(()) => {}
 8558            }
 8559        }
 8560
 8561        if let Some((diagnostics_summary, (downstream_client, _))) =
 8562            diagnostics_summary.zip(self.downstream_client.as_ref())
 8563        {
 8564            downstream_client.send(diagnostics_summary).log_err();
 8565        }
 8566        for (server_id, paths) in updated_diagnostics_paths {
 8567            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8568        }
 8569        Ok(())
 8570    }
 8571
 8572    fn update_worktree_diagnostics(
 8573        &mut self,
 8574        worktree_id: WorktreeId,
 8575        server_id: LanguageServerId,
 8576        path_in_worktree: Arc<RelPath>,
 8577        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8578        _: &mut Context<Worktree>,
 8579    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8580        let local = match &mut self.mode {
 8581            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8582            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8583        };
 8584
 8585        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8586        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8587        let summaries_by_server_id = summaries_for_tree
 8588            .entry(path_in_worktree.clone())
 8589            .or_default();
 8590
 8591        let old_summary = summaries_by_server_id
 8592            .remove(&server_id)
 8593            .unwrap_or_default();
 8594
 8595        let new_summary = DiagnosticSummary::new(&diagnostics);
 8596        if diagnostics.is_empty() {
 8597            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8598            {
 8599                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8600                    diagnostics_by_server_id.remove(ix);
 8601                }
 8602                if diagnostics_by_server_id.is_empty() {
 8603                    diagnostics_for_tree.remove(&path_in_worktree);
 8604                }
 8605            }
 8606        } else {
 8607            summaries_by_server_id.insert(server_id, new_summary);
 8608            let diagnostics_by_server_id = diagnostics_for_tree
 8609                .entry(path_in_worktree.clone())
 8610                .or_default();
 8611            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8612                Ok(ix) => {
 8613                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8614                }
 8615                Err(ix) => {
 8616                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8617                }
 8618            }
 8619        }
 8620
 8621        if !old_summary.is_empty() || !new_summary.is_empty() {
 8622            if let Some((_, project_id)) = &self.downstream_client {
 8623                Ok(ControlFlow::Continue(Some((
 8624                    *project_id,
 8625                    proto::DiagnosticSummary {
 8626                        path: path_in_worktree.to_proto(),
 8627                        language_server_id: server_id.0 as u64,
 8628                        error_count: new_summary.error_count as u32,
 8629                        warning_count: new_summary.warning_count as u32,
 8630                    },
 8631                ))))
 8632            } else {
 8633                Ok(ControlFlow::Continue(None))
 8634            }
 8635        } else {
 8636            Ok(ControlFlow::Break(()))
 8637        }
 8638    }
 8639
 8640    pub fn open_buffer_for_symbol(
 8641        &mut self,
 8642        symbol: &Symbol,
 8643        cx: &mut Context<Self>,
 8644    ) -> Task<Result<Entity<Buffer>>> {
 8645        if let Some((client, project_id)) = self.upstream_client() {
 8646            let request = client.request(proto::OpenBufferForSymbol {
 8647                project_id,
 8648                symbol: Some(Self::serialize_symbol(symbol)),
 8649            });
 8650            cx.spawn(async move |this, cx| {
 8651                let response = request.await?;
 8652                let buffer_id = BufferId::new(response.buffer_id)?;
 8653                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8654                    .await
 8655            })
 8656        } else if let Some(local) = self.as_local() {
 8657            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8658                seed.worktree_id == symbol.source_worktree_id
 8659                    && state.id == symbol.source_language_server_id
 8660                    && symbol.language_server_name == seed.name
 8661            });
 8662            if !is_valid {
 8663                return Task::ready(Err(anyhow!(
 8664                    "language server for worktree and language not found"
 8665                )));
 8666            };
 8667
 8668            let symbol_abs_path = match &symbol.path {
 8669                SymbolLocation::InProject(project_path) => self
 8670                    .worktree_store
 8671                    .read(cx)
 8672                    .absolutize(&project_path, cx)
 8673                    .context("no such worktree"),
 8674                SymbolLocation::OutsideProject {
 8675                    abs_path,
 8676                    signature: _,
 8677                } => Ok(abs_path.to_path_buf()),
 8678            };
 8679            let symbol_abs_path = match symbol_abs_path {
 8680                Ok(abs_path) => abs_path,
 8681                Err(err) => return Task::ready(Err(err)),
 8682            };
 8683            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8684                uri
 8685            } else {
 8686                return Task::ready(Err(anyhow!("invalid symbol path")));
 8687            };
 8688
 8689            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8690        } else {
 8691            Task::ready(Err(anyhow!("no upstream client or local store")))
 8692        }
 8693    }
 8694
 8695    pub(crate) fn open_local_buffer_via_lsp(
 8696        &mut self,
 8697        abs_path: lsp::Uri,
 8698        language_server_id: LanguageServerId,
 8699        cx: &mut Context<Self>,
 8700    ) -> Task<Result<Entity<Buffer>>> {
 8701        cx.spawn(async move |lsp_store, cx| {
 8702            // Escape percent-encoded string.
 8703            let current_scheme = abs_path.scheme().to_owned();
 8704            // Uri is immutable, so we can't modify the scheme
 8705
 8706            let abs_path = abs_path
 8707                .to_file_path()
 8708                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8709            let p = abs_path.clone();
 8710            let yarn_worktree = lsp_store
 8711                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8712                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8713                        cx.spawn(async move |this, cx| {
 8714                            let t = this
 8715                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8716                                .ok()?;
 8717                            t.await
 8718                        })
 8719                    }),
 8720                    None => Task::ready(None),
 8721                })?
 8722                .await;
 8723            let (worktree_root_target, known_relative_path) =
 8724                if let Some((zip_root, relative_path)) = yarn_worktree {
 8725                    (zip_root, Some(relative_path))
 8726                } else {
 8727                    (Arc::<Path>::from(abs_path.as_path()), None)
 8728                };
 8729            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8730                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8731                    worktree_store.find_worktree(&worktree_root_target, cx)
 8732                })
 8733            })?;
 8734            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8735                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8736                (result.0, relative_path, None)
 8737            } else {
 8738                let worktree = lsp_store
 8739                    .update(cx, |lsp_store, cx| {
 8740                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8741                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8742                        })
 8743                    })?
 8744                    .await?;
 8745                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8746                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8747                    lsp_store
 8748                        .update(cx, |lsp_store, cx| {
 8749                            if let Some(local) = lsp_store.as_local_mut() {
 8750                                local.register_language_server_for_invisible_worktree(
 8751                                    &worktree,
 8752                                    language_server_id,
 8753                                    cx,
 8754                                )
 8755                            }
 8756                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8757                                Some(status) => status.worktree,
 8758                                None => None,
 8759                            }
 8760                        })
 8761                        .ok()
 8762                        .flatten()
 8763                        .zip(Some(worktree_root.clone()))
 8764                } else {
 8765                    None
 8766                };
 8767                let relative_path = if let Some(known_path) = known_relative_path {
 8768                    known_path
 8769                } else {
 8770                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8771                        .into_arc()
 8772                };
 8773                (worktree, relative_path, source_ws)
 8774            };
 8775            let project_path = ProjectPath {
 8776                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8777                path: relative_path,
 8778            };
 8779            let buffer = lsp_store
 8780                .update(cx, |lsp_store, cx| {
 8781                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8782                        buffer_store.open_buffer(project_path, cx)
 8783                    })
 8784                })?
 8785                .await?;
 8786            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8787            if let Some((source_ws, worktree_root)) = source_ws {
 8788                buffer.update(cx, |buffer, cx| {
 8789                    let settings = WorktreeSettings::get(
 8790                        Some(
 8791                            (&ProjectPath {
 8792                                worktree_id: source_ws,
 8793                                path: Arc::from(RelPath::empty()),
 8794                            })
 8795                                .into(),
 8796                        ),
 8797                        cx,
 8798                    );
 8799                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8800                    if is_read_only {
 8801                        buffer.set_capability(Capability::ReadOnly, cx);
 8802                    }
 8803                });
 8804            }
 8805            Ok(buffer)
 8806        })
 8807    }
 8808
 8809    fn request_multiple_lsp_locally<P, R>(
 8810        &mut self,
 8811        buffer: &Entity<Buffer>,
 8812        position: Option<P>,
 8813        request: R,
 8814        cx: &mut Context<Self>,
 8815    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8816    where
 8817        P: ToOffset,
 8818        R: LspCommand + Clone,
 8819        <R::LspRequest as lsp::request::Request>::Result: Send,
 8820        <R::LspRequest as lsp::request::Request>::Params: Send,
 8821    {
 8822        let Some(local) = self.as_local() else {
 8823            return Task::ready(Vec::new());
 8824        };
 8825
 8826        let snapshot = buffer.read(cx).snapshot();
 8827        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8828
 8829        let server_ids = buffer.update(cx, |buffer, cx| {
 8830            local
 8831                .language_servers_for_buffer(buffer, cx)
 8832                .filter(|(adapter, _)| {
 8833                    scope
 8834                        .as_ref()
 8835                        .map(|scope| scope.language_allowed(&adapter.name))
 8836                        .unwrap_or(true)
 8837                })
 8838                .map(|(_, server)| server.server_id())
 8839                .filter(|server_id| {
 8840                    self.as_local().is_none_or(|local| {
 8841                        local
 8842                            .buffers_opened_in_servers
 8843                            .get(&snapshot.remote_id())
 8844                            .is_some_and(|servers| servers.contains(server_id))
 8845                    })
 8846                })
 8847                .collect::<Vec<_>>()
 8848        });
 8849
 8850        let mut response_results = server_ids
 8851            .into_iter()
 8852            .map(|server_id| {
 8853                let task = self.request_lsp(
 8854                    buffer.clone(),
 8855                    LanguageServerToQuery::Other(server_id),
 8856                    request.clone(),
 8857                    cx,
 8858                );
 8859                async move { (server_id, task.await) }
 8860            })
 8861            .collect::<FuturesUnordered<_>>();
 8862
 8863        cx.background_spawn(async move {
 8864            let mut responses = Vec::with_capacity(response_results.len());
 8865            while let Some((server_id, response_result)) = response_results.next().await {
 8866                match response_result {
 8867                    Ok(response) => responses.push((server_id, response)),
 8868                    // rust-analyzer likes to error with this when its still loading up
 8869                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8870                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8871                }
 8872            }
 8873            responses
 8874        })
 8875    }
 8876
 8877    async fn handle_lsp_get_completions(
 8878        this: Entity<Self>,
 8879        envelope: TypedEnvelope<proto::GetCompletions>,
 8880        mut cx: AsyncApp,
 8881    ) -> Result<proto::GetCompletionsResponse> {
 8882        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8883
 8884        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8885        let buffer_handle = this.update(&mut cx, |this, cx| {
 8886            this.buffer_store.read(cx).get_existing(buffer_id)
 8887        })?;
 8888        let request = GetCompletions::from_proto(
 8889            envelope.payload,
 8890            this.clone(),
 8891            buffer_handle.clone(),
 8892            cx.clone(),
 8893        )
 8894        .await?;
 8895
 8896        let server_to_query = match request.server_id {
 8897            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8898            None => LanguageServerToQuery::FirstCapable,
 8899        };
 8900
 8901        let response = this
 8902            .update(&mut cx, |this, cx| {
 8903                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8904            })
 8905            .await?;
 8906        this.update(&mut cx, |this, cx| {
 8907            Ok(GetCompletions::response_to_proto(
 8908                response,
 8909                this,
 8910                sender_id,
 8911                &buffer_handle.read(cx).version(),
 8912                cx,
 8913            ))
 8914        })
 8915    }
 8916
 8917    async fn handle_lsp_command<T: LspCommand>(
 8918        this: Entity<Self>,
 8919        envelope: TypedEnvelope<T::ProtoRequest>,
 8920        mut cx: AsyncApp,
 8921    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8922    where
 8923        <T::LspRequest as lsp::request::Request>::Params: Send,
 8924        <T::LspRequest as lsp::request::Request>::Result: Send,
 8925    {
 8926        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8927        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8928        let buffer_handle = this.update(&mut cx, |this, cx| {
 8929            this.buffer_store.read(cx).get_existing(buffer_id)
 8930        })?;
 8931        let request = T::from_proto(
 8932            envelope.payload,
 8933            this.clone(),
 8934            buffer_handle.clone(),
 8935            cx.clone(),
 8936        )
 8937        .await?;
 8938        let response = this
 8939            .update(&mut cx, |this, cx| {
 8940                this.request_lsp(
 8941                    buffer_handle.clone(),
 8942                    LanguageServerToQuery::FirstCapable,
 8943                    request,
 8944                    cx,
 8945                )
 8946            })
 8947            .await?;
 8948        this.update(&mut cx, |this, cx| {
 8949            Ok(T::response_to_proto(
 8950                response,
 8951                this,
 8952                sender_id,
 8953                &buffer_handle.read(cx).version(),
 8954                cx,
 8955            ))
 8956        })
 8957    }
 8958
 8959    async fn handle_lsp_query(
 8960        lsp_store: Entity<Self>,
 8961        envelope: TypedEnvelope<proto::LspQuery>,
 8962        mut cx: AsyncApp,
 8963    ) -> Result<proto::Ack> {
 8964        use proto::lsp_query::Request;
 8965        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8966        let lsp_query = envelope.payload;
 8967        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8968        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8969        match lsp_query.request.context("invalid LSP query request")? {
 8970            Request::GetReferences(get_references) => {
 8971                let position = get_references.position.clone().and_then(deserialize_anchor);
 8972                Self::query_lsp_locally::<GetReferences>(
 8973                    lsp_store,
 8974                    server_id,
 8975                    sender_id,
 8976                    lsp_request_id,
 8977                    get_references,
 8978                    position,
 8979                    &mut cx,
 8980                )
 8981                .await?;
 8982            }
 8983            Request::GetDocumentColor(get_document_color) => {
 8984                Self::query_lsp_locally::<GetDocumentColor>(
 8985                    lsp_store,
 8986                    server_id,
 8987                    sender_id,
 8988                    lsp_request_id,
 8989                    get_document_color,
 8990                    None,
 8991                    &mut cx,
 8992                )
 8993                .await?;
 8994            }
 8995            Request::GetHover(get_hover) => {
 8996                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8997                Self::query_lsp_locally::<GetHover>(
 8998                    lsp_store,
 8999                    server_id,
 9000                    sender_id,
 9001                    lsp_request_id,
 9002                    get_hover,
 9003                    position,
 9004                    &mut cx,
 9005                )
 9006                .await?;
 9007            }
 9008            Request::GetCodeActions(get_code_actions) => {
 9009                Self::query_lsp_locally::<GetCodeActions>(
 9010                    lsp_store,
 9011                    server_id,
 9012                    sender_id,
 9013                    lsp_request_id,
 9014                    get_code_actions,
 9015                    None,
 9016                    &mut cx,
 9017                )
 9018                .await?;
 9019            }
 9020            Request::GetSignatureHelp(get_signature_help) => {
 9021                let position = get_signature_help
 9022                    .position
 9023                    .clone()
 9024                    .and_then(deserialize_anchor);
 9025                Self::query_lsp_locally::<GetSignatureHelp>(
 9026                    lsp_store,
 9027                    server_id,
 9028                    sender_id,
 9029                    lsp_request_id,
 9030                    get_signature_help,
 9031                    position,
 9032                    &mut cx,
 9033                )
 9034                .await?;
 9035            }
 9036            Request::GetCodeLens(get_code_lens) => {
 9037                Self::query_lsp_locally::<GetCodeLens>(
 9038                    lsp_store,
 9039                    server_id,
 9040                    sender_id,
 9041                    lsp_request_id,
 9042                    get_code_lens,
 9043                    None,
 9044                    &mut cx,
 9045                )
 9046                .await?;
 9047            }
 9048            Request::GetDefinition(get_definition) => {
 9049                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9050                Self::query_lsp_locally::<GetDefinitions>(
 9051                    lsp_store,
 9052                    server_id,
 9053                    sender_id,
 9054                    lsp_request_id,
 9055                    get_definition,
 9056                    position,
 9057                    &mut cx,
 9058                )
 9059                .await?;
 9060            }
 9061            Request::GetDeclaration(get_declaration) => {
 9062                let position = get_declaration
 9063                    .position
 9064                    .clone()
 9065                    .and_then(deserialize_anchor);
 9066                Self::query_lsp_locally::<GetDeclarations>(
 9067                    lsp_store,
 9068                    server_id,
 9069                    sender_id,
 9070                    lsp_request_id,
 9071                    get_declaration,
 9072                    position,
 9073                    &mut cx,
 9074                )
 9075                .await?;
 9076            }
 9077            Request::GetTypeDefinition(get_type_definition) => {
 9078                let position = get_type_definition
 9079                    .position
 9080                    .clone()
 9081                    .and_then(deserialize_anchor);
 9082                Self::query_lsp_locally::<GetTypeDefinitions>(
 9083                    lsp_store,
 9084                    server_id,
 9085                    sender_id,
 9086                    lsp_request_id,
 9087                    get_type_definition,
 9088                    position,
 9089                    &mut cx,
 9090                )
 9091                .await?;
 9092            }
 9093            Request::GetImplementation(get_implementation) => {
 9094                let position = get_implementation
 9095                    .position
 9096                    .clone()
 9097                    .and_then(deserialize_anchor);
 9098                Self::query_lsp_locally::<GetImplementations>(
 9099                    lsp_store,
 9100                    server_id,
 9101                    sender_id,
 9102                    lsp_request_id,
 9103                    get_implementation,
 9104                    position,
 9105                    &mut cx,
 9106                )
 9107                .await?;
 9108            }
 9109            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9110                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 9111                let version = deserialize_version(get_document_diagnostics.buffer_version());
 9112                let buffer = lsp_store.update(&mut cx, |this, cx| {
 9113                    this.buffer_store.read(cx).get_existing(buffer_id)
 9114                })?;
 9115                buffer
 9116                    .update(&mut cx, |buffer, _| {
 9117                        buffer.wait_for_version(version.clone())
 9118                    })
 9119                    .await?;
 9120                lsp_store.update(&mut cx, |lsp_store, cx| {
 9121                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9122                    let key = LspKey {
 9123                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9124                        server_queried: server_id,
 9125                    };
 9126                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9127                    ) {
 9128                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9129                            lsp_requests.clear();
 9130                        };
 9131                    }
 9132
 9133                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 9134                    existing_queries.insert(
 9135                        lsp_request_id,
 9136                        cx.spawn(async move |lsp_store, cx| {
 9137                            let diagnostics_pull = lsp_store.update(cx, |lsp_store, cx| {
 9138                                lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9139                            });
 9140                            if let Ok(diagnostics_pull) = diagnostics_pull {
 9141                                match diagnostics_pull.await {
 9142                                    Ok(()) => {}
 9143                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9144                                };
 9145                            }
 9146                        }),
 9147                    );
 9148                });
 9149            }
 9150            Request::InlayHints(inlay_hints) => {
 9151                let query_start = inlay_hints
 9152                    .start
 9153                    .clone()
 9154                    .and_then(deserialize_anchor)
 9155                    .context("invalid inlay hints range start")?;
 9156                let query_end = inlay_hints
 9157                    .end
 9158                    .clone()
 9159                    .and_then(deserialize_anchor)
 9160                    .context("invalid inlay hints range end")?;
 9161                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9162                    &lsp_store,
 9163                    server_id,
 9164                    lsp_request_id,
 9165                    &inlay_hints,
 9166                    query_start..query_end,
 9167                    &mut cx,
 9168                )
 9169                .await
 9170                .context("preparing inlay hints request")?;
 9171                Self::query_lsp_locally::<InlayHints>(
 9172                    lsp_store,
 9173                    server_id,
 9174                    sender_id,
 9175                    lsp_request_id,
 9176                    inlay_hints,
 9177                    None,
 9178                    &mut cx,
 9179                )
 9180                .await
 9181                .context("querying for inlay hints")?
 9182            }
 9183        }
 9184        Ok(proto::Ack {})
 9185    }
 9186
 9187    async fn handle_lsp_query_response(
 9188        lsp_store: Entity<Self>,
 9189        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9190        cx: AsyncApp,
 9191    ) -> Result<()> {
 9192        lsp_store.read_with(&cx, |lsp_store, _| {
 9193            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9194                upstream_client.handle_lsp_response(envelope.clone());
 9195            }
 9196        });
 9197        Ok(())
 9198    }
 9199
 9200    async fn handle_apply_code_action(
 9201        this: Entity<Self>,
 9202        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9203        mut cx: AsyncApp,
 9204    ) -> Result<proto::ApplyCodeActionResponse> {
 9205        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9206        let action =
 9207            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9208        let apply_code_action = this.update(&mut cx, |this, cx| {
 9209            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9210            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9211            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9212        })?;
 9213
 9214        let project_transaction = apply_code_action.await?;
 9215        let project_transaction = this.update(&mut cx, |this, cx| {
 9216            this.buffer_store.update(cx, |buffer_store, cx| {
 9217                buffer_store.serialize_project_transaction_for_peer(
 9218                    project_transaction,
 9219                    sender_id,
 9220                    cx,
 9221                )
 9222            })
 9223        });
 9224        Ok(proto::ApplyCodeActionResponse {
 9225            transaction: Some(project_transaction),
 9226        })
 9227    }
 9228
 9229    async fn handle_register_buffer_with_language_servers(
 9230        this: Entity<Self>,
 9231        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9232        mut cx: AsyncApp,
 9233    ) -> Result<proto::Ack> {
 9234        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9235        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9236        this.update(&mut cx, |this, cx| {
 9237            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9238                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9239                    project_id: upstream_project_id,
 9240                    buffer_id: buffer_id.to_proto(),
 9241                    only_servers: envelope.payload.only_servers,
 9242                });
 9243            }
 9244
 9245            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9246                anyhow::bail!("buffer is not open");
 9247            };
 9248
 9249            let handle = this.register_buffer_with_language_servers(
 9250                &buffer,
 9251                envelope
 9252                    .payload
 9253                    .only_servers
 9254                    .into_iter()
 9255                    .filter_map(|selector| {
 9256                        Some(match selector.selector? {
 9257                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9258                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9259                            }
 9260                            proto::language_server_selector::Selector::Name(name) => {
 9261                                LanguageServerSelector::Name(LanguageServerName(
 9262                                    SharedString::from(name),
 9263                                ))
 9264                            }
 9265                        })
 9266                    })
 9267                    .collect(),
 9268                false,
 9269                cx,
 9270            );
 9271            this.buffer_store().update(cx, |buffer_store, _| {
 9272                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9273            });
 9274
 9275            Ok(())
 9276        })?;
 9277        Ok(proto::Ack {})
 9278    }
 9279
 9280    async fn handle_rename_project_entry(
 9281        this: Entity<Self>,
 9282        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9283        mut cx: AsyncApp,
 9284    ) -> Result<proto::ProjectEntryResponse> {
 9285        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9286        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9287        let new_path =
 9288            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9289
 9290        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9291            .update(&mut cx, |this, cx| {
 9292                let (worktree, entry) = this
 9293                    .worktree_store
 9294                    .read(cx)
 9295                    .worktree_and_entry_for_id(entry_id, cx)?;
 9296                let new_worktree = this
 9297                    .worktree_store
 9298                    .read(cx)
 9299                    .worktree_for_id(new_worktree_id, cx)?;
 9300                Some((
 9301                    this.worktree_store.clone(),
 9302                    worktree,
 9303                    new_worktree,
 9304                    entry.clone(),
 9305                ))
 9306            })
 9307            .context("worktree not found")?;
 9308        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9309            (worktree.absolutize(&old_entry.path), worktree.id())
 9310        });
 9311        let new_abs_path =
 9312            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9313
 9314        let _transaction = Self::will_rename_entry(
 9315            this.downgrade(),
 9316            old_worktree_id,
 9317            &old_abs_path,
 9318            &new_abs_path,
 9319            old_entry.is_dir(),
 9320            cx.clone(),
 9321        )
 9322        .await;
 9323        let response = WorktreeStore::handle_rename_project_entry(
 9324            worktree_store,
 9325            envelope.payload,
 9326            cx.clone(),
 9327        )
 9328        .await;
 9329        this.read_with(&cx, |this, _| {
 9330            this.did_rename_entry(
 9331                old_worktree_id,
 9332                &old_abs_path,
 9333                &new_abs_path,
 9334                old_entry.is_dir(),
 9335            );
 9336        });
 9337        response
 9338    }
 9339
 9340    async fn handle_update_diagnostic_summary(
 9341        this: Entity<Self>,
 9342        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9343        mut cx: AsyncApp,
 9344    ) -> Result<()> {
 9345        this.update(&mut cx, |lsp_store, cx| {
 9346            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9347            let mut updated_diagnostics_paths = HashMap::default();
 9348            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9349            for message_summary in envelope
 9350                .payload
 9351                .summary
 9352                .into_iter()
 9353                .chain(envelope.payload.more_summaries)
 9354            {
 9355                let project_path = ProjectPath {
 9356                    worktree_id,
 9357                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9358                };
 9359                let path = project_path.path.clone();
 9360                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9361                let summary = DiagnosticSummary {
 9362                    error_count: message_summary.error_count as usize,
 9363                    warning_count: message_summary.warning_count as usize,
 9364                };
 9365
 9366                if summary.is_empty() {
 9367                    if let Some(worktree_summaries) =
 9368                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9369                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9370                    {
 9371                        summaries.remove(&server_id);
 9372                        if summaries.is_empty() {
 9373                            worktree_summaries.remove(&path);
 9374                        }
 9375                    }
 9376                } else {
 9377                    lsp_store
 9378                        .diagnostic_summaries
 9379                        .entry(worktree_id)
 9380                        .or_default()
 9381                        .entry(path)
 9382                        .or_default()
 9383                        .insert(server_id, summary);
 9384                }
 9385
 9386                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9387                    match &mut diagnostics_summary {
 9388                        Some(diagnostics_summary) => {
 9389                            diagnostics_summary
 9390                                .more_summaries
 9391                                .push(proto::DiagnosticSummary {
 9392                                    path: project_path.path.as_ref().to_proto(),
 9393                                    language_server_id: server_id.0 as u64,
 9394                                    error_count: summary.error_count as u32,
 9395                                    warning_count: summary.warning_count as u32,
 9396                                })
 9397                        }
 9398                        None => {
 9399                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9400                                project_id: *project_id,
 9401                                worktree_id: worktree_id.to_proto(),
 9402                                summary: Some(proto::DiagnosticSummary {
 9403                                    path: project_path.path.as_ref().to_proto(),
 9404                                    language_server_id: server_id.0 as u64,
 9405                                    error_count: summary.error_count as u32,
 9406                                    warning_count: summary.warning_count as u32,
 9407                                }),
 9408                                more_summaries: Vec::new(),
 9409                            })
 9410                        }
 9411                    }
 9412                }
 9413                updated_diagnostics_paths
 9414                    .entry(server_id)
 9415                    .or_insert_with(Vec::new)
 9416                    .push(project_path);
 9417            }
 9418
 9419            if let Some((diagnostics_summary, (downstream_client, _))) =
 9420                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9421            {
 9422                downstream_client.send(diagnostics_summary).log_err();
 9423            }
 9424            for (server_id, paths) in updated_diagnostics_paths {
 9425                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9426            }
 9427            Ok(())
 9428        })
 9429    }
 9430
 9431    async fn handle_start_language_server(
 9432        lsp_store: Entity<Self>,
 9433        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9434        mut cx: AsyncApp,
 9435    ) -> Result<()> {
 9436        let server = envelope.payload.server.context("invalid server")?;
 9437        let server_capabilities =
 9438            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9439                .with_context(|| {
 9440                    format!(
 9441                        "incorrect server capabilities {}",
 9442                        envelope.payload.capabilities
 9443                    )
 9444                })?;
 9445        lsp_store.update(&mut cx, |lsp_store, cx| {
 9446            let server_id = LanguageServerId(server.id as usize);
 9447            let server_name = LanguageServerName::from_proto(server.name.clone());
 9448            lsp_store
 9449                .lsp_server_capabilities
 9450                .insert(server_id, server_capabilities);
 9451            lsp_store.language_server_statuses.insert(
 9452                server_id,
 9453                LanguageServerStatus {
 9454                    name: server_name.clone(),
 9455                    server_version: None,
 9456                    pending_work: Default::default(),
 9457                    has_pending_diagnostic_updates: false,
 9458                    progress_tokens: Default::default(),
 9459                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9460                    binary: None,
 9461                    configuration: None,
 9462                    workspace_folders: BTreeSet::new(),
 9463                },
 9464            );
 9465            cx.emit(LspStoreEvent::LanguageServerAdded(
 9466                server_id,
 9467                server_name,
 9468                server.worktree_id.map(WorktreeId::from_proto),
 9469            ));
 9470            cx.notify();
 9471        });
 9472        Ok(())
 9473    }
 9474
 9475    async fn handle_update_language_server(
 9476        lsp_store: Entity<Self>,
 9477        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9478        mut cx: AsyncApp,
 9479    ) -> Result<()> {
 9480        lsp_store.update(&mut cx, |lsp_store, cx| {
 9481            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9482
 9483            match envelope.payload.variant.context("invalid variant")? {
 9484                proto::update_language_server::Variant::WorkStart(payload) => {
 9485                    lsp_store.on_lsp_work_start(
 9486                        language_server_id,
 9487                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9488                            .context("invalid progress token value")?,
 9489                        LanguageServerProgress {
 9490                            title: payload.title,
 9491                            is_disk_based_diagnostics_progress: false,
 9492                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9493                            message: payload.message,
 9494                            percentage: payload.percentage.map(|p| p as usize),
 9495                            last_update_at: cx.background_executor().now(),
 9496                        },
 9497                        cx,
 9498                    );
 9499                }
 9500                proto::update_language_server::Variant::WorkProgress(payload) => {
 9501                    lsp_store.on_lsp_work_progress(
 9502                        language_server_id,
 9503                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9504                            .context("invalid progress token value")?,
 9505                        LanguageServerProgress {
 9506                            title: None,
 9507                            is_disk_based_diagnostics_progress: false,
 9508                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9509                            message: payload.message,
 9510                            percentage: payload.percentage.map(|p| p as usize),
 9511                            last_update_at: cx.background_executor().now(),
 9512                        },
 9513                        cx,
 9514                    );
 9515                }
 9516
 9517                proto::update_language_server::Variant::WorkEnd(payload) => {
 9518                    lsp_store.on_lsp_work_end(
 9519                        language_server_id,
 9520                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9521                            .context("invalid progress token value")?,
 9522                        cx,
 9523                    );
 9524                }
 9525
 9526                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9527                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9528                }
 9529
 9530                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9531                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9532                }
 9533
 9534                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9535                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9536                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9537                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9538                        language_server_id,
 9539                        name: envelope
 9540                            .payload
 9541                            .server_name
 9542                            .map(SharedString::new)
 9543                            .map(LanguageServerName),
 9544                        message: non_lsp,
 9545                    });
 9546                }
 9547            }
 9548
 9549            Ok(())
 9550        })
 9551    }
 9552
 9553    async fn handle_language_server_log(
 9554        this: Entity<Self>,
 9555        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9556        mut cx: AsyncApp,
 9557    ) -> Result<()> {
 9558        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9559        let log_type = envelope
 9560            .payload
 9561            .log_type
 9562            .map(LanguageServerLogType::from_proto)
 9563            .context("invalid language server log type")?;
 9564
 9565        let message = envelope.payload.message;
 9566
 9567        this.update(&mut cx, |_, cx| {
 9568            cx.emit(LspStoreEvent::LanguageServerLog(
 9569                language_server_id,
 9570                log_type,
 9571                message,
 9572            ));
 9573        });
 9574        Ok(())
 9575    }
 9576
 9577    async fn handle_lsp_ext_cancel_flycheck(
 9578        lsp_store: Entity<Self>,
 9579        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9580        cx: AsyncApp,
 9581    ) -> Result<proto::Ack> {
 9582        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9583        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9584            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9585                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9586            } else {
 9587                None
 9588            }
 9589        });
 9590        if let Some(task) = task {
 9591            task.context("handling lsp ext cancel flycheck")?;
 9592        }
 9593
 9594        Ok(proto::Ack {})
 9595    }
 9596
 9597    async fn handle_lsp_ext_run_flycheck(
 9598        lsp_store: Entity<Self>,
 9599        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9600        mut cx: AsyncApp,
 9601    ) -> Result<proto::Ack> {
 9602        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9603        lsp_store.update(&mut cx, |lsp_store, cx| {
 9604            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9605                let text_document = if envelope.payload.current_file_only {
 9606                    let buffer_id = envelope
 9607                        .payload
 9608                        .buffer_id
 9609                        .map(|id| BufferId::new(id))
 9610                        .transpose()?;
 9611                    buffer_id
 9612                        .and_then(|buffer_id| {
 9613                            lsp_store
 9614                                .buffer_store()
 9615                                .read(cx)
 9616                                .get(buffer_id)
 9617                                .and_then(|buffer| {
 9618                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9619                                })
 9620                                .map(|path| make_text_document_identifier(&path))
 9621                        })
 9622                        .transpose()?
 9623                } else {
 9624                    None
 9625                };
 9626                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9627                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9628                )?;
 9629            }
 9630            anyhow::Ok(())
 9631        })?;
 9632
 9633        Ok(proto::Ack {})
 9634    }
 9635
 9636    async fn handle_lsp_ext_clear_flycheck(
 9637        lsp_store: Entity<Self>,
 9638        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9639        cx: AsyncApp,
 9640    ) -> Result<proto::Ack> {
 9641        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9642        lsp_store.read_with(&cx, |lsp_store, _| {
 9643            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9644                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9645            } else {
 9646                None
 9647            }
 9648        });
 9649
 9650        Ok(proto::Ack {})
 9651    }
 9652
 9653    pub fn disk_based_diagnostics_started(
 9654        &mut self,
 9655        language_server_id: LanguageServerId,
 9656        cx: &mut Context<Self>,
 9657    ) {
 9658        if let Some(language_server_status) =
 9659            self.language_server_statuses.get_mut(&language_server_id)
 9660        {
 9661            language_server_status.has_pending_diagnostic_updates = true;
 9662        }
 9663
 9664        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9665        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9666            language_server_id,
 9667            name: self
 9668                .language_server_adapter_for_id(language_server_id)
 9669                .map(|adapter| adapter.name()),
 9670            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9671                Default::default(),
 9672            ),
 9673        })
 9674    }
 9675
 9676    pub fn disk_based_diagnostics_finished(
 9677        &mut self,
 9678        language_server_id: LanguageServerId,
 9679        cx: &mut Context<Self>,
 9680    ) {
 9681        if let Some(language_server_status) =
 9682            self.language_server_statuses.get_mut(&language_server_id)
 9683        {
 9684            language_server_status.has_pending_diagnostic_updates = false;
 9685        }
 9686
 9687        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9688        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9689            language_server_id,
 9690            name: self
 9691                .language_server_adapter_for_id(language_server_id)
 9692                .map(|adapter| adapter.name()),
 9693            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9694                Default::default(),
 9695            ),
 9696        })
 9697    }
 9698
 9699    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9700    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9701    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9702    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9703    // the language server might take some time to publish diagnostics.
 9704    fn simulate_disk_based_diagnostics_events_if_needed(
 9705        &mut self,
 9706        language_server_id: LanguageServerId,
 9707        cx: &mut Context<Self>,
 9708    ) {
 9709        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9710
 9711        let Some(LanguageServerState::Running {
 9712            simulate_disk_based_diagnostics_completion,
 9713            adapter,
 9714            ..
 9715        }) = self
 9716            .as_local_mut()
 9717            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9718        else {
 9719            return;
 9720        };
 9721
 9722        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9723            return;
 9724        }
 9725
 9726        let prev_task =
 9727            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9728                cx.background_executor()
 9729                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9730                    .await;
 9731
 9732                this.update(cx, |this, cx| {
 9733                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9734
 9735                    if let Some(LanguageServerState::Running {
 9736                        simulate_disk_based_diagnostics_completion,
 9737                        ..
 9738                    }) = this.as_local_mut().and_then(|local_store| {
 9739                        local_store.language_servers.get_mut(&language_server_id)
 9740                    }) {
 9741                        *simulate_disk_based_diagnostics_completion = None;
 9742                    }
 9743                })
 9744                .ok();
 9745            }));
 9746
 9747        if prev_task.is_none() {
 9748            self.disk_based_diagnostics_started(language_server_id, cx);
 9749        }
 9750    }
 9751
 9752    pub fn language_server_statuses(
 9753        &self,
 9754    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9755        self.language_server_statuses
 9756            .iter()
 9757            .map(|(key, value)| (*key, value))
 9758    }
 9759
 9760    pub(super) fn did_rename_entry(
 9761        &self,
 9762        worktree_id: WorktreeId,
 9763        old_path: &Path,
 9764        new_path: &Path,
 9765        is_dir: bool,
 9766    ) {
 9767        maybe!({
 9768            let local_store = self.as_local()?;
 9769
 9770            let old_uri = lsp::Uri::from_file_path(old_path)
 9771                .ok()
 9772                .map(|uri| uri.to_string())?;
 9773            let new_uri = lsp::Uri::from_file_path(new_path)
 9774                .ok()
 9775                .map(|uri| uri.to_string())?;
 9776
 9777            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9778                let Some(filter) = local_store
 9779                    .language_server_paths_watched_for_rename
 9780                    .get(&language_server.server_id())
 9781                else {
 9782                    continue;
 9783                };
 9784
 9785                if filter.should_send_did_rename(&old_uri, is_dir) {
 9786                    language_server
 9787                        .notify::<DidRenameFiles>(RenameFilesParams {
 9788                            files: vec![FileRename {
 9789                                old_uri: old_uri.clone(),
 9790                                new_uri: new_uri.clone(),
 9791                            }],
 9792                        })
 9793                        .ok();
 9794                }
 9795            }
 9796            Some(())
 9797        });
 9798    }
 9799
 9800    pub(super) fn will_rename_entry(
 9801        this: WeakEntity<Self>,
 9802        worktree_id: WorktreeId,
 9803        old_path: &Path,
 9804        new_path: &Path,
 9805        is_dir: bool,
 9806        cx: AsyncApp,
 9807    ) -> Task<ProjectTransaction> {
 9808        let old_uri = lsp::Uri::from_file_path(old_path)
 9809            .ok()
 9810            .map(|uri| uri.to_string());
 9811        let new_uri = lsp::Uri::from_file_path(new_path)
 9812            .ok()
 9813            .map(|uri| uri.to_string());
 9814        cx.spawn(async move |cx| {
 9815            let mut tasks = vec![];
 9816            this.update(cx, |this, cx| {
 9817                let local_store = this.as_local()?;
 9818                let old_uri = old_uri?;
 9819                let new_uri = new_uri?;
 9820                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9821                    let Some(filter) = local_store
 9822                        .language_server_paths_watched_for_rename
 9823                        .get(&language_server.server_id())
 9824                    else {
 9825                        continue;
 9826                    };
 9827
 9828                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9829                        let apply_edit = cx.spawn({
 9830                            let old_uri = old_uri.clone();
 9831                            let new_uri = new_uri.clone();
 9832                            let language_server = language_server.clone();
 9833                            async move |this, cx| {
 9834                                let edit = language_server
 9835                                    .request::<WillRenameFiles>(RenameFilesParams {
 9836                                        files: vec![FileRename { old_uri, new_uri }],
 9837                                    })
 9838                                    .await
 9839                                    .into_response()
 9840                                    .context("will rename files")
 9841                                    .log_err()
 9842                                    .flatten()?;
 9843
 9844                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9845                                    this.upgrade()?,
 9846                                    edit,
 9847                                    false,
 9848                                    language_server.clone(),
 9849                                    cx,
 9850                                )
 9851                                .await
 9852                                .ok()?;
 9853                                Some(transaction)
 9854                            }
 9855                        });
 9856                        tasks.push(apply_edit);
 9857                    }
 9858                }
 9859                Some(())
 9860            })
 9861            .ok()
 9862            .flatten();
 9863            let mut merged_transaction = ProjectTransaction::default();
 9864            for task in tasks {
 9865                // Await on tasks sequentially so that the order of application of edits is deterministic
 9866                // (at least with regards to the order of registration of language servers)
 9867                if let Some(transaction) = task.await {
 9868                    for (buffer, buffer_transaction) in transaction.0 {
 9869                        merged_transaction.0.insert(buffer, buffer_transaction);
 9870                    }
 9871                }
 9872            }
 9873            merged_transaction
 9874        })
 9875    }
 9876
 9877    fn lsp_notify_abs_paths_changed(
 9878        &mut self,
 9879        server_id: LanguageServerId,
 9880        changes: Vec<PathEvent>,
 9881    ) {
 9882        maybe!({
 9883            let server = self.language_server_for_id(server_id)?;
 9884            let changes = changes
 9885                .into_iter()
 9886                .filter_map(|event| {
 9887                    let typ = match event.kind? {
 9888                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9889                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9890                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9891                    };
 9892                    Some(lsp::FileEvent {
 9893                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9894                        typ,
 9895                    })
 9896                })
 9897                .collect::<Vec<_>>();
 9898            if !changes.is_empty() {
 9899                server
 9900                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9901                        lsp::DidChangeWatchedFilesParams { changes },
 9902                    )
 9903                    .ok();
 9904            }
 9905            Some(())
 9906        });
 9907    }
 9908
 9909    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9910        self.as_local()?.language_server_for_id(id)
 9911    }
 9912
 9913    fn on_lsp_progress(
 9914        &mut self,
 9915        progress_params: lsp::ProgressParams,
 9916        language_server_id: LanguageServerId,
 9917        disk_based_diagnostics_progress_token: Option<String>,
 9918        cx: &mut Context<Self>,
 9919    ) {
 9920        match progress_params.value {
 9921            lsp::ProgressParamsValue::WorkDone(progress) => {
 9922                self.handle_work_done_progress(
 9923                    progress,
 9924                    language_server_id,
 9925                    disk_based_diagnostics_progress_token,
 9926                    ProgressToken::from_lsp(progress_params.token),
 9927                    cx,
 9928                );
 9929            }
 9930            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9931                let registration_id = match progress_params.token {
 9932                    lsp::NumberOrString::Number(_) => None,
 9933                    lsp::NumberOrString::String(token) => token
 9934                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9935                        .map(|(_, id)| id.to_owned()),
 9936                };
 9937                if let Some(LanguageServerState::Running {
 9938                    workspace_diagnostics_refresh_tasks,
 9939                    ..
 9940                }) = self
 9941                    .as_local_mut()
 9942                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9943                    && let Some(workspace_diagnostics) =
 9944                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9945                {
 9946                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9947                    self.apply_workspace_diagnostic_report(
 9948                        language_server_id,
 9949                        report,
 9950                        registration_id.map(SharedString::from),
 9951                        cx,
 9952                    )
 9953                }
 9954            }
 9955        }
 9956    }
 9957
 9958    fn handle_work_done_progress(
 9959        &mut self,
 9960        progress: lsp::WorkDoneProgress,
 9961        language_server_id: LanguageServerId,
 9962        disk_based_diagnostics_progress_token: Option<String>,
 9963        token: ProgressToken,
 9964        cx: &mut Context<Self>,
 9965    ) {
 9966        let language_server_status =
 9967            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9968                status
 9969            } else {
 9970                return;
 9971            };
 9972
 9973        if !language_server_status.progress_tokens.contains(&token) {
 9974            return;
 9975        }
 9976
 9977        let is_disk_based_diagnostics_progress =
 9978            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9979                (&disk_based_diagnostics_progress_token, &token)
 9980            {
 9981                token.starts_with(disk_based_token)
 9982            } else {
 9983                false
 9984            };
 9985
 9986        match progress {
 9987            lsp::WorkDoneProgress::Begin(report) => {
 9988                if is_disk_based_diagnostics_progress {
 9989                    self.disk_based_diagnostics_started(language_server_id, cx);
 9990                }
 9991                self.on_lsp_work_start(
 9992                    language_server_id,
 9993                    token.clone(),
 9994                    LanguageServerProgress {
 9995                        title: Some(report.title),
 9996                        is_disk_based_diagnostics_progress,
 9997                        is_cancellable: report.cancellable.unwrap_or(false),
 9998                        message: report.message.clone(),
 9999                        percentage: report.percentage.map(|p| p as usize),
10000                        last_update_at: cx.background_executor().now(),
10001                    },
10002                    cx,
10003                );
10004            }
10005            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10006                language_server_id,
10007                token,
10008                LanguageServerProgress {
10009                    title: None,
10010                    is_disk_based_diagnostics_progress,
10011                    is_cancellable: report.cancellable.unwrap_or(false),
10012                    message: report.message,
10013                    percentage: report.percentage.map(|p| p as usize),
10014                    last_update_at: cx.background_executor().now(),
10015                },
10016                cx,
10017            ),
10018            lsp::WorkDoneProgress::End(_) => {
10019                language_server_status.progress_tokens.remove(&token);
10020                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10021                if is_disk_based_diagnostics_progress {
10022                    self.disk_based_diagnostics_finished(language_server_id, cx);
10023                }
10024            }
10025        }
10026    }
10027
10028    fn on_lsp_work_start(
10029        &mut self,
10030        language_server_id: LanguageServerId,
10031        token: ProgressToken,
10032        progress: LanguageServerProgress,
10033        cx: &mut Context<Self>,
10034    ) {
10035        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10036            status.pending_work.insert(token.clone(), progress.clone());
10037            cx.notify();
10038        }
10039        cx.emit(LspStoreEvent::LanguageServerUpdate {
10040            language_server_id,
10041            name: self
10042                .language_server_adapter_for_id(language_server_id)
10043                .map(|adapter| adapter.name()),
10044            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10045                token: Some(token.to_proto()),
10046                title: progress.title,
10047                message: progress.message,
10048                percentage: progress.percentage.map(|p| p as u32),
10049                is_cancellable: Some(progress.is_cancellable),
10050            }),
10051        })
10052    }
10053
10054    fn on_lsp_work_progress(
10055        &mut self,
10056        language_server_id: LanguageServerId,
10057        token: ProgressToken,
10058        progress: LanguageServerProgress,
10059        cx: &mut Context<Self>,
10060    ) {
10061        let mut did_update = false;
10062        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10063            match status.pending_work.entry(token.clone()) {
10064                btree_map::Entry::Vacant(entry) => {
10065                    entry.insert(progress.clone());
10066                    did_update = true;
10067                }
10068                btree_map::Entry::Occupied(mut entry) => {
10069                    let entry = entry.get_mut();
10070                    if (progress.last_update_at - entry.last_update_at)
10071                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10072                    {
10073                        entry.last_update_at = progress.last_update_at;
10074                        if progress.message.is_some() {
10075                            entry.message = progress.message.clone();
10076                        }
10077                        if progress.percentage.is_some() {
10078                            entry.percentage = progress.percentage;
10079                        }
10080                        if progress.is_cancellable != entry.is_cancellable {
10081                            entry.is_cancellable = progress.is_cancellable;
10082                        }
10083                        did_update = true;
10084                    }
10085                }
10086            }
10087        }
10088
10089        if did_update {
10090            cx.emit(LspStoreEvent::LanguageServerUpdate {
10091                language_server_id,
10092                name: self
10093                    .language_server_adapter_for_id(language_server_id)
10094                    .map(|adapter| adapter.name()),
10095                message: proto::update_language_server::Variant::WorkProgress(
10096                    proto::LspWorkProgress {
10097                        token: Some(token.to_proto()),
10098                        message: progress.message,
10099                        percentage: progress.percentage.map(|p| p as u32),
10100                        is_cancellable: Some(progress.is_cancellable),
10101                    },
10102                ),
10103            })
10104        }
10105    }
10106
10107    fn on_lsp_work_end(
10108        &mut self,
10109        language_server_id: LanguageServerId,
10110        token: ProgressToken,
10111        cx: &mut Context<Self>,
10112    ) {
10113        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10114            if let Some(work) = status.pending_work.remove(&token)
10115                && !work.is_disk_based_diagnostics_progress
10116            {
10117                cx.emit(LspStoreEvent::RefreshInlayHints {
10118                    server_id: language_server_id,
10119                    request_id: None,
10120                });
10121            }
10122            cx.notify();
10123        }
10124
10125        cx.emit(LspStoreEvent::LanguageServerUpdate {
10126            language_server_id,
10127            name: self
10128                .language_server_adapter_for_id(language_server_id)
10129                .map(|adapter| adapter.name()),
10130            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10131                token: Some(token.to_proto()),
10132            }),
10133        })
10134    }
10135
10136    pub async fn handle_resolve_completion_documentation(
10137        this: Entity<Self>,
10138        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10139        mut cx: AsyncApp,
10140    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10141        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10142
10143        let completion = this
10144            .read_with(&cx, |this, cx| {
10145                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10146                let server = this
10147                    .language_server_for_id(id)
10148                    .with_context(|| format!("No language server {id}"))?;
10149
10150                anyhow::Ok(cx.background_spawn(async move {
10151                    let can_resolve = server
10152                        .capabilities()
10153                        .completion_provider
10154                        .as_ref()
10155                        .and_then(|options| options.resolve_provider)
10156                        .unwrap_or(false);
10157                    if can_resolve {
10158                        server
10159                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
10160                            .await
10161                            .into_response()
10162                            .context("resolve completion item")
10163                    } else {
10164                        anyhow::Ok(lsp_completion)
10165                    }
10166                }))
10167            })?
10168            .await?;
10169
10170        let mut documentation_is_markdown = false;
10171        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10172        let documentation = match completion.documentation {
10173            Some(lsp::Documentation::String(text)) => text,
10174
10175            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10176                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10177                value
10178            }
10179
10180            _ => String::new(),
10181        };
10182
10183        // If we have a new buffer_id, that means we're talking to a new client
10184        // and want to check for new text_edits in the completion too.
10185        let mut old_replace_start = None;
10186        let mut old_replace_end = None;
10187        let mut old_insert_start = None;
10188        let mut old_insert_end = None;
10189        let mut new_text = String::default();
10190        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10191            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10192                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10193                anyhow::Ok(buffer.read(cx).snapshot())
10194            })?;
10195
10196            if let Some(text_edit) = completion.text_edit.as_ref() {
10197                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10198
10199                if let Some(mut edit) = edit {
10200                    LineEnding::normalize(&mut edit.new_text);
10201
10202                    new_text = edit.new_text;
10203                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10204                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10205                    if let Some(insert_range) = edit.insert_range {
10206                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10207                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10208                    }
10209                }
10210            }
10211        }
10212
10213        Ok(proto::ResolveCompletionDocumentationResponse {
10214            documentation,
10215            documentation_is_markdown,
10216            old_replace_start,
10217            old_replace_end,
10218            new_text,
10219            lsp_completion,
10220            old_insert_start,
10221            old_insert_end,
10222        })
10223    }
10224
10225    async fn handle_on_type_formatting(
10226        this: Entity<Self>,
10227        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10228        mut cx: AsyncApp,
10229    ) -> Result<proto::OnTypeFormattingResponse> {
10230        let on_type_formatting = this.update(&mut cx, |this, cx| {
10231            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10232            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10233            let position = envelope
10234                .payload
10235                .position
10236                .and_then(deserialize_anchor)
10237                .context("invalid position")?;
10238            anyhow::Ok(this.apply_on_type_formatting(
10239                buffer,
10240                position,
10241                envelope.payload.trigger.clone(),
10242                cx,
10243            ))
10244        })?;
10245
10246        let transaction = on_type_formatting
10247            .await?
10248            .as_ref()
10249            .map(language::proto::serialize_transaction);
10250        Ok(proto::OnTypeFormattingResponse { transaction })
10251    }
10252
10253    async fn handle_refresh_inlay_hints(
10254        lsp_store: Entity<Self>,
10255        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10256        mut cx: AsyncApp,
10257    ) -> Result<proto::Ack> {
10258        lsp_store.update(&mut cx, |_, cx| {
10259            cx.emit(LspStoreEvent::RefreshInlayHints {
10260                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10261                request_id: envelope.payload.request_id.map(|id| id as usize),
10262            });
10263        });
10264        Ok(proto::Ack {})
10265    }
10266
10267    async fn handle_pull_workspace_diagnostics(
10268        lsp_store: Entity<Self>,
10269        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10270        mut cx: AsyncApp,
10271    ) -> Result<proto::Ack> {
10272        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10273        lsp_store.update(&mut cx, |lsp_store, _| {
10274            lsp_store.pull_workspace_diagnostics(server_id);
10275        });
10276        Ok(proto::Ack {})
10277    }
10278
10279    async fn handle_get_color_presentation(
10280        lsp_store: Entity<Self>,
10281        envelope: TypedEnvelope<proto::GetColorPresentation>,
10282        mut cx: AsyncApp,
10283    ) -> Result<proto::GetColorPresentationResponse> {
10284        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10285        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10286            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10287        })?;
10288
10289        let color = envelope
10290            .payload
10291            .color
10292            .context("invalid color resolve request")?;
10293        let start = color
10294            .lsp_range_start
10295            .context("invalid color resolve request")?;
10296        let end = color
10297            .lsp_range_end
10298            .context("invalid color resolve request")?;
10299
10300        let color = DocumentColor {
10301            lsp_range: lsp::Range {
10302                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10303                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10304            },
10305            color: lsp::Color {
10306                red: color.red,
10307                green: color.green,
10308                blue: color.blue,
10309                alpha: color.alpha,
10310            },
10311            resolved: false,
10312            color_presentations: Vec::new(),
10313        };
10314        let resolved_color = lsp_store
10315            .update(&mut cx, |lsp_store, cx| {
10316                lsp_store.resolve_color_presentation(
10317                    color,
10318                    buffer.clone(),
10319                    LanguageServerId(envelope.payload.server_id as usize),
10320                    cx,
10321                )
10322            })
10323            .await
10324            .context("resolving color presentation")?;
10325
10326        Ok(proto::GetColorPresentationResponse {
10327            presentations: resolved_color
10328                .color_presentations
10329                .into_iter()
10330                .map(|presentation| proto::ColorPresentation {
10331                    label: presentation.label.to_string(),
10332                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10333                    additional_text_edits: presentation
10334                        .additional_text_edits
10335                        .into_iter()
10336                        .map(serialize_lsp_edit)
10337                        .collect(),
10338                })
10339                .collect(),
10340        })
10341    }
10342
10343    async fn handle_resolve_inlay_hint(
10344        lsp_store: Entity<Self>,
10345        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10346        mut cx: AsyncApp,
10347    ) -> Result<proto::ResolveInlayHintResponse> {
10348        let proto_hint = envelope
10349            .payload
10350            .hint
10351            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10352        let hint = InlayHints::proto_to_project_hint(proto_hint)
10353            .context("resolved proto inlay hint conversion")?;
10354        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10355            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10356            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10357        })?;
10358        let response_hint = lsp_store
10359            .update(&mut cx, |lsp_store, cx| {
10360                lsp_store.resolve_inlay_hint(
10361                    hint,
10362                    buffer,
10363                    LanguageServerId(envelope.payload.language_server_id as usize),
10364                    cx,
10365                )
10366            })
10367            .await
10368            .context("inlay hints fetch")?;
10369        Ok(proto::ResolveInlayHintResponse {
10370            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10371        })
10372    }
10373
10374    async fn handle_refresh_code_lens(
10375        this: Entity<Self>,
10376        _: TypedEnvelope<proto::RefreshCodeLens>,
10377        mut cx: AsyncApp,
10378    ) -> Result<proto::Ack> {
10379        this.update(&mut cx, |_, cx| {
10380            cx.emit(LspStoreEvent::RefreshCodeLens);
10381        });
10382        Ok(proto::Ack {})
10383    }
10384
10385    async fn handle_open_buffer_for_symbol(
10386        this: Entity<Self>,
10387        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10388        mut cx: AsyncApp,
10389    ) -> Result<proto::OpenBufferForSymbolResponse> {
10390        let peer_id = envelope.original_sender_id().unwrap_or_default();
10391        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10392        let symbol = Self::deserialize_symbol(symbol)?;
10393        this.read_with(&cx, |this, _| {
10394            if let SymbolLocation::OutsideProject {
10395                abs_path,
10396                signature,
10397            } = &symbol.path
10398            {
10399                let new_signature = this.symbol_signature(&abs_path);
10400                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10401            }
10402            Ok(())
10403        })?;
10404        let buffer = this
10405            .update(&mut cx, |this, cx| {
10406                this.open_buffer_for_symbol(
10407                    &Symbol {
10408                        language_server_name: symbol.language_server_name,
10409                        source_worktree_id: symbol.source_worktree_id,
10410                        source_language_server_id: symbol.source_language_server_id,
10411                        path: symbol.path,
10412                        name: symbol.name,
10413                        kind: symbol.kind,
10414                        range: symbol.range,
10415                        label: CodeLabel::default(),
10416                    },
10417                    cx,
10418                )
10419            })
10420            .await?;
10421
10422        this.update(&mut cx, |this, cx| {
10423            let is_private = buffer
10424                .read(cx)
10425                .file()
10426                .map(|f| f.is_private())
10427                .unwrap_or_default();
10428            if is_private {
10429                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10430            } else {
10431                this.buffer_store
10432                    .update(cx, |buffer_store, cx| {
10433                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10434                    })
10435                    .detach_and_log_err(cx);
10436                let buffer_id = buffer.read(cx).remote_id().to_proto();
10437                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10438            }
10439        })
10440    }
10441
10442    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10443        let mut hasher = Sha256::new();
10444        hasher.update(abs_path.to_string_lossy().as_bytes());
10445        hasher.update(self.nonce.to_be_bytes());
10446        hasher.finalize().as_slice().try_into().unwrap()
10447    }
10448
10449    pub async fn handle_get_project_symbols(
10450        this: Entity<Self>,
10451        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10452        mut cx: AsyncApp,
10453    ) -> Result<proto::GetProjectSymbolsResponse> {
10454        let symbols = this
10455            .update(&mut cx, |this, cx| {
10456                this.symbols(&envelope.payload.query, cx)
10457            })
10458            .await?;
10459
10460        Ok(proto::GetProjectSymbolsResponse {
10461            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10462        })
10463    }
10464
10465    pub async fn handle_restart_language_servers(
10466        this: Entity<Self>,
10467        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10468        mut cx: AsyncApp,
10469    ) -> Result<proto::Ack> {
10470        this.update(&mut cx, |lsp_store, cx| {
10471            let buffers =
10472                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10473            lsp_store.restart_language_servers_for_buffers(
10474                buffers,
10475                envelope
10476                    .payload
10477                    .only_servers
10478                    .into_iter()
10479                    .filter_map(|selector| {
10480                        Some(match selector.selector? {
10481                            proto::language_server_selector::Selector::ServerId(server_id) => {
10482                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10483                            }
10484                            proto::language_server_selector::Selector::Name(name) => {
10485                                LanguageServerSelector::Name(LanguageServerName(
10486                                    SharedString::from(name),
10487                                ))
10488                            }
10489                        })
10490                    })
10491                    .collect(),
10492                cx,
10493            );
10494        });
10495
10496        Ok(proto::Ack {})
10497    }
10498
10499    pub async fn handle_stop_language_servers(
10500        lsp_store: Entity<Self>,
10501        envelope: TypedEnvelope<proto::StopLanguageServers>,
10502        mut cx: AsyncApp,
10503    ) -> Result<proto::Ack> {
10504        lsp_store.update(&mut cx, |lsp_store, cx| {
10505            if envelope.payload.all
10506                && envelope.payload.also_servers.is_empty()
10507                && envelope.payload.buffer_ids.is_empty()
10508            {
10509                lsp_store.stop_all_language_servers(cx);
10510            } else {
10511                let buffers =
10512                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10513                lsp_store
10514                    .stop_language_servers_for_buffers(
10515                        buffers,
10516                        envelope
10517                            .payload
10518                            .also_servers
10519                            .into_iter()
10520                            .filter_map(|selector| {
10521                                Some(match selector.selector? {
10522                                    proto::language_server_selector::Selector::ServerId(
10523                                        server_id,
10524                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10525                                        server_id,
10526                                    )),
10527                                    proto::language_server_selector::Selector::Name(name) => {
10528                                        LanguageServerSelector::Name(LanguageServerName(
10529                                            SharedString::from(name),
10530                                        ))
10531                                    }
10532                                })
10533                            })
10534                            .collect(),
10535                        cx,
10536                    )
10537                    .detach_and_log_err(cx);
10538            }
10539        });
10540
10541        Ok(proto::Ack {})
10542    }
10543
10544    pub async fn handle_cancel_language_server_work(
10545        lsp_store: Entity<Self>,
10546        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10547        mut cx: AsyncApp,
10548    ) -> Result<proto::Ack> {
10549        lsp_store.update(&mut cx, |lsp_store, cx| {
10550            if let Some(work) = envelope.payload.work {
10551                match work {
10552                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10553                        let buffers =
10554                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10555                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10556                    }
10557                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10558                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10559                        let token = work
10560                            .token
10561                            .map(|token| {
10562                                ProgressToken::from_proto(token)
10563                                    .context("invalid work progress token")
10564                            })
10565                            .transpose()?;
10566                        lsp_store.cancel_language_server_work(server_id, token, cx);
10567                    }
10568                }
10569            }
10570            anyhow::Ok(())
10571        })?;
10572
10573        Ok(proto::Ack {})
10574    }
10575
10576    fn buffer_ids_to_buffers(
10577        &mut self,
10578        buffer_ids: impl Iterator<Item = u64>,
10579        cx: &mut Context<Self>,
10580    ) -> Vec<Entity<Buffer>> {
10581        buffer_ids
10582            .into_iter()
10583            .flat_map(|buffer_id| {
10584                self.buffer_store
10585                    .read(cx)
10586                    .get(BufferId::new(buffer_id).log_err()?)
10587            })
10588            .collect::<Vec<_>>()
10589    }
10590
10591    async fn handle_apply_additional_edits_for_completion(
10592        this: Entity<Self>,
10593        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10594        mut cx: AsyncApp,
10595    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10596        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10597            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10598            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10599            let completion = Self::deserialize_completion(
10600                envelope.payload.completion.context("invalid completion")?,
10601            )?;
10602            anyhow::Ok((buffer, completion))
10603        })?;
10604
10605        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10606            this.apply_additional_edits_for_completion(
10607                buffer,
10608                Rc::new(RefCell::new(Box::new([Completion {
10609                    replace_range: completion.replace_range,
10610                    new_text: completion.new_text,
10611                    source: completion.source,
10612                    documentation: None,
10613                    label: CodeLabel::default(),
10614                    match_start: None,
10615                    snippet_deduplication_key: None,
10616                    insert_text_mode: None,
10617                    icon_path: None,
10618                    confirm: None,
10619                }]))),
10620                0,
10621                false,
10622                cx,
10623            )
10624        });
10625
10626        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10627            transaction: apply_additional_edits
10628                .await?
10629                .as_ref()
10630                .map(language::proto::serialize_transaction),
10631        })
10632    }
10633
10634    pub fn last_formatting_failure(&self) -> Option<&str> {
10635        self.last_formatting_failure.as_deref()
10636    }
10637
10638    pub fn reset_last_formatting_failure(&mut self) {
10639        self.last_formatting_failure = None;
10640    }
10641
10642    pub fn environment_for_buffer(
10643        &self,
10644        buffer: &Entity<Buffer>,
10645        cx: &mut Context<Self>,
10646    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10647        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10648            environment.update(cx, |env, cx| {
10649                env.buffer_environment(buffer, &self.worktree_store, cx)
10650            })
10651        } else {
10652            Task::ready(None).shared()
10653        }
10654    }
10655
10656    pub fn format(
10657        &mut self,
10658        buffers: HashSet<Entity<Buffer>>,
10659        target: LspFormatTarget,
10660        push_to_history: bool,
10661        trigger: FormatTrigger,
10662        cx: &mut Context<Self>,
10663    ) -> Task<anyhow::Result<ProjectTransaction>> {
10664        let logger = zlog::scoped!("format");
10665        if self.as_local().is_some() {
10666            zlog::trace!(logger => "Formatting locally");
10667            let logger = zlog::scoped!(logger => "local");
10668            let buffers = buffers
10669                .into_iter()
10670                .map(|buffer_handle| {
10671                    let buffer = buffer_handle.read(cx);
10672                    let buffer_abs_path = File::from_dyn(buffer.file())
10673                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10674
10675                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10676                })
10677                .collect::<Vec<_>>();
10678
10679            cx.spawn(async move |lsp_store, cx| {
10680                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10681
10682                for (handle, abs_path, id) in buffers {
10683                    let env = lsp_store
10684                        .update(cx, |lsp_store, cx| {
10685                            lsp_store.environment_for_buffer(&handle, cx)
10686                        })?
10687                        .await;
10688
10689                    let ranges = match &target {
10690                        LspFormatTarget::Buffers => None,
10691                        LspFormatTarget::Ranges(ranges) => {
10692                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10693                        }
10694                    };
10695
10696                    formattable_buffers.push(FormattableBuffer {
10697                        handle,
10698                        abs_path,
10699                        env,
10700                        ranges,
10701                    });
10702                }
10703                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10704
10705                let format_timer = zlog::time!(logger => "Formatting buffers");
10706                let result = LocalLspStore::format_locally(
10707                    lsp_store.clone(),
10708                    formattable_buffers,
10709                    push_to_history,
10710                    trigger,
10711                    logger,
10712                    cx,
10713                )
10714                .await;
10715                format_timer.end();
10716
10717                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10718
10719                lsp_store.update(cx, |lsp_store, _| {
10720                    lsp_store.update_last_formatting_failure(&result);
10721                })?;
10722
10723                result
10724            })
10725        } else if let Some((client, project_id)) = self.upstream_client() {
10726            zlog::trace!(logger => "Formatting remotely");
10727            let logger = zlog::scoped!(logger => "remote");
10728            // Don't support formatting ranges via remote
10729            match target {
10730                LspFormatTarget::Buffers => {}
10731                LspFormatTarget::Ranges(_) => {
10732                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10733                    return Task::ready(Ok(ProjectTransaction::default()));
10734                }
10735            }
10736
10737            let buffer_store = self.buffer_store();
10738            cx.spawn(async move |lsp_store, cx| {
10739                zlog::trace!(logger => "Sending remote format request");
10740                let request_timer = zlog::time!(logger => "remote format request");
10741                let result = client
10742                    .request(proto::FormatBuffers {
10743                        project_id,
10744                        trigger: trigger as i32,
10745                        buffer_ids: buffers
10746                            .iter()
10747                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10748                            .collect(),
10749                    })
10750                    .await
10751                    .and_then(|result| result.transaction.context("missing transaction"));
10752                request_timer.end();
10753
10754                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10755
10756                lsp_store.update(cx, |lsp_store, _| {
10757                    lsp_store.update_last_formatting_failure(&result);
10758                })?;
10759
10760                let transaction_response = result?;
10761                let _timer = zlog::time!(logger => "deserializing project transaction");
10762                buffer_store
10763                    .update(cx, |buffer_store, cx| {
10764                        buffer_store.deserialize_project_transaction(
10765                            transaction_response,
10766                            push_to_history,
10767                            cx,
10768                        )
10769                    })
10770                    .await
10771            })
10772        } else {
10773            zlog::trace!(logger => "Not formatting");
10774            Task::ready(Ok(ProjectTransaction::default()))
10775        }
10776    }
10777
10778    async fn handle_format_buffers(
10779        this: Entity<Self>,
10780        envelope: TypedEnvelope<proto::FormatBuffers>,
10781        mut cx: AsyncApp,
10782    ) -> Result<proto::FormatBuffersResponse> {
10783        let sender_id = envelope.original_sender_id().unwrap_or_default();
10784        let format = this.update(&mut cx, |this, cx| {
10785            let mut buffers = HashSet::default();
10786            for buffer_id in &envelope.payload.buffer_ids {
10787                let buffer_id = BufferId::new(*buffer_id)?;
10788                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10789            }
10790            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10791            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10792        })?;
10793
10794        let project_transaction = format.await?;
10795        let project_transaction = this.update(&mut cx, |this, cx| {
10796            this.buffer_store.update(cx, |buffer_store, cx| {
10797                buffer_store.serialize_project_transaction_for_peer(
10798                    project_transaction,
10799                    sender_id,
10800                    cx,
10801                )
10802            })
10803        });
10804        Ok(proto::FormatBuffersResponse {
10805            transaction: Some(project_transaction),
10806        })
10807    }
10808
10809    async fn handle_apply_code_action_kind(
10810        this: Entity<Self>,
10811        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10812        mut cx: AsyncApp,
10813    ) -> Result<proto::ApplyCodeActionKindResponse> {
10814        let sender_id = envelope.original_sender_id().unwrap_or_default();
10815        let format = this.update(&mut cx, |this, cx| {
10816            let mut buffers = HashSet::default();
10817            for buffer_id in &envelope.payload.buffer_ids {
10818                let buffer_id = BufferId::new(*buffer_id)?;
10819                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10820            }
10821            let kind = match envelope.payload.kind.as_str() {
10822                "" => CodeActionKind::EMPTY,
10823                "quickfix" => CodeActionKind::QUICKFIX,
10824                "refactor" => CodeActionKind::REFACTOR,
10825                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10826                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10827                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10828                "source" => CodeActionKind::SOURCE,
10829                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10830                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10831                _ => anyhow::bail!(
10832                    "Invalid code action kind {}",
10833                    envelope.payload.kind.as_str()
10834                ),
10835            };
10836            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10837        })?;
10838
10839        let project_transaction = format.await?;
10840        let project_transaction = this.update(&mut cx, |this, cx| {
10841            this.buffer_store.update(cx, |buffer_store, cx| {
10842                buffer_store.serialize_project_transaction_for_peer(
10843                    project_transaction,
10844                    sender_id,
10845                    cx,
10846                )
10847            })
10848        });
10849        Ok(proto::ApplyCodeActionKindResponse {
10850            transaction: Some(project_transaction),
10851        })
10852    }
10853
10854    async fn shutdown_language_server(
10855        server_state: Option<LanguageServerState>,
10856        name: LanguageServerName,
10857        cx: &mut AsyncApp,
10858    ) {
10859        let server = match server_state {
10860            Some(LanguageServerState::Starting { startup, .. }) => {
10861                let mut timer = cx
10862                    .background_executor()
10863                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10864                    .fuse();
10865
10866                select! {
10867                    server = startup.fuse() => server,
10868                    () = timer => {
10869                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10870                        None
10871                    },
10872                }
10873            }
10874
10875            Some(LanguageServerState::Running { server, .. }) => Some(server),
10876
10877            None => None,
10878        };
10879
10880        if let Some(server) = server
10881            && let Some(shutdown) = server.shutdown()
10882        {
10883            shutdown.await;
10884        }
10885    }
10886
10887    // Returns a list of all of the worktrees which no longer have a language server and the root path
10888    // for the stopped server
10889    fn stop_local_language_server(
10890        &mut self,
10891        server_id: LanguageServerId,
10892        cx: &mut Context<Self>,
10893    ) -> Task<()> {
10894        let local = match &mut self.mode {
10895            LspStoreMode::Local(local) => local,
10896            _ => {
10897                return Task::ready(());
10898            }
10899        };
10900
10901        // Remove this server ID from all entries in the given worktree.
10902        local
10903            .language_server_ids
10904            .retain(|_, state| state.id != server_id);
10905        self.buffer_store.update(cx, |buffer_store, cx| {
10906            for buffer in buffer_store.buffers() {
10907                buffer.update(cx, |buffer, cx| {
10908                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10909                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10910                });
10911            }
10912        });
10913
10914        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10915            summaries.retain(|path, summaries_by_server_id| {
10916                if summaries_by_server_id.remove(&server_id).is_some() {
10917                    if let Some((client, project_id)) = self.downstream_client.clone() {
10918                        client
10919                            .send(proto::UpdateDiagnosticSummary {
10920                                project_id,
10921                                worktree_id: worktree_id.to_proto(),
10922                                summary: Some(proto::DiagnosticSummary {
10923                                    path: path.as_ref().to_proto(),
10924                                    language_server_id: server_id.0 as u64,
10925                                    error_count: 0,
10926                                    warning_count: 0,
10927                                }),
10928                                more_summaries: Vec::new(),
10929                            })
10930                            .log_err();
10931                    }
10932                    !summaries_by_server_id.is_empty()
10933                } else {
10934                    true
10935                }
10936            });
10937        }
10938
10939        let local = self.as_local_mut().unwrap();
10940        for diagnostics in local.diagnostics.values_mut() {
10941            diagnostics.retain(|_, diagnostics_by_server_id| {
10942                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10943                    diagnostics_by_server_id.remove(ix);
10944                    !diagnostics_by_server_id.is_empty()
10945                } else {
10946                    true
10947                }
10948            });
10949        }
10950        local.language_server_watched_paths.remove(&server_id);
10951
10952        let server_state = local.language_servers.remove(&server_id);
10953        self.cleanup_lsp_data(server_id);
10954        let name = self
10955            .language_server_statuses
10956            .remove(&server_id)
10957            .map(|status| status.name)
10958            .or_else(|| {
10959                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10960                    Some(adapter.name())
10961                } else {
10962                    None
10963                }
10964            });
10965
10966        if let Some(name) = name {
10967            log::info!("stopping language server {name}");
10968            self.languages
10969                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10970            cx.notify();
10971
10972            return cx.spawn(async move |lsp_store, cx| {
10973                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10974                lsp_store
10975                    .update(cx, |lsp_store, cx| {
10976                        lsp_store
10977                            .languages
10978                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10979                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10980                        cx.notify();
10981                    })
10982                    .ok();
10983            });
10984        }
10985
10986        if server_state.is_some() {
10987            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10988        }
10989        Task::ready(())
10990    }
10991
10992    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10993        if let Some((client, project_id)) = self.upstream_client() {
10994            let request = client.request(proto::StopLanguageServers {
10995                project_id,
10996                buffer_ids: Vec::new(),
10997                also_servers: Vec::new(),
10998                all: true,
10999            });
11000            cx.background_spawn(request).detach_and_log_err(cx);
11001        } else {
11002            let Some(local) = self.as_local_mut() else {
11003                return;
11004            };
11005            let language_servers_to_stop = local
11006                .language_server_ids
11007                .values()
11008                .map(|state| state.id)
11009                .collect();
11010            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11011            let tasks = language_servers_to_stop
11012                .into_iter()
11013                .map(|server| self.stop_local_language_server(server, cx))
11014                .collect::<Vec<_>>();
11015            cx.background_spawn(async move {
11016                futures::future::join_all(tasks).await;
11017            })
11018            .detach();
11019        }
11020    }
11021
11022    pub fn restart_language_servers_for_buffers(
11023        &mut self,
11024        buffers: Vec<Entity<Buffer>>,
11025        only_restart_servers: HashSet<LanguageServerSelector>,
11026        cx: &mut Context<Self>,
11027    ) {
11028        if let Some((client, project_id)) = self.upstream_client() {
11029            let request = client.request(proto::RestartLanguageServers {
11030                project_id,
11031                buffer_ids: buffers
11032                    .into_iter()
11033                    .map(|b| b.read(cx).remote_id().to_proto())
11034                    .collect(),
11035                only_servers: only_restart_servers
11036                    .into_iter()
11037                    .map(|selector| {
11038                        let selector = match selector {
11039                            LanguageServerSelector::Id(language_server_id) => {
11040                                proto::language_server_selector::Selector::ServerId(
11041                                    language_server_id.to_proto(),
11042                                )
11043                            }
11044                            LanguageServerSelector::Name(language_server_name) => {
11045                                proto::language_server_selector::Selector::Name(
11046                                    language_server_name.to_string(),
11047                                )
11048                            }
11049                        };
11050                        proto::LanguageServerSelector {
11051                            selector: Some(selector),
11052                        }
11053                    })
11054                    .collect(),
11055                all: false,
11056            });
11057            cx.background_spawn(request).detach_and_log_err(cx);
11058        } else {
11059            let stop_task = if only_restart_servers.is_empty() {
11060                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11061            } else {
11062                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11063            };
11064            cx.spawn(async move |lsp_store, cx| {
11065                stop_task.await;
11066                lsp_store.update(cx, |lsp_store, cx| {
11067                    for buffer in buffers {
11068                        lsp_store.register_buffer_with_language_servers(
11069                            &buffer,
11070                            only_restart_servers.clone(),
11071                            true,
11072                            cx,
11073                        );
11074                    }
11075                })
11076            })
11077            .detach();
11078        }
11079    }
11080
11081    pub fn stop_language_servers_for_buffers(
11082        &mut self,
11083        buffers: Vec<Entity<Buffer>>,
11084        also_stop_servers: HashSet<LanguageServerSelector>,
11085        cx: &mut Context<Self>,
11086    ) -> Task<Result<()>> {
11087        if let Some((client, project_id)) = self.upstream_client() {
11088            let request = client.request(proto::StopLanguageServers {
11089                project_id,
11090                buffer_ids: buffers
11091                    .into_iter()
11092                    .map(|b| b.read(cx).remote_id().to_proto())
11093                    .collect(),
11094                also_servers: also_stop_servers
11095                    .into_iter()
11096                    .map(|selector| {
11097                        let selector = match selector {
11098                            LanguageServerSelector::Id(language_server_id) => {
11099                                proto::language_server_selector::Selector::ServerId(
11100                                    language_server_id.to_proto(),
11101                                )
11102                            }
11103                            LanguageServerSelector::Name(language_server_name) => {
11104                                proto::language_server_selector::Selector::Name(
11105                                    language_server_name.to_string(),
11106                                )
11107                            }
11108                        };
11109                        proto::LanguageServerSelector {
11110                            selector: Some(selector),
11111                        }
11112                    })
11113                    .collect(),
11114                all: false,
11115            });
11116            cx.background_spawn(async move {
11117                let _ = request.await?;
11118                Ok(())
11119            })
11120        } else {
11121            let task =
11122                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11123            cx.background_spawn(async move {
11124                task.await;
11125                Ok(())
11126            })
11127        }
11128    }
11129
11130    fn stop_local_language_servers_for_buffers(
11131        &mut self,
11132        buffers: &[Entity<Buffer>],
11133        also_stop_servers: HashSet<LanguageServerSelector>,
11134        cx: &mut Context<Self>,
11135    ) -> Task<()> {
11136        let Some(local) = self.as_local_mut() else {
11137            return Task::ready(());
11138        };
11139        let mut language_server_names_to_stop = BTreeSet::default();
11140        let mut language_servers_to_stop = also_stop_servers
11141            .into_iter()
11142            .flat_map(|selector| match selector {
11143                LanguageServerSelector::Id(id) => Some(id),
11144                LanguageServerSelector::Name(name) => {
11145                    language_server_names_to_stop.insert(name);
11146                    None
11147                }
11148            })
11149            .collect::<BTreeSet<_>>();
11150
11151        let mut covered_worktrees = HashSet::default();
11152        for buffer in buffers {
11153            buffer.update(cx, |buffer, cx| {
11154                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11155                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11156                    && covered_worktrees.insert(worktree_id)
11157                {
11158                    language_server_names_to_stop.retain(|name| {
11159                        let old_ids_count = language_servers_to_stop.len();
11160                        let all_language_servers_with_this_name = local
11161                            .language_server_ids
11162                            .iter()
11163                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11164                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11165                        old_ids_count == language_servers_to_stop.len()
11166                    });
11167                }
11168            });
11169        }
11170        for name in language_server_names_to_stop {
11171            language_servers_to_stop.extend(
11172                local
11173                    .language_server_ids
11174                    .iter()
11175                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11176            );
11177        }
11178
11179        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11180        let tasks = language_servers_to_stop
11181            .into_iter()
11182            .map(|server| self.stop_local_language_server(server, cx))
11183            .collect::<Vec<_>>();
11184
11185        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11186    }
11187
11188    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11189        let (worktree, relative_path) =
11190            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11191
11192        let project_path = ProjectPath {
11193            worktree_id: worktree.read(cx).id(),
11194            path: relative_path,
11195        };
11196
11197        Some(
11198            self.buffer_store()
11199                .read(cx)
11200                .get_by_path(&project_path)?
11201                .read(cx),
11202        )
11203    }
11204
11205    #[cfg(any(test, feature = "test-support"))]
11206    pub fn update_diagnostics(
11207        &mut self,
11208        server_id: LanguageServerId,
11209        diagnostics: lsp::PublishDiagnosticsParams,
11210        result_id: Option<SharedString>,
11211        source_kind: DiagnosticSourceKind,
11212        disk_based_sources: &[String],
11213        cx: &mut Context<Self>,
11214    ) -> Result<()> {
11215        self.merge_lsp_diagnostics(
11216            source_kind,
11217            vec![DocumentDiagnosticsUpdate {
11218                diagnostics,
11219                result_id,
11220                server_id,
11221                disk_based_sources: Cow::Borrowed(disk_based_sources),
11222                registration_id: None,
11223            }],
11224            |_, _, _| false,
11225            cx,
11226        )
11227    }
11228
11229    pub fn merge_lsp_diagnostics(
11230        &mut self,
11231        source_kind: DiagnosticSourceKind,
11232        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11233        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11234        cx: &mut Context<Self>,
11235    ) -> Result<()> {
11236        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11237        let updates = lsp_diagnostics
11238            .into_iter()
11239            .filter_map(|update| {
11240                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11241                Some(DocumentDiagnosticsUpdate {
11242                    diagnostics: self.lsp_to_document_diagnostics(
11243                        abs_path,
11244                        source_kind,
11245                        update.server_id,
11246                        update.diagnostics,
11247                        &update.disk_based_sources,
11248                        update.registration_id.clone(),
11249                    ),
11250                    result_id: update.result_id,
11251                    server_id: update.server_id,
11252                    disk_based_sources: update.disk_based_sources,
11253                    registration_id: update.registration_id,
11254                })
11255            })
11256            .collect();
11257        self.merge_diagnostic_entries(updates, merge, cx)?;
11258        Ok(())
11259    }
11260
11261    fn lsp_to_document_diagnostics(
11262        &mut self,
11263        document_abs_path: PathBuf,
11264        source_kind: DiagnosticSourceKind,
11265        server_id: LanguageServerId,
11266        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11267        disk_based_sources: &[String],
11268        registration_id: Option<SharedString>,
11269    ) -> DocumentDiagnostics {
11270        let mut diagnostics = Vec::default();
11271        let mut primary_diagnostic_group_ids = HashMap::default();
11272        let mut sources_by_group_id = HashMap::default();
11273        let mut supporting_diagnostics = HashMap::default();
11274
11275        let adapter = self.language_server_adapter_for_id(server_id);
11276
11277        // Ensure that primary diagnostics are always the most severe
11278        lsp_diagnostics
11279            .diagnostics
11280            .sort_by_key(|item| item.severity);
11281
11282        for diagnostic in &lsp_diagnostics.diagnostics {
11283            let source = diagnostic.source.as_ref();
11284            let range = range_from_lsp(diagnostic.range);
11285            let is_supporting = diagnostic
11286                .related_information
11287                .as_ref()
11288                .is_some_and(|infos| {
11289                    infos.iter().any(|info| {
11290                        primary_diagnostic_group_ids.contains_key(&(
11291                            source,
11292                            diagnostic.code.clone(),
11293                            range_from_lsp(info.location.range),
11294                        ))
11295                    })
11296                });
11297
11298            let is_unnecessary = diagnostic
11299                .tags
11300                .as_ref()
11301                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11302
11303            let underline = self
11304                .language_server_adapter_for_id(server_id)
11305                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11306
11307            if is_supporting {
11308                supporting_diagnostics.insert(
11309                    (source, diagnostic.code.clone(), range),
11310                    (diagnostic.severity, is_unnecessary),
11311                );
11312            } else {
11313                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11314                let is_disk_based =
11315                    source.is_some_and(|source| disk_based_sources.contains(source));
11316
11317                sources_by_group_id.insert(group_id, source);
11318                primary_diagnostic_group_ids
11319                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11320
11321                diagnostics.push(DiagnosticEntry {
11322                    range,
11323                    diagnostic: Diagnostic {
11324                        source: diagnostic.source.clone(),
11325                        source_kind,
11326                        code: diagnostic.code.clone(),
11327                        code_description: diagnostic
11328                            .code_description
11329                            .as_ref()
11330                            .and_then(|d| d.href.clone()),
11331                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11332                        markdown: adapter.as_ref().and_then(|adapter| {
11333                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11334                        }),
11335                        message: diagnostic.message.trim().to_string(),
11336                        group_id,
11337                        is_primary: true,
11338                        is_disk_based,
11339                        is_unnecessary,
11340                        underline,
11341                        data: diagnostic.data.clone(),
11342                        registration_id: registration_id.clone(),
11343                    },
11344                });
11345                if let Some(infos) = &diagnostic.related_information {
11346                    for info in infos {
11347                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11348                            let range = range_from_lsp(info.location.range);
11349                            diagnostics.push(DiagnosticEntry {
11350                                range,
11351                                diagnostic: Diagnostic {
11352                                    source: diagnostic.source.clone(),
11353                                    source_kind,
11354                                    code: diagnostic.code.clone(),
11355                                    code_description: diagnostic
11356                                        .code_description
11357                                        .as_ref()
11358                                        .and_then(|d| d.href.clone()),
11359                                    severity: DiagnosticSeverity::INFORMATION,
11360                                    markdown: adapter.as_ref().and_then(|adapter| {
11361                                        adapter.diagnostic_message_to_markdown(&info.message)
11362                                    }),
11363                                    message: info.message.trim().to_string(),
11364                                    group_id,
11365                                    is_primary: false,
11366                                    is_disk_based,
11367                                    is_unnecessary: false,
11368                                    underline,
11369                                    data: diagnostic.data.clone(),
11370                                    registration_id: registration_id.clone(),
11371                                },
11372                            });
11373                        }
11374                    }
11375                }
11376            }
11377        }
11378
11379        for entry in &mut diagnostics {
11380            let diagnostic = &mut entry.diagnostic;
11381            if !diagnostic.is_primary {
11382                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11383                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11384                    source,
11385                    diagnostic.code.clone(),
11386                    entry.range.clone(),
11387                )) {
11388                    if let Some(severity) = severity {
11389                        diagnostic.severity = severity;
11390                    }
11391                    diagnostic.is_unnecessary = is_unnecessary;
11392                }
11393            }
11394        }
11395
11396        DocumentDiagnostics {
11397            diagnostics,
11398            document_abs_path,
11399            version: lsp_diagnostics.version,
11400        }
11401    }
11402
11403    fn insert_newly_running_language_server(
11404        &mut self,
11405        adapter: Arc<CachedLspAdapter>,
11406        language_server: Arc<LanguageServer>,
11407        server_id: LanguageServerId,
11408        key: LanguageServerSeed,
11409        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11410        cx: &mut Context<Self>,
11411    ) {
11412        let Some(local) = self.as_local_mut() else {
11413            return;
11414        };
11415        // If the language server for this key doesn't match the server id, don't store the
11416        // server. Which will cause it to be dropped, killing the process
11417        if local
11418            .language_server_ids
11419            .get(&key)
11420            .map(|state| state.id != server_id)
11421            .unwrap_or(false)
11422        {
11423            return;
11424        }
11425
11426        // Update language_servers collection with Running variant of LanguageServerState
11427        // indicating that the server is up and running and ready
11428        let workspace_folders = workspace_folders.lock().clone();
11429        language_server.set_workspace_folders(workspace_folders);
11430
11431        let workspace_diagnostics_refresh_tasks = language_server
11432            .capabilities()
11433            .diagnostic_provider
11434            .and_then(|provider| {
11435                local
11436                    .language_server_dynamic_registrations
11437                    .entry(server_id)
11438                    .or_default()
11439                    .diagnostics
11440                    .entry(None)
11441                    .or_insert(provider.clone());
11442                let workspace_refresher =
11443                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11444
11445                Some((None, workspace_refresher))
11446            })
11447            .into_iter()
11448            .collect();
11449        local.language_servers.insert(
11450            server_id,
11451            LanguageServerState::Running {
11452                workspace_diagnostics_refresh_tasks,
11453                adapter: adapter.clone(),
11454                server: language_server.clone(),
11455                simulate_disk_based_diagnostics_completion: None,
11456            },
11457        );
11458        local
11459            .languages
11460            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11461        if let Some(file_ops_caps) = language_server
11462            .capabilities()
11463            .workspace
11464            .as_ref()
11465            .and_then(|ws| ws.file_operations.as_ref())
11466        {
11467            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11468            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11469            if did_rename_caps.or(will_rename_caps).is_some() {
11470                let watcher = RenamePathsWatchedForServer::default()
11471                    .with_did_rename_patterns(did_rename_caps)
11472                    .with_will_rename_patterns(will_rename_caps);
11473                local
11474                    .language_server_paths_watched_for_rename
11475                    .insert(server_id, watcher);
11476            }
11477        }
11478
11479        self.language_server_statuses.insert(
11480            server_id,
11481            LanguageServerStatus {
11482                name: language_server.name(),
11483                server_version: language_server.version(),
11484                pending_work: Default::default(),
11485                has_pending_diagnostic_updates: false,
11486                progress_tokens: Default::default(),
11487                worktree: Some(key.worktree_id),
11488                binary: Some(language_server.binary().clone()),
11489                configuration: Some(language_server.configuration().clone()),
11490                workspace_folders: language_server.workspace_folders(),
11491            },
11492        );
11493
11494        cx.emit(LspStoreEvent::LanguageServerAdded(
11495            server_id,
11496            language_server.name(),
11497            Some(key.worktree_id),
11498        ));
11499
11500        let server_capabilities = language_server.capabilities();
11501        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11502            downstream_client
11503                .send(proto::StartLanguageServer {
11504                    project_id: *project_id,
11505                    server: Some(proto::LanguageServer {
11506                        id: server_id.to_proto(),
11507                        name: language_server.name().to_string(),
11508                        worktree_id: Some(key.worktree_id.to_proto()),
11509                    }),
11510                    capabilities: serde_json::to_string(&server_capabilities)
11511                        .expect("serializing server LSP capabilities"),
11512                })
11513                .log_err();
11514        }
11515        self.lsp_server_capabilities
11516            .insert(server_id, server_capabilities);
11517
11518        // Tell the language server about every open buffer in the worktree that matches the language.
11519        // Also check for buffers in worktrees that reused this server
11520        let mut worktrees_using_server = vec![key.worktree_id];
11521        if let Some(local) = self.as_local() {
11522            // Find all worktrees that have this server in their language server tree
11523            for (worktree_id, servers) in &local.lsp_tree.instances {
11524                if *worktree_id != key.worktree_id {
11525                    for server_map in servers.roots.values() {
11526                        if server_map
11527                            .values()
11528                            .any(|(node, _)| node.id() == Some(server_id))
11529                        {
11530                            worktrees_using_server.push(*worktree_id);
11531                        }
11532                    }
11533                }
11534            }
11535        }
11536
11537        let mut buffer_paths_registered = Vec::new();
11538        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11539            let mut lsp_adapters = HashMap::default();
11540            for buffer_handle in buffer_store.buffers() {
11541                let buffer = buffer_handle.read(cx);
11542                let file = match File::from_dyn(buffer.file()) {
11543                    Some(file) => file,
11544                    None => continue,
11545                };
11546                let language = match buffer.language() {
11547                    Some(language) => language,
11548                    None => continue,
11549                };
11550
11551                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11552                    || !lsp_adapters
11553                        .entry(language.name())
11554                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11555                        .iter()
11556                        .any(|a| a.name == key.name)
11557                {
11558                    continue;
11559                }
11560                // didOpen
11561                let file = match file.as_local() {
11562                    Some(file) => file,
11563                    None => continue,
11564                };
11565
11566                let local = self.as_local_mut().unwrap();
11567
11568                let buffer_id = buffer.remote_id();
11569                if local.registered_buffers.contains_key(&buffer_id) {
11570                    let versions = local
11571                        .buffer_snapshots
11572                        .entry(buffer_id)
11573                        .or_default()
11574                        .entry(server_id)
11575                        .and_modify(|_| {
11576                            assert!(
11577                            false,
11578                            "There should not be an existing snapshot for a newly inserted buffer"
11579                        )
11580                        })
11581                        .or_insert_with(|| {
11582                            vec![LspBufferSnapshot {
11583                                version: 0,
11584                                snapshot: buffer.text_snapshot(),
11585                            }]
11586                        });
11587
11588                    let snapshot = versions.last().unwrap();
11589                    let version = snapshot.version;
11590                    let initial_snapshot = &snapshot.snapshot;
11591                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11592                    language_server.register_buffer(
11593                        uri,
11594                        adapter.language_id(&language.name()),
11595                        version,
11596                        initial_snapshot.text(),
11597                    );
11598                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11599                    local
11600                        .buffers_opened_in_servers
11601                        .entry(buffer_id)
11602                        .or_default()
11603                        .insert(server_id);
11604                }
11605                buffer_handle.update(cx, |buffer, cx| {
11606                    buffer.set_completion_triggers(
11607                        server_id,
11608                        language_server
11609                            .capabilities()
11610                            .completion_provider
11611                            .as_ref()
11612                            .and_then(|provider| {
11613                                provider
11614                                    .trigger_characters
11615                                    .as_ref()
11616                                    .map(|characters| characters.iter().cloned().collect())
11617                            })
11618                            .unwrap_or_default(),
11619                        cx,
11620                    )
11621                });
11622            }
11623        });
11624
11625        for (buffer_id, abs_path) in buffer_paths_registered {
11626            cx.emit(LspStoreEvent::LanguageServerUpdate {
11627                language_server_id: server_id,
11628                name: Some(adapter.name()),
11629                message: proto::update_language_server::Variant::RegisteredForBuffer(
11630                    proto::RegisteredForBuffer {
11631                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11632                        buffer_id: buffer_id.to_proto(),
11633                    },
11634                ),
11635            });
11636        }
11637
11638        cx.notify();
11639    }
11640
11641    pub fn language_servers_running_disk_based_diagnostics(
11642        &self,
11643    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11644        self.language_server_statuses
11645            .iter()
11646            .filter_map(|(id, status)| {
11647                if status.has_pending_diagnostic_updates {
11648                    Some(*id)
11649                } else {
11650                    None
11651                }
11652            })
11653    }
11654
11655    pub(crate) fn cancel_language_server_work_for_buffers(
11656        &mut self,
11657        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11658        cx: &mut Context<Self>,
11659    ) {
11660        if let Some((client, project_id)) = self.upstream_client() {
11661            let request = client.request(proto::CancelLanguageServerWork {
11662                project_id,
11663                work: Some(proto::cancel_language_server_work::Work::Buffers(
11664                    proto::cancel_language_server_work::Buffers {
11665                        buffer_ids: buffers
11666                            .into_iter()
11667                            .map(|b| b.read(cx).remote_id().to_proto())
11668                            .collect(),
11669                    },
11670                )),
11671            });
11672            cx.background_spawn(request).detach_and_log_err(cx);
11673        } else if let Some(local) = self.as_local() {
11674            let servers = buffers
11675                .into_iter()
11676                .flat_map(|buffer| {
11677                    buffer.update(cx, |buffer, cx| {
11678                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11679                    })
11680                })
11681                .collect::<HashSet<_>>();
11682            for server_id in servers {
11683                self.cancel_language_server_work(server_id, None, cx);
11684            }
11685        }
11686    }
11687
11688    pub(crate) fn cancel_language_server_work(
11689        &mut self,
11690        server_id: LanguageServerId,
11691        token_to_cancel: Option<ProgressToken>,
11692        cx: &mut Context<Self>,
11693    ) {
11694        if let Some(local) = self.as_local() {
11695            let status = self.language_server_statuses.get(&server_id);
11696            let server = local.language_servers.get(&server_id);
11697            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11698            {
11699                for (token, progress) in &status.pending_work {
11700                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11701                        && token != token_to_cancel
11702                    {
11703                        continue;
11704                    }
11705                    if progress.is_cancellable {
11706                        server
11707                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11708                                WorkDoneProgressCancelParams {
11709                                    token: token.to_lsp(),
11710                                },
11711                            )
11712                            .ok();
11713                    }
11714                }
11715            }
11716        } else if let Some((client, project_id)) = self.upstream_client() {
11717            let request = client.request(proto::CancelLanguageServerWork {
11718                project_id,
11719                work: Some(
11720                    proto::cancel_language_server_work::Work::LanguageServerWork(
11721                        proto::cancel_language_server_work::LanguageServerWork {
11722                            language_server_id: server_id.to_proto(),
11723                            token: token_to_cancel.map(|token| token.to_proto()),
11724                        },
11725                    ),
11726                ),
11727            });
11728            cx.background_spawn(request).detach_and_log_err(cx);
11729        }
11730    }
11731
11732    fn register_supplementary_language_server(
11733        &mut self,
11734        id: LanguageServerId,
11735        name: LanguageServerName,
11736        server: Arc<LanguageServer>,
11737        cx: &mut Context<Self>,
11738    ) {
11739        if let Some(local) = self.as_local_mut() {
11740            local
11741                .supplementary_language_servers
11742                .insert(id, (name.clone(), server));
11743            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11744        }
11745    }
11746
11747    fn unregister_supplementary_language_server(
11748        &mut self,
11749        id: LanguageServerId,
11750        cx: &mut Context<Self>,
11751    ) {
11752        if let Some(local) = self.as_local_mut() {
11753            local.supplementary_language_servers.remove(&id);
11754            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11755        }
11756    }
11757
11758    pub(crate) fn supplementary_language_servers(
11759        &self,
11760    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11761        self.as_local().into_iter().flat_map(|local| {
11762            local
11763                .supplementary_language_servers
11764                .iter()
11765                .map(|(id, (name, _))| (*id, name.clone()))
11766        })
11767    }
11768
11769    pub fn language_server_adapter_for_id(
11770        &self,
11771        id: LanguageServerId,
11772    ) -> Option<Arc<CachedLspAdapter>> {
11773        self.as_local()
11774            .and_then(|local| local.language_servers.get(&id))
11775            .and_then(|language_server_state| match language_server_state {
11776                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11777                _ => None,
11778            })
11779    }
11780
11781    pub(super) fn update_local_worktree_language_servers(
11782        &mut self,
11783        worktree_handle: &Entity<Worktree>,
11784        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11785        cx: &mut Context<Self>,
11786    ) {
11787        if changes.is_empty() {
11788            return;
11789        }
11790
11791        let Some(local) = self.as_local() else { return };
11792
11793        local.prettier_store.update(cx, |prettier_store, cx| {
11794            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11795        });
11796
11797        let worktree_id = worktree_handle.read(cx).id();
11798        let mut language_server_ids = local
11799            .language_server_ids
11800            .iter()
11801            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11802            .collect::<Vec<_>>();
11803        language_server_ids.sort();
11804        language_server_ids.dedup();
11805
11806        // let abs_path = worktree_handle.read(cx).abs_path();
11807        for server_id in &language_server_ids {
11808            if let Some(LanguageServerState::Running { server, .. }) =
11809                local.language_servers.get(server_id)
11810                && let Some(watched_paths) = local
11811                    .language_server_watched_paths
11812                    .get(server_id)
11813                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11814            {
11815                let params = lsp::DidChangeWatchedFilesParams {
11816                    changes: changes
11817                        .iter()
11818                        .filter_map(|(path, _, change)| {
11819                            if !watched_paths.is_match(path.as_std_path()) {
11820                                return None;
11821                            }
11822                            let typ = match change {
11823                                PathChange::Loaded => return None,
11824                                PathChange::Added => lsp::FileChangeType::CREATED,
11825                                PathChange::Removed => lsp::FileChangeType::DELETED,
11826                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11827                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11828                            };
11829                            let uri = lsp::Uri::from_file_path(
11830                                worktree_handle.read(cx).absolutize(&path),
11831                            )
11832                            .ok()?;
11833                            Some(lsp::FileEvent { uri, typ })
11834                        })
11835                        .collect(),
11836                };
11837                if !params.changes.is_empty() {
11838                    server
11839                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11840                        .ok();
11841                }
11842            }
11843        }
11844        for (path, _, _) in changes {
11845            if let Some(file_name) = path.file_name()
11846                && local.watched_manifest_filenames.contains(file_name)
11847            {
11848                self.request_workspace_config_refresh();
11849                break;
11850            }
11851        }
11852    }
11853
11854    pub fn wait_for_remote_buffer(
11855        &mut self,
11856        id: BufferId,
11857        cx: &mut Context<Self>,
11858    ) -> Task<Result<Entity<Buffer>>> {
11859        self.buffer_store.update(cx, |buffer_store, cx| {
11860            buffer_store.wait_for_remote_buffer(id, cx)
11861        })
11862    }
11863
11864    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11865        let mut result = proto::Symbol {
11866            language_server_name: symbol.language_server_name.0.to_string(),
11867            source_worktree_id: symbol.source_worktree_id.to_proto(),
11868            language_server_id: symbol.source_language_server_id.to_proto(),
11869            name: symbol.name.clone(),
11870            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11871            start: Some(proto::PointUtf16 {
11872                row: symbol.range.start.0.row,
11873                column: symbol.range.start.0.column,
11874            }),
11875            end: Some(proto::PointUtf16 {
11876                row: symbol.range.end.0.row,
11877                column: symbol.range.end.0.column,
11878            }),
11879            worktree_id: Default::default(),
11880            path: Default::default(),
11881            signature: Default::default(),
11882        };
11883        match &symbol.path {
11884            SymbolLocation::InProject(path) => {
11885                result.worktree_id = path.worktree_id.to_proto();
11886                result.path = path.path.to_proto();
11887            }
11888            SymbolLocation::OutsideProject {
11889                abs_path,
11890                signature,
11891            } => {
11892                result.path = abs_path.to_string_lossy().into_owned();
11893                result.signature = signature.to_vec();
11894            }
11895        }
11896        result
11897    }
11898
11899    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11900        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11901        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11902        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11903
11904        let path = if serialized_symbol.signature.is_empty() {
11905            SymbolLocation::InProject(ProjectPath {
11906                worktree_id,
11907                path: RelPath::from_proto(&serialized_symbol.path)
11908                    .context("invalid symbol path")?,
11909            })
11910        } else {
11911            SymbolLocation::OutsideProject {
11912                abs_path: Path::new(&serialized_symbol.path).into(),
11913                signature: serialized_symbol
11914                    .signature
11915                    .try_into()
11916                    .map_err(|_| anyhow!("invalid signature"))?,
11917            }
11918        };
11919
11920        let start = serialized_symbol.start.context("invalid start")?;
11921        let end = serialized_symbol.end.context("invalid end")?;
11922        Ok(CoreSymbol {
11923            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11924            source_worktree_id,
11925            source_language_server_id: LanguageServerId::from_proto(
11926                serialized_symbol.language_server_id,
11927            ),
11928            path,
11929            name: serialized_symbol.name,
11930            range: Unclipped(PointUtf16::new(start.row, start.column))
11931                ..Unclipped(PointUtf16::new(end.row, end.column)),
11932            kind,
11933        })
11934    }
11935
11936    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11937        let mut serialized_completion = proto::Completion {
11938            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11939            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11940            new_text: completion.new_text.clone(),
11941            ..proto::Completion::default()
11942        };
11943        match &completion.source {
11944            CompletionSource::Lsp {
11945                insert_range,
11946                server_id,
11947                lsp_completion,
11948                lsp_defaults,
11949                resolved,
11950            } => {
11951                let (old_insert_start, old_insert_end) = insert_range
11952                    .as_ref()
11953                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11954                    .unzip();
11955
11956                serialized_completion.old_insert_start = old_insert_start;
11957                serialized_completion.old_insert_end = old_insert_end;
11958                serialized_completion.source = proto::completion::Source::Lsp as i32;
11959                serialized_completion.server_id = server_id.0 as u64;
11960                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11961                serialized_completion.lsp_defaults = lsp_defaults
11962                    .as_deref()
11963                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11964                serialized_completion.resolved = *resolved;
11965            }
11966            CompletionSource::BufferWord {
11967                word_range,
11968                resolved,
11969            } => {
11970                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11971                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11972                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11973                serialized_completion.resolved = *resolved;
11974            }
11975            CompletionSource::Custom => {
11976                serialized_completion.source = proto::completion::Source::Custom as i32;
11977                serialized_completion.resolved = true;
11978            }
11979            CompletionSource::Dap { sort_text } => {
11980                serialized_completion.source = proto::completion::Source::Dap as i32;
11981                serialized_completion.sort_text = Some(sort_text.clone());
11982            }
11983        }
11984
11985        serialized_completion
11986    }
11987
11988    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11989        let old_replace_start = completion
11990            .old_replace_start
11991            .and_then(deserialize_anchor)
11992            .context("invalid old start")?;
11993        let old_replace_end = completion
11994            .old_replace_end
11995            .and_then(deserialize_anchor)
11996            .context("invalid old end")?;
11997        let insert_range = {
11998            match completion.old_insert_start.zip(completion.old_insert_end) {
11999                Some((start, end)) => {
12000                    let start = deserialize_anchor(start).context("invalid insert old start")?;
12001                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12002                    Some(start..end)
12003                }
12004                None => None,
12005            }
12006        };
12007        Ok(CoreCompletion {
12008            replace_range: old_replace_start..old_replace_end,
12009            new_text: completion.new_text,
12010            source: match proto::completion::Source::from_i32(completion.source) {
12011                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12012                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12013                    insert_range,
12014                    server_id: LanguageServerId::from_proto(completion.server_id),
12015                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12016                    lsp_defaults: completion
12017                        .lsp_defaults
12018                        .as_deref()
12019                        .map(serde_json::from_slice)
12020                        .transpose()?,
12021                    resolved: completion.resolved,
12022                },
12023                Some(proto::completion::Source::BufferWord) => {
12024                    let word_range = completion
12025                        .buffer_word_start
12026                        .and_then(deserialize_anchor)
12027                        .context("invalid buffer word start")?
12028                        ..completion
12029                            .buffer_word_end
12030                            .and_then(deserialize_anchor)
12031                            .context("invalid buffer word end")?;
12032                    CompletionSource::BufferWord {
12033                        word_range,
12034                        resolved: completion.resolved,
12035                    }
12036                }
12037                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12038                    sort_text: completion
12039                        .sort_text
12040                        .context("expected sort text to exist")?,
12041                },
12042                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12043            },
12044        })
12045    }
12046
12047    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12048        let (kind, lsp_action) = match &action.lsp_action {
12049            LspAction::Action(code_action) => (
12050                proto::code_action::Kind::Action as i32,
12051                serde_json::to_vec(code_action).unwrap(),
12052            ),
12053            LspAction::Command(command) => (
12054                proto::code_action::Kind::Command as i32,
12055                serde_json::to_vec(command).unwrap(),
12056            ),
12057            LspAction::CodeLens(code_lens) => (
12058                proto::code_action::Kind::CodeLens as i32,
12059                serde_json::to_vec(code_lens).unwrap(),
12060            ),
12061        };
12062
12063        proto::CodeAction {
12064            server_id: action.server_id.0 as u64,
12065            start: Some(serialize_anchor(&action.range.start)),
12066            end: Some(serialize_anchor(&action.range.end)),
12067            lsp_action,
12068            kind,
12069            resolved: action.resolved,
12070        }
12071    }
12072
12073    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12074        let start = action
12075            .start
12076            .and_then(deserialize_anchor)
12077            .context("invalid start")?;
12078        let end = action
12079            .end
12080            .and_then(deserialize_anchor)
12081            .context("invalid end")?;
12082        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12083            Some(proto::code_action::Kind::Action) => {
12084                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12085            }
12086            Some(proto::code_action::Kind::Command) => {
12087                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12088            }
12089            Some(proto::code_action::Kind::CodeLens) => {
12090                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12091            }
12092            None => anyhow::bail!("Unknown action kind {}", action.kind),
12093        };
12094        Ok(CodeAction {
12095            server_id: LanguageServerId(action.server_id as usize),
12096            range: start..end,
12097            resolved: action.resolved,
12098            lsp_action,
12099        })
12100    }
12101
12102    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12103        match &formatting_result {
12104            Ok(_) => self.last_formatting_failure = None,
12105            Err(error) => {
12106                let error_string = format!("{error:#}");
12107                log::error!("Formatting failed: {error_string}");
12108                self.last_formatting_failure
12109                    .replace(error_string.lines().join(" "));
12110            }
12111        }
12112    }
12113
12114    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12115        self.lsp_server_capabilities.remove(&for_server);
12116        for lsp_data in self.lsp_data.values_mut() {
12117            lsp_data.remove_server_data(for_server);
12118        }
12119        if let Some(local) = self.as_local_mut() {
12120            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12121            local
12122                .workspace_pull_diagnostics_result_ids
12123                .remove(&for_server);
12124            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12125                buffer_servers.remove(&for_server);
12126            }
12127        }
12128    }
12129
12130    pub fn result_id_for_buffer_pull(
12131        &self,
12132        server_id: LanguageServerId,
12133        buffer_id: BufferId,
12134        registration_id: &Option<SharedString>,
12135        cx: &App,
12136    ) -> Option<SharedString> {
12137        let abs_path = self
12138            .buffer_store
12139            .read(cx)
12140            .get(buffer_id)
12141            .and_then(|b| File::from_dyn(b.read(cx).file()))
12142            .map(|f| f.abs_path(cx))?;
12143        self.as_local()?
12144            .buffer_pull_diagnostics_result_ids
12145            .get(&server_id)?
12146            .get(registration_id)?
12147            .get(&abs_path)?
12148            .clone()
12149    }
12150
12151    /// Gets all result_ids for a workspace diagnostics pull request.
12152    /// 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.
12153    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12154    pub fn result_ids_for_workspace_refresh(
12155        &self,
12156        server_id: LanguageServerId,
12157        registration_id: &Option<SharedString>,
12158    ) -> HashMap<PathBuf, SharedString> {
12159        let Some(local) = self.as_local() else {
12160            return HashMap::default();
12161        };
12162        local
12163            .workspace_pull_diagnostics_result_ids
12164            .get(&server_id)
12165            .into_iter()
12166            .filter_map(|diagnostics| diagnostics.get(registration_id))
12167            .flatten()
12168            .filter_map(|(abs_path, result_id)| {
12169                let result_id = local
12170                    .buffer_pull_diagnostics_result_ids
12171                    .get(&server_id)
12172                    .and_then(|buffer_ids_result_ids| {
12173                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12174                    })
12175                    .cloned()
12176                    .flatten()
12177                    .or_else(|| result_id.clone())?;
12178                Some((abs_path.clone(), result_id))
12179            })
12180            .collect()
12181    }
12182
12183    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12184        if let Some(LanguageServerState::Running {
12185            workspace_diagnostics_refresh_tasks,
12186            ..
12187        }) = self
12188            .as_local_mut()
12189            .and_then(|local| local.language_servers.get_mut(&server_id))
12190        {
12191            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12192                diagnostics.refresh_tx.try_send(()).ok();
12193            }
12194        }
12195    }
12196
12197    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12198    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12199    /// which requires refreshing both workspace and document diagnostics.
12200    pub fn pull_document_diagnostics_for_server(
12201        &mut self,
12202        server_id: LanguageServerId,
12203        cx: &mut Context<Self>,
12204    ) -> Task<()> {
12205        let buffers_to_pull = self
12206            .as_local()
12207            .into_iter()
12208            .flat_map(|local| {
12209                self.buffer_store.read(cx).buffers().filter(|buffer| {
12210                    let buffer_id = buffer.read(cx).remote_id();
12211                    local
12212                        .buffers_opened_in_servers
12213                        .get(&buffer_id)
12214                        .is_some_and(|servers| servers.contains(&server_id))
12215                })
12216            })
12217            .collect::<Vec<_>>();
12218
12219        let pulls = join_all(buffers_to_pull.into_iter().map(|buffer| {
12220            let buffer_path = buffer.read(cx).file().map(|f| f.full_path(cx));
12221            let pull_task = self.pull_diagnostics_for_buffer(buffer, cx);
12222            async move { (buffer_path, pull_task.await) }
12223        }));
12224        cx.background_spawn(async move {
12225            for (pull_task_path, pull_task_result) in pulls.await {
12226                if let Err(e) = pull_task_result {
12227                    match pull_task_path {
12228                        Some(path) => {
12229                            log::error!("Failed to pull diagnostics for buffer {path:?}: {e:#}");
12230                        }
12231                        None => log::error!("Failed to pull diagnostics: {e:#}"),
12232                    }
12233                }
12234            }
12235        })
12236    }
12237
12238    fn apply_workspace_diagnostic_report(
12239        &mut self,
12240        server_id: LanguageServerId,
12241        report: lsp::WorkspaceDiagnosticReportResult,
12242        registration_id: Option<SharedString>,
12243        cx: &mut Context<Self>,
12244    ) {
12245        let mut workspace_diagnostics =
12246            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12247                report,
12248                server_id,
12249                registration_id,
12250            );
12251        workspace_diagnostics.retain(|d| match &d.diagnostics {
12252            LspPullDiagnostics::Response {
12253                server_id,
12254                registration_id,
12255                ..
12256            } => self.diagnostic_registration_exists(*server_id, registration_id),
12257            LspPullDiagnostics::Default => false,
12258        });
12259        let mut unchanged_buffers = HashMap::default();
12260        let workspace_diagnostics_updates = workspace_diagnostics
12261            .into_iter()
12262            .filter_map(
12263                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12264                    LspPullDiagnostics::Response {
12265                        server_id,
12266                        uri,
12267                        diagnostics,
12268                        registration_id,
12269                    } => Some((
12270                        server_id,
12271                        uri,
12272                        diagnostics,
12273                        workspace_diagnostics.version,
12274                        registration_id,
12275                    )),
12276                    LspPullDiagnostics::Default => None,
12277                },
12278            )
12279            .fold(
12280                HashMap::default(),
12281                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12282                    let (result_id, diagnostics) = match diagnostics {
12283                        PulledDiagnostics::Unchanged { result_id } => {
12284                            unchanged_buffers
12285                                .entry(new_registration_id.clone())
12286                                .or_insert_with(HashSet::default)
12287                                .insert(uri.clone());
12288                            (Some(result_id), Vec::new())
12289                        }
12290                        PulledDiagnostics::Changed {
12291                            result_id,
12292                            diagnostics,
12293                        } => (result_id, diagnostics),
12294                    };
12295                    let disk_based_sources = Cow::Owned(
12296                        self.language_server_adapter_for_id(server_id)
12297                            .as_ref()
12298                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12299                            .unwrap_or(&[])
12300                            .to_vec(),
12301                    );
12302
12303                    let Some(abs_path) = uri.to_file_path().ok() else {
12304                        return acc;
12305                    };
12306                    let Some((worktree, relative_path)) =
12307                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12308                    else {
12309                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12310                        return acc;
12311                    };
12312                    let worktree_id = worktree.read(cx).id();
12313                    let project_path = ProjectPath {
12314                        worktree_id,
12315                        path: relative_path,
12316                    };
12317                    if let Some(local_lsp_store) = self.as_local_mut() {
12318                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12319                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12320                    }
12321                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12322                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12323                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12324                        acc.entry(server_id)
12325                            .or_insert_with(HashMap::default)
12326                            .entry(new_registration_id.clone())
12327                            .or_insert_with(Vec::new)
12328                            .push(DocumentDiagnosticsUpdate {
12329                                server_id,
12330                                diagnostics: lsp::PublishDiagnosticsParams {
12331                                    uri,
12332                                    diagnostics,
12333                                    version,
12334                                },
12335                                result_id,
12336                                disk_based_sources,
12337                                registration_id: new_registration_id,
12338                            });
12339                    }
12340                    acc
12341                },
12342            );
12343
12344        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12345            for (registration_id, diagnostic_updates) in diagnostic_updates {
12346                self.merge_lsp_diagnostics(
12347                    DiagnosticSourceKind::Pulled,
12348                    diagnostic_updates,
12349                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12350                        DiagnosticSourceKind::Pulled => {
12351                            old_diagnostic.registration_id != registration_id
12352                                || unchanged_buffers
12353                                    .get(&old_diagnostic.registration_id)
12354                                    .is_some_and(|unchanged_buffers| {
12355                                        unchanged_buffers.contains(&document_uri)
12356                                    })
12357                        }
12358                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12359                    },
12360                    cx,
12361                )
12362                .log_err();
12363            }
12364        }
12365    }
12366
12367    fn register_server_capabilities(
12368        &mut self,
12369        server_id: LanguageServerId,
12370        params: lsp::RegistrationParams,
12371        cx: &mut Context<Self>,
12372    ) -> anyhow::Result<()> {
12373        let server = self
12374            .language_server_for_id(server_id)
12375            .with_context(|| format!("no server {server_id} found"))?;
12376        for reg in params.registrations {
12377            match reg.method.as_str() {
12378                "workspace/didChangeWatchedFiles" => {
12379                    if let Some(options) = reg.register_options {
12380                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12381                            let caps = serde_json::from_value(options)?;
12382                            local_lsp_store
12383                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12384                            true
12385                        } else {
12386                            false
12387                        };
12388                        if notify {
12389                            notify_server_capabilities_updated(&server, cx);
12390                        }
12391                    }
12392                }
12393                "workspace/didChangeConfiguration" => {
12394                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12395                }
12396                "workspace/didChangeWorkspaceFolders" => {
12397                    // In this case register options is an empty object, we can ignore it
12398                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12399                        supported: Some(true),
12400                        change_notifications: Some(OneOf::Right(reg.id)),
12401                    };
12402                    server.update_capabilities(|capabilities| {
12403                        capabilities
12404                            .workspace
12405                            .get_or_insert_default()
12406                            .workspace_folders = Some(caps);
12407                    });
12408                    notify_server_capabilities_updated(&server, cx);
12409                }
12410                "workspace/symbol" => {
12411                    let options = parse_register_capabilities(reg)?;
12412                    server.update_capabilities(|capabilities| {
12413                        capabilities.workspace_symbol_provider = Some(options);
12414                    });
12415                    notify_server_capabilities_updated(&server, cx);
12416                }
12417                "workspace/fileOperations" => {
12418                    if let Some(options) = reg.register_options {
12419                        let caps = serde_json::from_value(options)?;
12420                        server.update_capabilities(|capabilities| {
12421                            capabilities
12422                                .workspace
12423                                .get_or_insert_default()
12424                                .file_operations = Some(caps);
12425                        });
12426                        notify_server_capabilities_updated(&server, cx);
12427                    }
12428                }
12429                "workspace/executeCommand" => {
12430                    if let Some(options) = reg.register_options {
12431                        let options = serde_json::from_value(options)?;
12432                        server.update_capabilities(|capabilities| {
12433                            capabilities.execute_command_provider = Some(options);
12434                        });
12435                        notify_server_capabilities_updated(&server, cx);
12436                    }
12437                }
12438                "textDocument/rangeFormatting" => {
12439                    let options = parse_register_capabilities(reg)?;
12440                    server.update_capabilities(|capabilities| {
12441                        capabilities.document_range_formatting_provider = Some(options);
12442                    });
12443                    notify_server_capabilities_updated(&server, cx);
12444                }
12445                "textDocument/onTypeFormatting" => {
12446                    if let Some(options) = reg
12447                        .register_options
12448                        .map(serde_json::from_value)
12449                        .transpose()?
12450                    {
12451                        server.update_capabilities(|capabilities| {
12452                            capabilities.document_on_type_formatting_provider = Some(options);
12453                        });
12454                        notify_server_capabilities_updated(&server, cx);
12455                    }
12456                }
12457                "textDocument/formatting" => {
12458                    let options = parse_register_capabilities(reg)?;
12459                    server.update_capabilities(|capabilities| {
12460                        capabilities.document_formatting_provider = Some(options);
12461                    });
12462                    notify_server_capabilities_updated(&server, cx);
12463                }
12464                "textDocument/rename" => {
12465                    let options = parse_register_capabilities(reg)?;
12466                    server.update_capabilities(|capabilities| {
12467                        capabilities.rename_provider = Some(options);
12468                    });
12469                    notify_server_capabilities_updated(&server, cx);
12470                }
12471                "textDocument/inlayHint" => {
12472                    let options = parse_register_capabilities(reg)?;
12473                    server.update_capabilities(|capabilities| {
12474                        capabilities.inlay_hint_provider = Some(options);
12475                    });
12476                    notify_server_capabilities_updated(&server, cx);
12477                }
12478                "textDocument/documentSymbol" => {
12479                    let options = parse_register_capabilities(reg)?;
12480                    server.update_capabilities(|capabilities| {
12481                        capabilities.document_symbol_provider = Some(options);
12482                    });
12483                    notify_server_capabilities_updated(&server, cx);
12484                }
12485                "textDocument/codeAction" => {
12486                    let options = parse_register_capabilities(reg)?;
12487                    let provider = match options {
12488                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12489                        OneOf::Right(caps) => caps,
12490                    };
12491                    server.update_capabilities(|capabilities| {
12492                        capabilities.code_action_provider = Some(provider);
12493                    });
12494                    notify_server_capabilities_updated(&server, cx);
12495                }
12496                "textDocument/definition" => {
12497                    let options = parse_register_capabilities(reg)?;
12498                    server.update_capabilities(|capabilities| {
12499                        capabilities.definition_provider = Some(options);
12500                    });
12501                    notify_server_capabilities_updated(&server, cx);
12502                }
12503                "textDocument/completion" => {
12504                    if let Some(caps) = reg
12505                        .register_options
12506                        .map(serde_json::from_value::<CompletionOptions>)
12507                        .transpose()?
12508                    {
12509                        server.update_capabilities(|capabilities| {
12510                            capabilities.completion_provider = Some(caps.clone());
12511                        });
12512
12513                        if let Some(local) = self.as_local() {
12514                            let mut buffers_with_language_server = Vec::new();
12515                            for handle in self.buffer_store.read(cx).buffers() {
12516                                let buffer_id = handle.read(cx).remote_id();
12517                                if local
12518                                    .buffers_opened_in_servers
12519                                    .get(&buffer_id)
12520                                    .filter(|s| s.contains(&server_id))
12521                                    .is_some()
12522                                {
12523                                    buffers_with_language_server.push(handle);
12524                                }
12525                            }
12526                            let triggers = caps
12527                                .trigger_characters
12528                                .unwrap_or_default()
12529                                .into_iter()
12530                                .collect::<BTreeSet<_>>();
12531                            for handle in buffers_with_language_server {
12532                                let triggers = triggers.clone();
12533                                let _ = handle.update(cx, move |buffer, cx| {
12534                                    buffer.set_completion_triggers(server_id, triggers, cx);
12535                                });
12536                            }
12537                        }
12538                        notify_server_capabilities_updated(&server, cx);
12539                    }
12540                }
12541                "textDocument/hover" => {
12542                    let options = parse_register_capabilities(reg)?;
12543                    let provider = match options {
12544                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12545                        OneOf::Right(caps) => caps,
12546                    };
12547                    server.update_capabilities(|capabilities| {
12548                        capabilities.hover_provider = Some(provider);
12549                    });
12550                    notify_server_capabilities_updated(&server, cx);
12551                }
12552                "textDocument/signatureHelp" => {
12553                    if let Some(caps) = reg
12554                        .register_options
12555                        .map(serde_json::from_value)
12556                        .transpose()?
12557                    {
12558                        server.update_capabilities(|capabilities| {
12559                            capabilities.signature_help_provider = Some(caps);
12560                        });
12561                        notify_server_capabilities_updated(&server, cx);
12562                    }
12563                }
12564                "textDocument/didChange" => {
12565                    if let Some(sync_kind) = reg
12566                        .register_options
12567                        .and_then(|opts| opts.get("syncKind").cloned())
12568                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12569                        .transpose()?
12570                    {
12571                        server.update_capabilities(|capabilities| {
12572                            let mut sync_options =
12573                                Self::take_text_document_sync_options(capabilities);
12574                            sync_options.change = Some(sync_kind);
12575                            capabilities.text_document_sync =
12576                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12577                        });
12578                        notify_server_capabilities_updated(&server, cx);
12579                    }
12580                }
12581                "textDocument/didSave" => {
12582                    if let Some(include_text) = reg
12583                        .register_options
12584                        .map(|opts| {
12585                            let transpose = opts
12586                                .get("includeText")
12587                                .cloned()
12588                                .map(serde_json::from_value::<Option<bool>>)
12589                                .transpose();
12590                            match transpose {
12591                                Ok(value) => Ok(value.flatten()),
12592                                Err(e) => Err(e),
12593                            }
12594                        })
12595                        .transpose()?
12596                    {
12597                        server.update_capabilities(|capabilities| {
12598                            let mut sync_options =
12599                                Self::take_text_document_sync_options(capabilities);
12600                            sync_options.save =
12601                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12602                                    include_text,
12603                                }));
12604                            capabilities.text_document_sync =
12605                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12606                        });
12607                        notify_server_capabilities_updated(&server, cx);
12608                    }
12609                }
12610                "textDocument/codeLens" => {
12611                    if let Some(caps) = reg
12612                        .register_options
12613                        .map(serde_json::from_value)
12614                        .transpose()?
12615                    {
12616                        server.update_capabilities(|capabilities| {
12617                            capabilities.code_lens_provider = Some(caps);
12618                        });
12619                        notify_server_capabilities_updated(&server, cx);
12620                    }
12621                }
12622                "textDocument/diagnostic" => {
12623                    if let Some(caps) = reg
12624                        .register_options
12625                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12626                        .transpose()?
12627                    {
12628                        let local = self
12629                            .as_local_mut()
12630                            .context("Expected LSP Store to be local")?;
12631                        let state = local
12632                            .language_servers
12633                            .get_mut(&server_id)
12634                            .context("Could not obtain Language Servers state")?;
12635                        local
12636                            .language_server_dynamic_registrations
12637                            .entry(server_id)
12638                            .or_default()
12639                            .diagnostics
12640                            .insert(Some(reg.id.clone()), caps.clone());
12641
12642                        let supports_workspace_diagnostics =
12643                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12644                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12645                                    diagnostic_options.workspace_diagnostics
12646                                }
12647                                DiagnosticServerCapabilities::RegistrationOptions(
12648                                    diagnostic_registration_options,
12649                                ) => {
12650                                    diagnostic_registration_options
12651                                        .diagnostic_options
12652                                        .workspace_diagnostics
12653                                }
12654                            };
12655
12656                        if supports_workspace_diagnostics(&caps) {
12657                            if let LanguageServerState::Running {
12658                                workspace_diagnostics_refresh_tasks,
12659                                ..
12660                            } = state
12661                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12662                                    Some(reg.id.clone()),
12663                                    caps.clone(),
12664                                    server.clone(),
12665                                    cx,
12666                                )
12667                            {
12668                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12669                            }
12670                        }
12671
12672                        server.update_capabilities(|capabilities| {
12673                            capabilities.diagnostic_provider = Some(caps);
12674                        });
12675
12676                        notify_server_capabilities_updated(&server, cx);
12677
12678                        self.pull_document_diagnostics_for_server(server_id, cx)
12679                            .detach();
12680                    }
12681                }
12682                "textDocument/documentColor" => {
12683                    let options = parse_register_capabilities(reg)?;
12684                    let provider = match options {
12685                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12686                        OneOf::Right(caps) => caps,
12687                    };
12688                    server.update_capabilities(|capabilities| {
12689                        capabilities.color_provider = Some(provider);
12690                    });
12691                    notify_server_capabilities_updated(&server, cx);
12692                }
12693                _ => log::warn!("unhandled capability registration: {reg:?}"),
12694            }
12695        }
12696
12697        Ok(())
12698    }
12699
12700    fn unregister_server_capabilities(
12701        &mut self,
12702        server_id: LanguageServerId,
12703        params: lsp::UnregistrationParams,
12704        cx: &mut Context<Self>,
12705    ) -> anyhow::Result<()> {
12706        let server = self
12707            .language_server_for_id(server_id)
12708            .with_context(|| format!("no server {server_id} found"))?;
12709        for unreg in params.unregisterations.iter() {
12710            match unreg.method.as_str() {
12711                "workspace/didChangeWatchedFiles" => {
12712                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12713                        local_lsp_store
12714                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12715                        true
12716                    } else {
12717                        false
12718                    };
12719                    if notify {
12720                        notify_server_capabilities_updated(&server, cx);
12721                    }
12722                }
12723                "workspace/didChangeConfiguration" => {
12724                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12725                }
12726                "workspace/didChangeWorkspaceFolders" => {
12727                    server.update_capabilities(|capabilities| {
12728                        capabilities
12729                            .workspace
12730                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12731                                workspace_folders: None,
12732                                file_operations: None,
12733                            })
12734                            .workspace_folders = None;
12735                    });
12736                    notify_server_capabilities_updated(&server, cx);
12737                }
12738                "workspace/symbol" => {
12739                    server.update_capabilities(|capabilities| {
12740                        capabilities.workspace_symbol_provider = None
12741                    });
12742                    notify_server_capabilities_updated(&server, cx);
12743                }
12744                "workspace/fileOperations" => {
12745                    server.update_capabilities(|capabilities| {
12746                        capabilities
12747                            .workspace
12748                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12749                                workspace_folders: None,
12750                                file_operations: None,
12751                            })
12752                            .file_operations = None;
12753                    });
12754                    notify_server_capabilities_updated(&server, cx);
12755                }
12756                "workspace/executeCommand" => {
12757                    server.update_capabilities(|capabilities| {
12758                        capabilities.execute_command_provider = None;
12759                    });
12760                    notify_server_capabilities_updated(&server, cx);
12761                }
12762                "textDocument/rangeFormatting" => {
12763                    server.update_capabilities(|capabilities| {
12764                        capabilities.document_range_formatting_provider = None
12765                    });
12766                    notify_server_capabilities_updated(&server, cx);
12767                }
12768                "textDocument/onTypeFormatting" => {
12769                    server.update_capabilities(|capabilities| {
12770                        capabilities.document_on_type_formatting_provider = None;
12771                    });
12772                    notify_server_capabilities_updated(&server, cx);
12773                }
12774                "textDocument/formatting" => {
12775                    server.update_capabilities(|capabilities| {
12776                        capabilities.document_formatting_provider = None;
12777                    });
12778                    notify_server_capabilities_updated(&server, cx);
12779                }
12780                "textDocument/rename" => {
12781                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12782                    notify_server_capabilities_updated(&server, cx);
12783                }
12784                "textDocument/codeAction" => {
12785                    server.update_capabilities(|capabilities| {
12786                        capabilities.code_action_provider = None;
12787                    });
12788                    notify_server_capabilities_updated(&server, cx);
12789                }
12790                "textDocument/definition" => {
12791                    server.update_capabilities(|capabilities| {
12792                        capabilities.definition_provider = None;
12793                    });
12794                    notify_server_capabilities_updated(&server, cx);
12795                }
12796                "textDocument/completion" => {
12797                    server.update_capabilities(|capabilities| {
12798                        capabilities.completion_provider = None;
12799                    });
12800                    notify_server_capabilities_updated(&server, cx);
12801                }
12802                "textDocument/hover" => {
12803                    server.update_capabilities(|capabilities| {
12804                        capabilities.hover_provider = None;
12805                    });
12806                    notify_server_capabilities_updated(&server, cx);
12807                }
12808                "textDocument/signatureHelp" => {
12809                    server.update_capabilities(|capabilities| {
12810                        capabilities.signature_help_provider = None;
12811                    });
12812                    notify_server_capabilities_updated(&server, cx);
12813                }
12814                "textDocument/didChange" => {
12815                    server.update_capabilities(|capabilities| {
12816                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12817                        sync_options.change = None;
12818                        capabilities.text_document_sync =
12819                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12820                    });
12821                    notify_server_capabilities_updated(&server, cx);
12822                }
12823                "textDocument/didSave" => {
12824                    server.update_capabilities(|capabilities| {
12825                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12826                        sync_options.save = None;
12827                        capabilities.text_document_sync =
12828                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12829                    });
12830                    notify_server_capabilities_updated(&server, cx);
12831                }
12832                "textDocument/codeLens" => {
12833                    server.update_capabilities(|capabilities| {
12834                        capabilities.code_lens_provider = None;
12835                    });
12836                    notify_server_capabilities_updated(&server, cx);
12837                }
12838                "textDocument/diagnostic" => {
12839                    let local = self
12840                        .as_local_mut()
12841                        .context("Expected LSP Store to be local")?;
12842
12843                    let state = local
12844                        .language_servers
12845                        .get_mut(&server_id)
12846                        .context("Could not obtain Language Servers state")?;
12847                    let registrations = local
12848                        .language_server_dynamic_registrations
12849                        .get_mut(&server_id)
12850                        .with_context(|| {
12851                            format!("Expected dynamic registration to exist for server {server_id}")
12852                        })?;
12853                    registrations.diagnostics
12854                        .remove(&Some(unreg.id.clone()))
12855                        .with_context(|| format!(
12856                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12857                            unreg.id)
12858                        )?;
12859                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12860
12861                    if let LanguageServerState::Running {
12862                        workspace_diagnostics_refresh_tasks,
12863                        ..
12864                    } = state
12865                    {
12866                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12867                    }
12868
12869                    self.clear_unregistered_diagnostics(
12870                        server_id,
12871                        SharedString::from(unreg.id.clone()),
12872                        cx,
12873                    )?;
12874
12875                    if removed_last_diagnostic_provider {
12876                        server.update_capabilities(|capabilities| {
12877                            debug_assert!(capabilities.diagnostic_provider.is_some());
12878                            capabilities.diagnostic_provider = None;
12879                        });
12880                    }
12881
12882                    notify_server_capabilities_updated(&server, cx);
12883                }
12884                "textDocument/documentColor" => {
12885                    server.update_capabilities(|capabilities| {
12886                        capabilities.color_provider = None;
12887                    });
12888                    notify_server_capabilities_updated(&server, cx);
12889                }
12890                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12891            }
12892        }
12893
12894        Ok(())
12895    }
12896
12897    fn clear_unregistered_diagnostics(
12898        &mut self,
12899        server_id: LanguageServerId,
12900        cleared_registration_id: SharedString,
12901        cx: &mut Context<Self>,
12902    ) -> anyhow::Result<()> {
12903        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12904
12905        self.buffer_store.update(cx, |buffer_store, cx| {
12906            for buffer_handle in buffer_store.buffers() {
12907                let buffer = buffer_handle.read(cx);
12908                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12909                let Some(abs_path) = abs_path else {
12910                    continue;
12911                };
12912                affected_abs_paths.insert(abs_path);
12913            }
12914        });
12915
12916        let local = self.as_local().context("Expected LSP Store to be local")?;
12917        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12918            let Some(worktree) = self
12919                .worktree_store
12920                .read(cx)
12921                .worktree_for_id(*worktree_id, cx)
12922            else {
12923                continue;
12924            };
12925
12926            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
12927                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
12928                    let has_matching_registration =
12929                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
12930                            entry.diagnostic.registration_id.as_ref()
12931                                == Some(&cleared_registration_id)
12932                        });
12933                    if has_matching_registration {
12934                        let abs_path = worktree.read(cx).absolutize(rel_path);
12935                        affected_abs_paths.insert(abs_path);
12936                    }
12937                }
12938            }
12939        }
12940
12941        if affected_abs_paths.is_empty() {
12942            return Ok(());
12943        }
12944
12945        // Send a fake diagnostic update which clears the state for the registration ID
12946        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
12947            affected_abs_paths
12948                .into_iter()
12949                .map(|abs_path| DocumentDiagnosticsUpdate {
12950                    diagnostics: DocumentDiagnostics {
12951                        diagnostics: Vec::new(),
12952                        document_abs_path: abs_path,
12953                        version: None,
12954                    },
12955                    result_id: None,
12956                    registration_id: Some(cleared_registration_id.clone()),
12957                    server_id,
12958                    disk_based_sources: Cow::Borrowed(&[]),
12959                })
12960                .collect();
12961
12962        let merge_registration_id = cleared_registration_id.clone();
12963        self.merge_diagnostic_entries(
12964            clears,
12965            move |_, diagnostic, _| {
12966                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
12967                    diagnostic.registration_id != Some(merge_registration_id.clone())
12968                } else {
12969                    true
12970                }
12971            },
12972            cx,
12973        )?;
12974
12975        Ok(())
12976    }
12977
12978    async fn deduplicate_range_based_lsp_requests<T>(
12979        lsp_store: &Entity<Self>,
12980        server_id: Option<LanguageServerId>,
12981        lsp_request_id: LspRequestId,
12982        proto_request: &T::ProtoRequest,
12983        range: Range<Anchor>,
12984        cx: &mut AsyncApp,
12985    ) -> Result<()>
12986    where
12987        T: LspCommand,
12988        T::ProtoRequest: proto::LspRequestMessage,
12989    {
12990        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12991        let version = deserialize_version(proto_request.buffer_version());
12992        let buffer = lsp_store.update(cx, |this, cx| {
12993            this.buffer_store.read(cx).get_existing(buffer_id)
12994        })?;
12995        buffer
12996            .update(cx, |buffer, _| buffer.wait_for_version(version))
12997            .await?;
12998        lsp_store.update(cx, |lsp_store, cx| {
12999            let buffer_snapshot = buffer.read(cx).snapshot();
13000            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13001            let chunks_queried_for = lsp_data
13002                .inlay_hints
13003                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
13004                .collect::<Vec<_>>();
13005            match chunks_queried_for.as_slice() {
13006                &[chunk] => {
13007                    let key = LspKey {
13008                        request_type: TypeId::of::<T>(),
13009                        server_queried: server_id,
13010                    };
13011                    let previous_request = lsp_data
13012                        .chunk_lsp_requests
13013                        .entry(key)
13014                        .or_default()
13015                        .insert(chunk, lsp_request_id);
13016                    if let Some((previous_request, running_requests)) =
13017                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13018                    {
13019                        running_requests.remove(&previous_request);
13020                    }
13021                }
13022                _ambiguous_chunks => {
13023                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13024                    // there, a buffer version-based check will be performed and outdated requests discarded.
13025                }
13026            }
13027            anyhow::Ok(())
13028        })?;
13029
13030        Ok(())
13031    }
13032
13033    async fn query_lsp_locally<T>(
13034        lsp_store: Entity<Self>,
13035        for_server_id: Option<LanguageServerId>,
13036        sender_id: proto::PeerId,
13037        lsp_request_id: LspRequestId,
13038        proto_request: T::ProtoRequest,
13039        position: Option<Anchor>,
13040        cx: &mut AsyncApp,
13041    ) -> Result<()>
13042    where
13043        T: LspCommand + Clone,
13044        T::ProtoRequest: proto::LspRequestMessage,
13045        <T::ProtoRequest as proto::RequestMessage>::Response:
13046            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13047    {
13048        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13049        let version = deserialize_version(proto_request.buffer_version());
13050        let buffer = lsp_store.update(cx, |this, cx| {
13051            this.buffer_store.read(cx).get_existing(buffer_id)
13052        })?;
13053        buffer
13054            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13055            .await?;
13056        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13057        let request =
13058            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13059        let key = LspKey {
13060            request_type: TypeId::of::<T>(),
13061            server_queried: for_server_id,
13062        };
13063        lsp_store.update(cx, |lsp_store, cx| {
13064            let request_task = match for_server_id {
13065                Some(server_id) => {
13066                    let server_task = lsp_store.request_lsp(
13067                        buffer.clone(),
13068                        LanguageServerToQuery::Other(server_id),
13069                        request.clone(),
13070                        cx,
13071                    );
13072                    cx.background_spawn(async move {
13073                        let mut responses = Vec::new();
13074                        match server_task.await {
13075                            Ok(response) => responses.push((server_id, response)),
13076                            // rust-analyzer likes to error with this when its still loading up
13077                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13078                            Err(e) => log::error!(
13079                                "Error handling response for request {request:?}: {e:#}"
13080                            ),
13081                        }
13082                        responses
13083                    })
13084                }
13085                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13086            };
13087            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13088            if T::ProtoRequest::stop_previous_requests() {
13089                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13090                    lsp_requests.clear();
13091                }
13092            }
13093            lsp_data.lsp_requests.entry(key).or_default().insert(
13094                lsp_request_id,
13095                cx.spawn(async move |lsp_store, cx| {
13096                    let response = request_task.await;
13097                    lsp_store
13098                        .update(cx, |lsp_store, cx| {
13099                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13100                            {
13101                                let response = response
13102                                    .into_iter()
13103                                    .map(|(server_id, response)| {
13104                                        (
13105                                            server_id.to_proto(),
13106                                            T::response_to_proto(
13107                                                response,
13108                                                lsp_store,
13109                                                sender_id,
13110                                                &buffer_version,
13111                                                cx,
13112                                            )
13113                                            .into(),
13114                                        )
13115                                    })
13116                                    .collect::<HashMap<_, _>>();
13117                                match client.send_lsp_response::<T::ProtoRequest>(
13118                                    project_id,
13119                                    lsp_request_id,
13120                                    response,
13121                                ) {
13122                                    Ok(()) => {}
13123                                    Err(e) => {
13124                                        log::error!("Failed to send LSP response: {e:#}",)
13125                                    }
13126                                }
13127                            }
13128                        })
13129                        .ok();
13130                }),
13131            );
13132        });
13133        Ok(())
13134    }
13135
13136    fn take_text_document_sync_options(
13137        capabilities: &mut lsp::ServerCapabilities,
13138    ) -> lsp::TextDocumentSyncOptions {
13139        match capabilities.text_document_sync.take() {
13140            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13141            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13142                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13143                sync_options.change = Some(sync_kind);
13144                sync_options
13145            }
13146            None => lsp::TextDocumentSyncOptions::default(),
13147        }
13148    }
13149
13150    #[cfg(any(test, feature = "test-support"))]
13151    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
13152        Some(
13153            self.lsp_data
13154                .get_mut(&buffer_id)?
13155                .code_lens
13156                .take()?
13157                .update
13158                .take()?
13159                .1,
13160        )
13161    }
13162
13163    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13164        self.downstream_client.clone()
13165    }
13166
13167    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13168        self.worktree_store.clone()
13169    }
13170
13171    /// Gets what's stored in the LSP data for the given buffer.
13172    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13173        self.lsp_data.get_mut(&buffer_id)
13174    }
13175
13176    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13177    /// new [`BufferLspData`] will be created to replace the previous state.
13178    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13179        let (buffer_id, buffer_version) =
13180            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13181        let lsp_data = self
13182            .lsp_data
13183            .entry(buffer_id)
13184            .or_insert_with(|| BufferLspData::new(buffer, cx));
13185        if buffer_version.changed_since(&lsp_data.buffer_version) {
13186            *lsp_data = BufferLspData::new(buffer, cx);
13187        }
13188        lsp_data
13189    }
13190}
13191
13192// Registration with registerOptions as null, should fallback to true.
13193// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13194fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13195    reg: lsp::Registration,
13196) -> Result<OneOf<bool, T>> {
13197    Ok(match reg.register_options {
13198        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13199        None => OneOf::Left(true),
13200    })
13201}
13202
13203fn subscribe_to_binary_statuses(
13204    languages: &Arc<LanguageRegistry>,
13205    cx: &mut Context<'_, LspStore>,
13206) -> Task<()> {
13207    let mut server_statuses = languages.language_server_binary_statuses();
13208    cx.spawn(async move |lsp_store, cx| {
13209        while let Some((server_name, binary_status)) = server_statuses.next().await {
13210            if lsp_store
13211                .update(cx, |_, cx| {
13212                    let mut message = None;
13213                    let binary_status = match binary_status {
13214                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13215                        BinaryStatus::CheckingForUpdate => {
13216                            proto::ServerBinaryStatus::CheckingForUpdate
13217                        }
13218                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13219                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13220                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13221                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13222                        BinaryStatus::Failed { error } => {
13223                            message = Some(error);
13224                            proto::ServerBinaryStatus::Failed
13225                        }
13226                    };
13227                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13228                        // Binary updates are about the binary that might not have any language server id at that point.
13229                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13230                        language_server_id: LanguageServerId(0),
13231                        name: Some(server_name),
13232                        message: proto::update_language_server::Variant::StatusUpdate(
13233                            proto::StatusUpdate {
13234                                message,
13235                                status: Some(proto::status_update::Status::Binary(
13236                                    binary_status as i32,
13237                                )),
13238                            },
13239                        ),
13240                    });
13241                })
13242                .is_err()
13243            {
13244                break;
13245            }
13246        }
13247    })
13248}
13249
13250fn lsp_workspace_diagnostics_refresh(
13251    registration_id: Option<String>,
13252    options: DiagnosticServerCapabilities,
13253    server: Arc<LanguageServer>,
13254    cx: &mut Context<'_, LspStore>,
13255) -> Option<WorkspaceRefreshTask> {
13256    let identifier = workspace_diagnostic_identifier(&options)?;
13257    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13258
13259    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13260    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13261    refresh_tx.try_send(()).ok();
13262
13263    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13264        let mut attempts = 0;
13265        let max_attempts = 50;
13266        let mut requests = 0;
13267
13268        loop {
13269            let Some(()) = refresh_rx.recv().await else {
13270                return;
13271            };
13272
13273            'request: loop {
13274                requests += 1;
13275                if attempts > max_attempts {
13276                    log::error!(
13277                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13278                    );
13279                    return;
13280                }
13281                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13282                cx.background_executor()
13283                    .timer(Duration::from_millis(backoff_millis))
13284                    .await;
13285                attempts += 1;
13286
13287                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13288                    lsp_store
13289                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13290                        .into_iter()
13291                        .filter_map(|(abs_path, result_id)| {
13292                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13293                            Some(lsp::PreviousResultId {
13294                                uri,
13295                                value: result_id.to_string(),
13296                            })
13297                        })
13298                        .collect()
13299                }) else {
13300                    return;
13301                };
13302
13303                let token = if let Some(registration_id) = &registration_id {
13304                    format!(
13305                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13306                        server.server_id(),
13307                    )
13308                } else {
13309                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13310                };
13311
13312                progress_rx.try_recv().ok();
13313                let timer =
13314                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13315                let progress = pin!(progress_rx.recv().fuse());
13316                let response_result = server
13317                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13318                        lsp::WorkspaceDiagnosticParams {
13319                            previous_result_ids,
13320                            identifier: identifier.clone(),
13321                            work_done_progress_params: Default::default(),
13322                            partial_result_params: lsp::PartialResultParams {
13323                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13324                            },
13325                        },
13326                        select(timer, progress).then(|either| match either {
13327                            Either::Left((message, ..)) => ready(message).left_future(),
13328                            Either::Right(..) => pending::<String>().right_future(),
13329                        }),
13330                    )
13331                    .await;
13332
13333                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13334                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13335                match response_result {
13336                    ConnectionResult::Timeout => {
13337                        log::error!("Timeout during workspace diagnostics pull");
13338                        continue 'request;
13339                    }
13340                    ConnectionResult::ConnectionReset => {
13341                        log::error!("Server closed a workspace diagnostics pull request");
13342                        continue 'request;
13343                    }
13344                    ConnectionResult::Result(Err(e)) => {
13345                        log::error!("Error during workspace diagnostics pull: {e:#}");
13346                        break 'request;
13347                    }
13348                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13349                        attempts = 0;
13350                        if lsp_store
13351                            .update(cx, |lsp_store, cx| {
13352                                lsp_store.apply_workspace_diagnostic_report(
13353                                    server.server_id(),
13354                                    pulled_diagnostics,
13355                                    registration_id_shared.clone(),
13356                                    cx,
13357                                )
13358                            })
13359                            .is_err()
13360                        {
13361                            return;
13362                        }
13363                        break 'request;
13364                    }
13365                }
13366            }
13367        }
13368    });
13369
13370    Some(WorkspaceRefreshTask {
13371        refresh_tx,
13372        progress_tx,
13373        task: workspace_query_language_server,
13374    })
13375}
13376
13377fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13378    match &options {
13379        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13380            diagnostic_options.identifier.clone()
13381        }
13382        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13383            let diagnostic_options = &registration_options.diagnostic_options;
13384            diagnostic_options.identifier.clone()
13385        }
13386    }
13387}
13388
13389fn workspace_diagnostic_identifier(
13390    options: &DiagnosticServerCapabilities,
13391) -> Option<Option<String>> {
13392    match &options {
13393        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13394            if !diagnostic_options.workspace_diagnostics {
13395                return None;
13396            }
13397            Some(diagnostic_options.identifier.clone())
13398        }
13399        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13400            let diagnostic_options = &registration_options.diagnostic_options;
13401            if !diagnostic_options.workspace_diagnostics {
13402                return None;
13403            }
13404            Some(diagnostic_options.identifier.clone())
13405        }
13406    }
13407}
13408
13409fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13410    let CompletionSource::BufferWord {
13411        word_range,
13412        resolved,
13413    } = &mut completion.source
13414    else {
13415        return;
13416    };
13417    if *resolved {
13418        return;
13419    }
13420
13421    if completion.new_text
13422        != snapshot
13423            .text_for_range(word_range.clone())
13424            .collect::<String>()
13425    {
13426        return;
13427    }
13428
13429    let mut offset = 0;
13430    for chunk in snapshot.chunks(word_range.clone(), true) {
13431        let end_offset = offset + chunk.text.len();
13432        if let Some(highlight_id) = chunk.syntax_highlight_id {
13433            completion
13434                .label
13435                .runs
13436                .push((offset..end_offset, highlight_id));
13437        }
13438        offset = end_offset;
13439    }
13440    *resolved = true;
13441}
13442
13443impl EventEmitter<LspStoreEvent> for LspStore {}
13444
13445fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13446    hover
13447        .contents
13448        .retain(|hover_block| !hover_block.text.trim().is_empty());
13449    if hover.contents.is_empty() {
13450        None
13451    } else {
13452        Some(hover)
13453    }
13454}
13455
13456async fn populate_labels_for_completions(
13457    new_completions: Vec<CoreCompletion>,
13458    language: Option<Arc<Language>>,
13459    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13460) -> Vec<Completion> {
13461    let lsp_completions = new_completions
13462        .iter()
13463        .filter_map(|new_completion| {
13464            new_completion
13465                .source
13466                .lsp_completion(true)
13467                .map(|lsp_completion| lsp_completion.into_owned())
13468        })
13469        .collect::<Vec<_>>();
13470
13471    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13472        lsp_adapter
13473            .labels_for_completions(&lsp_completions, language)
13474            .await
13475            .log_err()
13476            .unwrap_or_default()
13477    } else {
13478        Vec::new()
13479    }
13480    .into_iter()
13481    .fuse();
13482
13483    let mut completions = Vec::new();
13484    for completion in new_completions {
13485        match completion.source.lsp_completion(true) {
13486            Some(lsp_completion) => {
13487                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13488
13489                let mut label = labels.next().flatten().unwrap_or_else(|| {
13490                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13491                });
13492                ensure_uniform_list_compatible_label(&mut label);
13493                completions.push(Completion {
13494                    label,
13495                    documentation,
13496                    replace_range: completion.replace_range,
13497                    new_text: completion.new_text,
13498                    insert_text_mode: lsp_completion.insert_text_mode,
13499                    source: completion.source,
13500                    icon_path: None,
13501                    confirm: None,
13502                    match_start: None,
13503                    snippet_deduplication_key: None,
13504                });
13505            }
13506            None => {
13507                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13508                ensure_uniform_list_compatible_label(&mut label);
13509                completions.push(Completion {
13510                    label,
13511                    documentation: None,
13512                    replace_range: completion.replace_range,
13513                    new_text: completion.new_text,
13514                    source: completion.source,
13515                    insert_text_mode: None,
13516                    icon_path: None,
13517                    confirm: None,
13518                    match_start: None,
13519                    snippet_deduplication_key: None,
13520                });
13521            }
13522        }
13523    }
13524    completions
13525}
13526
13527#[derive(Debug)]
13528pub enum LanguageServerToQuery {
13529    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13530    FirstCapable,
13531    /// Query a specific language server.
13532    Other(LanguageServerId),
13533}
13534
13535#[derive(Default)]
13536struct RenamePathsWatchedForServer {
13537    did_rename: Vec<RenameActionPredicate>,
13538    will_rename: Vec<RenameActionPredicate>,
13539}
13540
13541impl RenamePathsWatchedForServer {
13542    fn with_did_rename_patterns(
13543        mut self,
13544        did_rename: Option<&FileOperationRegistrationOptions>,
13545    ) -> Self {
13546        if let Some(did_rename) = did_rename {
13547            self.did_rename = did_rename
13548                .filters
13549                .iter()
13550                .filter_map(|filter| filter.try_into().log_err())
13551                .collect();
13552        }
13553        self
13554    }
13555    fn with_will_rename_patterns(
13556        mut self,
13557        will_rename: Option<&FileOperationRegistrationOptions>,
13558    ) -> Self {
13559        if let Some(will_rename) = will_rename {
13560            self.will_rename = will_rename
13561                .filters
13562                .iter()
13563                .filter_map(|filter| filter.try_into().log_err())
13564                .collect();
13565        }
13566        self
13567    }
13568
13569    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13570        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13571    }
13572    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13573        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13574    }
13575}
13576
13577impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13578    type Error = globset::Error;
13579    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13580        Ok(Self {
13581            kind: ops.pattern.matches.clone(),
13582            glob: GlobBuilder::new(&ops.pattern.glob)
13583                .case_insensitive(
13584                    ops.pattern
13585                        .options
13586                        .as_ref()
13587                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13588                )
13589                .build()?
13590                .compile_matcher(),
13591        })
13592    }
13593}
13594struct RenameActionPredicate {
13595    glob: GlobMatcher,
13596    kind: Option<FileOperationPatternKind>,
13597}
13598
13599impl RenameActionPredicate {
13600    // Returns true if language server should be notified
13601    fn eval(&self, path: &str, is_dir: bool) -> bool {
13602        self.kind.as_ref().is_none_or(|kind| {
13603            let expected_kind = if is_dir {
13604                FileOperationPatternKind::Folder
13605            } else {
13606                FileOperationPatternKind::File
13607            };
13608            kind == &expected_kind
13609        }) && self.glob.is_match(path)
13610    }
13611}
13612
13613#[derive(Default)]
13614struct LanguageServerWatchedPaths {
13615    worktree_paths: HashMap<WorktreeId, GlobSet>,
13616    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13617}
13618
13619#[derive(Default)]
13620struct LanguageServerWatchedPathsBuilder {
13621    worktree_paths: HashMap<WorktreeId, GlobSet>,
13622    abs_paths: HashMap<Arc<Path>, GlobSet>,
13623}
13624
13625impl LanguageServerWatchedPathsBuilder {
13626    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13627        self.worktree_paths.insert(worktree_id, glob_set);
13628    }
13629    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13630        self.abs_paths.insert(path, glob_set);
13631    }
13632    fn build(
13633        self,
13634        fs: Arc<dyn Fs>,
13635        language_server_id: LanguageServerId,
13636        cx: &mut Context<LspStore>,
13637    ) -> LanguageServerWatchedPaths {
13638        let lsp_store = cx.weak_entity();
13639
13640        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13641        let abs_paths = self
13642            .abs_paths
13643            .into_iter()
13644            .map(|(abs_path, globset)| {
13645                let task = cx.spawn({
13646                    let abs_path = abs_path.clone();
13647                    let fs = fs.clone();
13648
13649                    let lsp_store = lsp_store.clone();
13650                    async move |_, cx| {
13651                        maybe!(async move {
13652                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13653                            while let Some(update) = push_updates.0.next().await {
13654                                let action = lsp_store
13655                                    .update(cx, |this, _| {
13656                                        let Some(local) = this.as_local() else {
13657                                            return ControlFlow::Break(());
13658                                        };
13659                                        let Some(watcher) = local
13660                                            .language_server_watched_paths
13661                                            .get(&language_server_id)
13662                                        else {
13663                                            return ControlFlow::Break(());
13664                                        };
13665                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13666                                            "Watched abs path is not registered with a watcher",
13667                                        );
13668                                        let matching_entries = update
13669                                            .into_iter()
13670                                            .filter(|event| globs.is_match(&event.path))
13671                                            .collect::<Vec<_>>();
13672                                        this.lsp_notify_abs_paths_changed(
13673                                            language_server_id,
13674                                            matching_entries,
13675                                        );
13676                                        ControlFlow::Continue(())
13677                                    })
13678                                    .ok()?;
13679
13680                                if action.is_break() {
13681                                    break;
13682                                }
13683                            }
13684                            Some(())
13685                        })
13686                        .await;
13687                    }
13688                });
13689                (abs_path, (globset, task))
13690            })
13691            .collect();
13692        LanguageServerWatchedPaths {
13693            worktree_paths: self.worktree_paths,
13694            abs_paths,
13695        }
13696    }
13697}
13698
13699struct LspBufferSnapshot {
13700    version: i32,
13701    snapshot: TextBufferSnapshot,
13702}
13703
13704/// A prompt requested by LSP server.
13705#[derive(Clone, Debug)]
13706pub struct LanguageServerPromptRequest {
13707    pub level: PromptLevel,
13708    pub message: String,
13709    pub actions: Vec<MessageActionItem>,
13710    pub lsp_name: String,
13711    pub(crate) response_channel: Sender<MessageActionItem>,
13712}
13713
13714impl LanguageServerPromptRequest {
13715    pub async fn respond(self, index: usize) -> Option<()> {
13716        if let Some(response) = self.actions.into_iter().nth(index) {
13717            self.response_channel.send(response).await.ok()
13718        } else {
13719            None
13720        }
13721    }
13722}
13723impl PartialEq for LanguageServerPromptRequest {
13724    fn eq(&self, other: &Self) -> bool {
13725        self.message == other.message && self.actions == other.actions
13726    }
13727}
13728
13729#[derive(Clone, Debug, PartialEq)]
13730pub enum LanguageServerLogType {
13731    Log(MessageType),
13732    Trace { verbose_info: Option<String> },
13733    Rpc { received: bool },
13734}
13735
13736impl LanguageServerLogType {
13737    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13738        match self {
13739            Self::Log(log_type) => {
13740                use proto::log_message::LogLevel;
13741                let level = match *log_type {
13742                    MessageType::ERROR => LogLevel::Error,
13743                    MessageType::WARNING => LogLevel::Warning,
13744                    MessageType::INFO => LogLevel::Info,
13745                    MessageType::LOG => LogLevel::Log,
13746                    other => {
13747                        log::warn!("Unknown lsp log message type: {other:?}");
13748                        LogLevel::Log
13749                    }
13750                };
13751                proto::language_server_log::LogType::Log(proto::LogMessage {
13752                    level: level as i32,
13753                })
13754            }
13755            Self::Trace { verbose_info } => {
13756                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13757                    verbose_info: verbose_info.to_owned(),
13758                })
13759            }
13760            Self::Rpc { received } => {
13761                let kind = if *received {
13762                    proto::rpc_message::Kind::Received
13763                } else {
13764                    proto::rpc_message::Kind::Sent
13765                };
13766                let kind = kind as i32;
13767                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13768            }
13769        }
13770    }
13771
13772    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13773        use proto::log_message::LogLevel;
13774        use proto::rpc_message;
13775        match log_type {
13776            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13777                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13778                    LogLevel::Error => MessageType::ERROR,
13779                    LogLevel::Warning => MessageType::WARNING,
13780                    LogLevel::Info => MessageType::INFO,
13781                    LogLevel::Log => MessageType::LOG,
13782                },
13783            ),
13784            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13785                verbose_info: trace_message.verbose_info,
13786            },
13787            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13788                received: match rpc_message::Kind::from_i32(message.kind)
13789                    .unwrap_or(rpc_message::Kind::Received)
13790                {
13791                    rpc_message::Kind::Received => true,
13792                    rpc_message::Kind::Sent => false,
13793                },
13794            },
13795        }
13796    }
13797}
13798
13799pub struct WorkspaceRefreshTask {
13800    refresh_tx: mpsc::Sender<()>,
13801    progress_tx: mpsc::Sender<()>,
13802    #[allow(dead_code)]
13803    task: Task<()>,
13804}
13805
13806pub enum LanguageServerState {
13807    Starting {
13808        startup: Task<Option<Arc<LanguageServer>>>,
13809        /// List of language servers that will be added to the workspace once it's initialization completes.
13810        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13811    },
13812
13813    Running {
13814        adapter: Arc<CachedLspAdapter>,
13815        server: Arc<LanguageServer>,
13816        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13817        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13818    },
13819}
13820
13821impl LanguageServerState {
13822    fn add_workspace_folder(&self, uri: Uri) {
13823        match self {
13824            LanguageServerState::Starting {
13825                pending_workspace_folders,
13826                ..
13827            } => {
13828                pending_workspace_folders.lock().insert(uri);
13829            }
13830            LanguageServerState::Running { server, .. } => {
13831                server.add_workspace_folder(uri);
13832            }
13833        }
13834    }
13835    fn _remove_workspace_folder(&self, uri: Uri) {
13836        match self {
13837            LanguageServerState::Starting {
13838                pending_workspace_folders,
13839                ..
13840            } => {
13841                pending_workspace_folders.lock().remove(&uri);
13842            }
13843            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13844        }
13845    }
13846}
13847
13848impl std::fmt::Debug for LanguageServerState {
13849    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13850        match self {
13851            LanguageServerState::Starting { .. } => {
13852                f.debug_struct("LanguageServerState::Starting").finish()
13853            }
13854            LanguageServerState::Running { .. } => {
13855                f.debug_struct("LanguageServerState::Running").finish()
13856            }
13857        }
13858    }
13859}
13860
13861#[derive(Clone, Debug, Serialize)]
13862pub struct LanguageServerProgress {
13863    pub is_disk_based_diagnostics_progress: bool,
13864    pub is_cancellable: bool,
13865    pub title: Option<String>,
13866    pub message: Option<String>,
13867    pub percentage: Option<usize>,
13868    #[serde(skip_serializing)]
13869    pub last_update_at: Instant,
13870}
13871
13872#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13873pub struct DiagnosticSummary {
13874    pub error_count: usize,
13875    pub warning_count: usize,
13876}
13877
13878impl DiagnosticSummary {
13879    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13880        let mut this = Self {
13881            error_count: 0,
13882            warning_count: 0,
13883        };
13884
13885        for entry in diagnostics {
13886            if entry.diagnostic.is_primary {
13887                match entry.diagnostic.severity {
13888                    DiagnosticSeverity::ERROR => this.error_count += 1,
13889                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13890                    _ => {}
13891                }
13892            }
13893        }
13894
13895        this
13896    }
13897
13898    pub fn is_empty(&self) -> bool {
13899        self.error_count == 0 && self.warning_count == 0
13900    }
13901
13902    pub fn to_proto(
13903        self,
13904        language_server_id: LanguageServerId,
13905        path: &RelPath,
13906    ) -> proto::DiagnosticSummary {
13907        proto::DiagnosticSummary {
13908            path: path.to_proto(),
13909            language_server_id: language_server_id.0 as u64,
13910            error_count: self.error_count as u32,
13911            warning_count: self.warning_count as u32,
13912        }
13913    }
13914}
13915
13916#[derive(Clone, Debug)]
13917pub enum CompletionDocumentation {
13918    /// There is no documentation for this completion.
13919    Undocumented,
13920    /// A single line of documentation.
13921    SingleLine(SharedString),
13922    /// Multiple lines of plain text documentation.
13923    MultiLinePlainText(SharedString),
13924    /// Markdown documentation.
13925    MultiLineMarkdown(SharedString),
13926    /// Both single line and multiple lines of plain text documentation.
13927    SingleLineAndMultiLinePlainText {
13928        single_line: SharedString,
13929        plain_text: Option<SharedString>,
13930    },
13931}
13932
13933impl CompletionDocumentation {
13934    #[cfg(any(test, feature = "test-support"))]
13935    pub fn text(&self) -> SharedString {
13936        match self {
13937            CompletionDocumentation::Undocumented => "".into(),
13938            CompletionDocumentation::SingleLine(s) => s.clone(),
13939            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13940            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13941            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13942                single_line.clone()
13943            }
13944        }
13945    }
13946}
13947
13948impl From<lsp::Documentation> for CompletionDocumentation {
13949    fn from(docs: lsp::Documentation) -> Self {
13950        match docs {
13951            lsp::Documentation::String(text) => {
13952                if text.lines().count() <= 1 {
13953                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
13954                } else {
13955                    CompletionDocumentation::MultiLinePlainText(text.into())
13956                }
13957            }
13958
13959            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13960                lsp::MarkupKind::PlainText => {
13961                    if value.lines().count() <= 1 {
13962                        CompletionDocumentation::SingleLine(value.into())
13963                    } else {
13964                        CompletionDocumentation::MultiLinePlainText(value.into())
13965                    }
13966                }
13967
13968                lsp::MarkupKind::Markdown => {
13969                    CompletionDocumentation::MultiLineMarkdown(value.into())
13970                }
13971            },
13972        }
13973    }
13974}
13975
13976pub enum ResolvedHint {
13977    Resolved(InlayHint),
13978    Resolving(Shared<Task<()>>),
13979}
13980
13981fn glob_literal_prefix(glob: &Path) -> PathBuf {
13982    glob.components()
13983        .take_while(|component| match component {
13984            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13985            _ => true,
13986        })
13987        .collect()
13988}
13989
13990pub struct SshLspAdapter {
13991    name: LanguageServerName,
13992    binary: LanguageServerBinary,
13993    initialization_options: Option<String>,
13994    code_action_kinds: Option<Vec<CodeActionKind>>,
13995}
13996
13997impl SshLspAdapter {
13998    pub fn new(
13999        name: LanguageServerName,
14000        binary: LanguageServerBinary,
14001        initialization_options: Option<String>,
14002        code_action_kinds: Option<String>,
14003    ) -> Self {
14004        Self {
14005            name,
14006            binary,
14007            initialization_options,
14008            code_action_kinds: code_action_kinds
14009                .as_ref()
14010                .and_then(|c| serde_json::from_str(c).ok()),
14011        }
14012    }
14013}
14014
14015impl LspInstaller for SshLspAdapter {
14016    type BinaryVersion = ();
14017    async fn check_if_user_installed(
14018        &self,
14019        _: &dyn LspAdapterDelegate,
14020        _: Option<Toolchain>,
14021        _: &AsyncApp,
14022    ) -> Option<LanguageServerBinary> {
14023        Some(self.binary.clone())
14024    }
14025
14026    async fn cached_server_binary(
14027        &self,
14028        _: PathBuf,
14029        _: &dyn LspAdapterDelegate,
14030    ) -> Option<LanguageServerBinary> {
14031        None
14032    }
14033
14034    async fn fetch_latest_server_version(
14035        &self,
14036        _: &dyn LspAdapterDelegate,
14037        _: bool,
14038        _: &mut AsyncApp,
14039    ) -> Result<()> {
14040        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14041    }
14042
14043    async fn fetch_server_binary(
14044        &self,
14045        _: (),
14046        _: PathBuf,
14047        _: &dyn LspAdapterDelegate,
14048    ) -> Result<LanguageServerBinary> {
14049        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14050    }
14051}
14052
14053#[async_trait(?Send)]
14054impl LspAdapter for SshLspAdapter {
14055    fn name(&self) -> LanguageServerName {
14056        self.name.clone()
14057    }
14058
14059    async fn initialization_options(
14060        self: Arc<Self>,
14061        _: &Arc<dyn LspAdapterDelegate>,
14062    ) -> Result<Option<serde_json::Value>> {
14063        let Some(options) = &self.initialization_options else {
14064            return Ok(None);
14065        };
14066        let result = serde_json::from_str(options)?;
14067        Ok(result)
14068    }
14069
14070    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14071        self.code_action_kinds.clone()
14072    }
14073}
14074
14075pub fn language_server_settings<'a>(
14076    delegate: &'a dyn LspAdapterDelegate,
14077    language: &LanguageServerName,
14078    cx: &'a App,
14079) -> Option<&'a LspSettings> {
14080    language_server_settings_for(
14081        SettingsLocation {
14082            worktree_id: delegate.worktree_id(),
14083            path: RelPath::empty(),
14084        },
14085        language,
14086        cx,
14087    )
14088}
14089
14090pub fn language_server_settings_for<'a>(
14091    location: SettingsLocation<'a>,
14092    language: &LanguageServerName,
14093    cx: &'a App,
14094) -> Option<&'a LspSettings> {
14095    ProjectSettings::get(Some(location), cx).lsp.get(language)
14096}
14097
14098pub struct LocalLspAdapterDelegate {
14099    lsp_store: WeakEntity<LspStore>,
14100    worktree: worktree::Snapshot,
14101    fs: Arc<dyn Fs>,
14102    http_client: Arc<dyn HttpClient>,
14103    language_registry: Arc<LanguageRegistry>,
14104    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14105}
14106
14107impl LocalLspAdapterDelegate {
14108    pub fn new(
14109        language_registry: Arc<LanguageRegistry>,
14110        environment: &Entity<ProjectEnvironment>,
14111        lsp_store: WeakEntity<LspStore>,
14112        worktree: &Entity<Worktree>,
14113        http_client: Arc<dyn HttpClient>,
14114        fs: Arc<dyn Fs>,
14115        cx: &mut App,
14116    ) -> Arc<Self> {
14117        let load_shell_env_task =
14118            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14119
14120        Arc::new(Self {
14121            lsp_store,
14122            worktree: worktree.read(cx).snapshot(),
14123            fs,
14124            http_client,
14125            language_registry,
14126            load_shell_env_task,
14127        })
14128    }
14129
14130    pub fn from_local_lsp(
14131        local: &LocalLspStore,
14132        worktree: &Entity<Worktree>,
14133        cx: &mut App,
14134    ) -> Arc<Self> {
14135        Self::new(
14136            local.languages.clone(),
14137            &local.environment,
14138            local.weak.clone(),
14139            worktree,
14140            local.http_client.clone(),
14141            local.fs.clone(),
14142            cx,
14143        )
14144    }
14145}
14146
14147#[async_trait]
14148impl LspAdapterDelegate for LocalLspAdapterDelegate {
14149    fn show_notification(&self, message: &str, cx: &mut App) {
14150        self.lsp_store
14151            .update(cx, |_, cx| {
14152                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14153            })
14154            .ok();
14155    }
14156
14157    fn http_client(&self) -> Arc<dyn HttpClient> {
14158        self.http_client.clone()
14159    }
14160
14161    fn worktree_id(&self) -> WorktreeId {
14162        self.worktree.id()
14163    }
14164
14165    fn worktree_root_path(&self) -> &Path {
14166        self.worktree.abs_path().as_ref()
14167    }
14168
14169    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
14170        self.worktree.resolve_executable_path(path)
14171    }
14172
14173    async fn shell_env(&self) -> HashMap<String, String> {
14174        let task = self.load_shell_env_task.clone();
14175        task.await.unwrap_or_default()
14176    }
14177
14178    async fn npm_package_installed_version(
14179        &self,
14180        package_name: &str,
14181    ) -> Result<Option<(PathBuf, Version)>> {
14182        let local_package_directory = self.worktree_root_path();
14183        let node_modules_directory = local_package_directory.join("node_modules");
14184
14185        if let Some(version) =
14186            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14187        {
14188            return Ok(Some((node_modules_directory, version)));
14189        }
14190        let Some(npm) = self.which("npm".as_ref()).await else {
14191            log::warn!(
14192                "Failed to find npm executable for {:?}",
14193                local_package_directory
14194            );
14195            return Ok(None);
14196        };
14197
14198        let env = self.shell_env().await;
14199        let output = util::command::new_smol_command(&npm)
14200            .args(["root", "-g"])
14201            .envs(env)
14202            .current_dir(local_package_directory)
14203            .output()
14204            .await?;
14205        let global_node_modules =
14206            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14207
14208        if let Some(version) =
14209            read_package_installed_version(global_node_modules.clone(), package_name).await?
14210        {
14211            return Ok(Some((global_node_modules, version)));
14212        }
14213        return Ok(None);
14214    }
14215
14216    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14217        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14218        if self.fs.is_file(&worktree_abs_path).await {
14219            worktree_abs_path.pop();
14220        }
14221
14222        let env = self.shell_env().await;
14223
14224        let shell_path = env.get("PATH").cloned();
14225
14226        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14227    }
14228
14229    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14230        let mut working_dir = self.worktree_root_path().to_path_buf();
14231        if self.fs.is_file(&working_dir).await {
14232            working_dir.pop();
14233        }
14234        let output = util::command::new_smol_command(&command.path)
14235            .args(command.arguments)
14236            .envs(command.env.clone().unwrap_or_default())
14237            .current_dir(working_dir)
14238            .output()
14239            .await?;
14240
14241        anyhow::ensure!(
14242            output.status.success(),
14243            "{}, stdout: {:?}, stderr: {:?}",
14244            output.status,
14245            String::from_utf8_lossy(&output.stdout),
14246            String::from_utf8_lossy(&output.stderr)
14247        );
14248        Ok(())
14249    }
14250
14251    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14252        self.language_registry
14253            .update_lsp_binary_status(server_name, status);
14254    }
14255
14256    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14257        self.language_registry
14258            .all_lsp_adapters()
14259            .into_iter()
14260            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14261            .collect()
14262    }
14263
14264    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14265        let dir = self.language_registry.language_server_download_dir(name)?;
14266
14267        if !dir.exists() {
14268            smol::fs::create_dir_all(&dir)
14269                .await
14270                .context("failed to create container directory")
14271                .log_err()?;
14272        }
14273
14274        Some(dir)
14275    }
14276
14277    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14278        let entry = self
14279            .worktree
14280            .entry_for_path(path)
14281            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14282        let abs_path = self.worktree.absolutize(&entry.path);
14283        self.fs.load(&abs_path).await
14284    }
14285}
14286
14287async fn populate_labels_for_symbols(
14288    symbols: Vec<CoreSymbol>,
14289    language_registry: &Arc<LanguageRegistry>,
14290    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14291    output: &mut Vec<Symbol>,
14292) {
14293    #[allow(clippy::mutable_key_type)]
14294    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14295
14296    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14297    for symbol in symbols {
14298        let Some(file_name) = symbol.path.file_name() else {
14299            continue;
14300        };
14301        let language = language_registry
14302            .load_language_for_file_path(Path::new(file_name))
14303            .await
14304            .ok()
14305            .or_else(|| {
14306                unknown_paths.insert(file_name.into());
14307                None
14308            });
14309        symbols_by_language
14310            .entry(language)
14311            .or_default()
14312            .push(symbol);
14313    }
14314
14315    for unknown_path in unknown_paths {
14316        log::info!("no language found for symbol in file {unknown_path:?}");
14317    }
14318
14319    let mut label_params = Vec::new();
14320    for (language, mut symbols) in symbols_by_language {
14321        label_params.clear();
14322        label_params.extend(
14323            symbols
14324                .iter_mut()
14325                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14326        );
14327
14328        let mut labels = Vec::new();
14329        if let Some(language) = language {
14330            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14331                language_registry
14332                    .lsp_adapters(&language.name())
14333                    .first()
14334                    .cloned()
14335            });
14336            if let Some(lsp_adapter) = lsp_adapter {
14337                labels = lsp_adapter
14338                    .labels_for_symbols(&label_params, &language)
14339                    .await
14340                    .log_err()
14341                    .unwrap_or_default();
14342            }
14343        }
14344
14345        for ((symbol, (name, _)), label) in symbols
14346            .into_iter()
14347            .zip(label_params.drain(..))
14348            .zip(labels.into_iter().chain(iter::repeat(None)))
14349        {
14350            output.push(Symbol {
14351                language_server_name: symbol.language_server_name,
14352                source_worktree_id: symbol.source_worktree_id,
14353                source_language_server_id: symbol.source_language_server_id,
14354                path: symbol.path,
14355                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14356                name,
14357                kind: symbol.kind,
14358                range: symbol.range,
14359            });
14360        }
14361    }
14362}
14363
14364fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14365    match server.capabilities().text_document_sync.as_ref()? {
14366        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14367            // Server wants didSave but didn't specify includeText.
14368            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14369            // Server doesn't want didSave at all.
14370            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14371            // Server provided SaveOptions.
14372            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14373                Some(save_options.include_text.unwrap_or(false))
14374            }
14375        },
14376        // We do not have any save info. Kind affects didChange only.
14377        lsp::TextDocumentSyncCapability::Kind(_) => None,
14378    }
14379}
14380
14381/// Completion items are displayed in a `UniformList`.
14382/// Usually, those items are single-line strings, but in LSP responses,
14383/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14384/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14385/// 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,
14386/// breaking the completions menu presentation.
14387///
14388/// 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.
14389fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14390    let mut new_text = String::with_capacity(label.text.len());
14391    let mut offset_map = vec![0; label.text.len() + 1];
14392    let mut last_char_was_space = false;
14393    let mut new_idx = 0;
14394    let chars = label.text.char_indices().fuse();
14395    let mut newlines_removed = false;
14396
14397    for (idx, c) in chars {
14398        offset_map[idx] = new_idx;
14399
14400        match c {
14401            '\n' if last_char_was_space => {
14402                newlines_removed = true;
14403            }
14404            '\t' | ' ' if last_char_was_space => {}
14405            '\n' if !last_char_was_space => {
14406                new_text.push(' ');
14407                new_idx += 1;
14408                last_char_was_space = true;
14409                newlines_removed = true;
14410            }
14411            ' ' | '\t' => {
14412                new_text.push(' ');
14413                new_idx += 1;
14414                last_char_was_space = true;
14415            }
14416            _ => {
14417                new_text.push(c);
14418                new_idx += c.len_utf8();
14419                last_char_was_space = false;
14420            }
14421        }
14422    }
14423    offset_map[label.text.len()] = new_idx;
14424
14425    // Only modify the label if newlines were removed.
14426    if !newlines_removed {
14427        return;
14428    }
14429
14430    let last_index = new_idx;
14431    let mut run_ranges_errors = Vec::new();
14432    label.runs.retain_mut(|(range, _)| {
14433        match offset_map.get(range.start) {
14434            Some(&start) => range.start = start,
14435            None => {
14436                run_ranges_errors.push(range.clone());
14437                return false;
14438            }
14439        }
14440
14441        match offset_map.get(range.end) {
14442            Some(&end) => range.end = end,
14443            None => {
14444                run_ranges_errors.push(range.clone());
14445                range.end = last_index;
14446            }
14447        }
14448        true
14449    });
14450    if !run_ranges_errors.is_empty() {
14451        log::error!(
14452            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14453            label.text
14454        );
14455    }
14456
14457    let mut wrong_filter_range = None;
14458    if label.filter_range == (0..label.text.len()) {
14459        label.filter_range = 0..new_text.len();
14460    } else {
14461        let mut original_filter_range = Some(label.filter_range.clone());
14462        match offset_map.get(label.filter_range.start) {
14463            Some(&start) => label.filter_range.start = start,
14464            None => {
14465                wrong_filter_range = original_filter_range.take();
14466                label.filter_range.start = last_index;
14467            }
14468        }
14469
14470        match offset_map.get(label.filter_range.end) {
14471            Some(&end) => label.filter_range.end = end,
14472            None => {
14473                wrong_filter_range = original_filter_range.take();
14474                label.filter_range.end = last_index;
14475            }
14476        }
14477    }
14478    if let Some(wrong_filter_range) = wrong_filter_range {
14479        log::error!(
14480            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14481            label.text
14482        );
14483    }
14484
14485    label.text = new_text;
14486}
14487
14488#[cfg(test)]
14489mod tests {
14490    use language::HighlightId;
14491
14492    use super::*;
14493
14494    #[test]
14495    fn test_glob_literal_prefix() {
14496        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14497        assert_eq!(
14498            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14499            Path::new("node_modules")
14500        );
14501        assert_eq!(
14502            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14503            Path::new("foo")
14504        );
14505        assert_eq!(
14506            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14507            Path::new("foo/bar/baz.js")
14508        );
14509
14510        #[cfg(target_os = "windows")]
14511        {
14512            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14513            assert_eq!(
14514                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14515                Path::new("node_modules")
14516            );
14517            assert_eq!(
14518                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14519                Path::new("foo")
14520            );
14521            assert_eq!(
14522                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14523                Path::new("foo/bar/baz.js")
14524            );
14525        }
14526    }
14527
14528    #[test]
14529    fn test_multi_len_chars_normalization() {
14530        let mut label = CodeLabel::new(
14531            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14532            0..6,
14533            vec![(0..6, HighlightId(1))],
14534        );
14535        ensure_uniform_list_compatible_label(&mut label);
14536        assert_eq!(
14537            label,
14538            CodeLabel::new(
14539                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14540                0..6,
14541                vec![(0..6, HighlightId(1))],
14542            )
14543        );
14544    }
14545
14546    #[test]
14547    fn test_trailing_newline_in_completion_documentation() {
14548        let doc = lsp::Documentation::String(
14549            "Inappropriate argument value (of correct type).\n".to_string(),
14550        );
14551        let completion_doc: CompletionDocumentation = doc.into();
14552        assert!(
14553            matches!(completion_doc, CompletionDocumentation::SingleLine(s) if s == "Inappropriate argument value (of correct type).")
14554        );
14555
14556        let doc = lsp::Documentation::String("  some value  \n".to_string());
14557        let completion_doc: CompletionDocumentation = doc.into();
14558        assert!(matches!(
14559            completion_doc,
14560            CompletionDocumentation::SingleLine(s) if s == "some value"
14561        ));
14562    }
14563}