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 snippet::Snippet;
  102use std::{
  103    any::TypeId,
  104    borrow::Cow,
  105    cell::RefCell,
  106    cmp::{Ordering, Reverse},
  107    collections::hash_map,
  108    convert::TryInto,
  109    ffi::OsStr,
  110    future::ready,
  111    iter, mem,
  112    ops::{ControlFlow, Range},
  113    path::{self, Path, PathBuf},
  114    pin::pin,
  115    rc::Rc,
  116    sync::{
  117        Arc,
  118        atomic::{self, AtomicUsize},
  119    },
  120    time::{Duration, Instant},
  121    vec,
  122};
  123use sum_tree::Dimensions;
  124use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  125
  126use util::{
  127    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  128    paths::{PathStyle, SanitizedPath},
  129    post_inc,
  130    redact::redact_command,
  131    rel_path::RelPath,
  132};
  133
  134pub use fs::*;
  135pub use language::Location;
  136pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  137#[cfg(any(test, feature = "test-support"))]
  138pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  139pub use worktree::{
  140    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  141    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  142};
  143
  144const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  145pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  146const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  147const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  148
  149#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  150pub enum ProgressToken {
  151    Number(i32),
  152    String(SharedString),
  153}
  154
  155impl std::fmt::Display for ProgressToken {
  156    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  157        match self {
  158            Self::Number(number) => write!(f, "{number}"),
  159            Self::String(string) => write!(f, "{string}"),
  160        }
  161    }
  162}
  163
  164impl ProgressToken {
  165    fn from_lsp(value: lsp::NumberOrString) -> Self {
  166        match value {
  167            lsp::NumberOrString::Number(number) => Self::Number(number),
  168            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  169        }
  170    }
  171
  172    fn to_lsp(&self) -> lsp::NumberOrString {
  173        match self {
  174            Self::Number(number) => lsp::NumberOrString::Number(*number),
  175            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  176        }
  177    }
  178
  179    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  180        Some(match value.value? {
  181            proto::progress_token::Value::Number(number) => Self::Number(number),
  182            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  183        })
  184    }
  185
  186    fn to_proto(&self) -> proto::ProgressToken {
  187        proto::ProgressToken {
  188            value: Some(match self {
  189                Self::Number(number) => proto::progress_token::Value::Number(*number),
  190                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  191            }),
  192        }
  193    }
  194}
  195
  196#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  197pub enum FormatTrigger {
  198    Save,
  199    Manual,
  200}
  201
  202pub enum LspFormatTarget {
  203    Buffers,
  204    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  205}
  206
  207#[derive(Clone, PartialEq, Eq, Hash)]
  208pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  209
  210struct OpenLspBuffer(Entity<Buffer>);
  211
  212impl FormatTrigger {
  213    fn from_proto(value: i32) -> FormatTrigger {
  214        match value {
  215            0 => FormatTrigger::Save,
  216            1 => FormatTrigger::Manual,
  217            _ => FormatTrigger::Save,
  218        }
  219    }
  220}
  221
  222#[derive(Clone)]
  223struct UnifiedLanguageServer {
  224    id: LanguageServerId,
  225    project_roots: HashSet<Arc<RelPath>>,
  226}
  227
  228#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  229struct LanguageServerSeed {
  230    worktree_id: WorktreeId,
  231    name: LanguageServerName,
  232    toolchain: Option<Toolchain>,
  233    settings: Arc<LspSettings>,
  234}
  235
  236#[derive(Debug)]
  237pub struct DocumentDiagnosticsUpdate<'a, D> {
  238    pub diagnostics: D,
  239    pub result_id: Option<SharedString>,
  240    pub registration_id: Option<SharedString>,
  241    pub server_id: LanguageServerId,
  242    pub disk_based_sources: Cow<'a, [String]>,
  243}
  244
  245pub struct DocumentDiagnostics {
  246    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  247    document_abs_path: PathBuf,
  248    version: Option<i32>,
  249}
  250
  251#[derive(Default, Debug)]
  252struct DynamicRegistrations {
  253    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  254    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  255}
  256
  257pub struct LocalLspStore {
  258    weak: WeakEntity<LspStore>,
  259    pub worktree_store: Entity<WorktreeStore>,
  260    toolchain_store: Entity<LocalToolchainStore>,
  261    http_client: Arc<dyn HttpClient>,
  262    environment: Entity<ProjectEnvironment>,
  263    fs: Arc<dyn Fs>,
  264    languages: Arc<LanguageRegistry>,
  265    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  266    yarn: Entity<YarnPathStore>,
  267    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  268    buffers_being_formatted: HashSet<BufferId>,
  269    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  270    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  271    watched_manifest_filenames: HashSet<ManifestName>,
  272    language_server_paths_watched_for_rename:
  273        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  274    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  275    supplementary_language_servers:
  276        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  277    prettier_store: Entity<PrettierStore>,
  278    next_diagnostic_group_id: usize,
  279    diagnostics: HashMap<
  280        WorktreeId,
  281        HashMap<
  282            Arc<RelPath>,
  283            Vec<(
  284                LanguageServerId,
  285                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  286            )>,
  287        >,
  288    >,
  289    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  290    _subscription: gpui::Subscription,
  291    lsp_tree: LanguageServerTree,
  292    registered_buffers: HashMap<BufferId, usize>,
  293    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  294    buffer_pull_diagnostics_result_ids: HashMap<
  295        LanguageServerId,
  296        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  297    >,
  298    workspace_pull_diagnostics_result_ids: HashMap<
  299        LanguageServerId,
  300        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  301    >,
  302    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  303}
  304
  305impl LocalLspStore {
  306    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  307    pub fn running_language_server_for_id(
  308        &self,
  309        id: LanguageServerId,
  310    ) -> Option<&Arc<LanguageServer>> {
  311        let language_server_state = self.language_servers.get(&id)?;
  312
  313        match language_server_state {
  314            LanguageServerState::Running { server, .. } => Some(server),
  315            LanguageServerState::Starting { .. } => None,
  316        }
  317    }
  318
  319    fn get_or_insert_language_server(
  320        &mut self,
  321        worktree_handle: &Entity<Worktree>,
  322        delegate: Arc<LocalLspAdapterDelegate>,
  323        disposition: &Arc<LaunchDisposition>,
  324        language_name: &LanguageName,
  325        cx: &mut App,
  326    ) -> LanguageServerId {
  327        let key = LanguageServerSeed {
  328            worktree_id: worktree_handle.read(cx).id(),
  329            name: disposition.server_name.clone(),
  330            settings: disposition.settings.clone(),
  331            toolchain: disposition.toolchain.clone(),
  332        };
  333        if let Some(state) = self.language_server_ids.get_mut(&key) {
  334            state.project_roots.insert(disposition.path.path.clone());
  335            state.id
  336        } else {
  337            let adapter = self
  338                .languages
  339                .lsp_adapters(language_name)
  340                .into_iter()
  341                .find(|adapter| adapter.name() == disposition.server_name)
  342                .expect("To find LSP adapter");
  343            let new_language_server_id = self.start_language_server(
  344                worktree_handle,
  345                delegate,
  346                adapter,
  347                disposition.settings.clone(),
  348                key.clone(),
  349                cx,
  350            );
  351            if let Some(state) = self.language_server_ids.get_mut(&key) {
  352                state.project_roots.insert(disposition.path.path.clone());
  353            } else {
  354                debug_assert!(
  355                    false,
  356                    "Expected `start_language_server` to ensure that `key` exists in a map"
  357                );
  358            }
  359            new_language_server_id
  360        }
  361    }
  362
  363    fn start_language_server(
  364        &mut self,
  365        worktree_handle: &Entity<Worktree>,
  366        delegate: Arc<LocalLspAdapterDelegate>,
  367        adapter: Arc<CachedLspAdapter>,
  368        settings: Arc<LspSettings>,
  369        key: LanguageServerSeed,
  370        cx: &mut App,
  371    ) -> LanguageServerId {
  372        let worktree = worktree_handle.read(cx);
  373
  374        let worktree_id = worktree.id();
  375        let worktree_abs_path = worktree.abs_path();
  376        let toolchain = key.toolchain.clone();
  377        let override_options = settings.initialization_options.clone();
  378
  379        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  380
  381        let server_id = self.languages.next_language_server_id();
  382        log::trace!(
  383            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  384            adapter.name.0
  385        );
  386
  387        let wait_until_worktree_trust =
  388            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  389                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  390                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  391                });
  392                if can_trust {
  393                    self.restricted_worktrees_tasks.remove(&worktree_id);
  394                    None
  395                } else {
  396                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  397                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  398                        hash_map::Entry::Vacant(v) => {
  399                            let (mut tx, rx) = watch::channel::<bool>();
  400                            let lsp_store = self.weak.clone();
  401                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  402                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  403                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  404                                        tx.blocking_send(true).ok();
  405                                        lsp_store
  406                                            .update(cx, |lsp_store, _| {
  407                                                if let Some(local_lsp_store) =
  408                                                    lsp_store.as_local_mut()
  409                                                {
  410                                                    local_lsp_store
  411                                                        .restricted_worktrees_tasks
  412                                                        .remove(&worktree_id);
  413                                                }
  414                                            })
  415                                            .ok();
  416                                    }
  417                                }
  418                            });
  419                            v.insert((subscription, rx.clone()));
  420                            Some(rx)
  421                        }
  422                    }
  423                }
  424            });
  425        let update_binary_status = wait_until_worktree_trust.is_none();
  426
  427        let binary = self.get_language_server_binary(
  428            worktree_abs_path.clone(),
  429            adapter.clone(),
  430            settings,
  431            toolchain.clone(),
  432            delegate.clone(),
  433            true,
  434            wait_until_worktree_trust,
  435            cx,
  436        );
  437        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  438
  439        let pending_server = cx.spawn({
  440            let adapter = adapter.clone();
  441            let server_name = adapter.name.clone();
  442            let stderr_capture = stderr_capture.clone();
  443            #[cfg(any(test, feature = "test-support"))]
  444            let lsp_store = self.weak.clone();
  445            let pending_workspace_folders = pending_workspace_folders.clone();
  446            async move |cx| {
  447                let binary = binary.await?;
  448                #[cfg(any(test, feature = "test-support"))]
  449                if let Some(server) = lsp_store
  450                    .update(&mut cx.clone(), |this, cx| {
  451                        this.languages.create_fake_language_server(
  452                            server_id,
  453                            &server_name,
  454                            binary.clone(),
  455                            &mut cx.to_async(),
  456                        )
  457                    })
  458                    .ok()
  459                    .flatten()
  460                {
  461                    return Ok(server);
  462                }
  463
  464                let code_action_kinds = adapter.code_action_kinds();
  465                lsp::LanguageServer::new(
  466                    stderr_capture,
  467                    server_id,
  468                    server_name,
  469                    binary,
  470                    &worktree_abs_path,
  471                    code_action_kinds,
  472                    Some(pending_workspace_folders),
  473                    cx,
  474                )
  475            }
  476        });
  477
  478        let startup = {
  479            let server_name = adapter.name.0.clone();
  480            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  481            let key = key.clone();
  482            let adapter = adapter.clone();
  483            let lsp_store = self.weak.clone();
  484            let pending_workspace_folders = pending_workspace_folders.clone();
  485
  486            let pull_diagnostics = ProjectSettings::get_global(cx)
  487                .diagnostics
  488                .lsp_pull_diagnostics
  489                .enabled;
  490            cx.spawn(async move |cx| {
  491                let result = async {
  492                    let language_server = pending_server.await?;
  493
  494                    let workspace_config = Self::workspace_configuration_for_adapter(
  495                        adapter.adapter.clone(),
  496                        &delegate,
  497                        toolchain,
  498                        None,
  499                        cx,
  500                    )
  501                    .await?;
  502
  503                    let mut initialization_options = Self::initialization_options_for_adapter(
  504                        adapter.adapter.clone(),
  505                        &delegate,
  506                    )
  507                    .await?;
  508
  509                    match (&mut initialization_options, override_options) {
  510                        (Some(initialization_options), Some(override_options)) => {
  511                            merge_json_value_into(override_options, initialization_options);
  512                        }
  513                        (None, override_options) => initialization_options = override_options,
  514                        _ => {}
  515                    }
  516
  517                    let initialization_params = cx.update(|cx| {
  518                        let mut params =
  519                            language_server.default_initialize_params(pull_diagnostics, cx);
  520                        params.initialization_options = initialization_options;
  521                        adapter.adapter.prepare_initialize_params(params, cx)
  522                    })??;
  523
  524                    Self::setup_lsp_messages(
  525                        lsp_store.clone(),
  526                        &language_server,
  527                        delegate.clone(),
  528                        adapter.clone(),
  529                    );
  530
  531                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  532                        settings: workspace_config,
  533                    };
  534                    let language_server = cx
  535                        .update(|cx| {
  536                            language_server.initialize(
  537                                initialization_params,
  538                                Arc::new(did_change_configuration_params.clone()),
  539                                cx,
  540                            )
  541                        })?
  542                        .await
  543                        .inspect_err(|_| {
  544                            if let Some(lsp_store) = lsp_store.upgrade() {
  545                                lsp_store
  546                                    .update(cx, |lsp_store, cx| {
  547                                        lsp_store.cleanup_lsp_data(server_id);
  548                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  549                                    })
  550                                    .ok();
  551                            }
  552                        })?;
  553
  554                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  555                        did_change_configuration_params,
  556                    )?;
  557
  558                    anyhow::Ok(language_server)
  559                }
  560                .await;
  561
  562                match result {
  563                    Ok(server) => {
  564                        lsp_store
  565                            .update(cx, |lsp_store, cx| {
  566                                lsp_store.insert_newly_running_language_server(
  567                                    adapter,
  568                                    server.clone(),
  569                                    server_id,
  570                                    key,
  571                                    pending_workspace_folders,
  572                                    cx,
  573                                );
  574                            })
  575                            .ok();
  576                        stderr_capture.lock().take();
  577                        Some(server)
  578                    }
  579
  580                    Err(err) => {
  581                        let log = stderr_capture.lock().take().unwrap_or_default();
  582                        delegate.update_status(
  583                            adapter.name(),
  584                            BinaryStatus::Failed {
  585                                error: if log.is_empty() {
  586                                    format!("{err:#}")
  587                                } else {
  588                                    format!("{err:#}\n-- stderr --\n{log}")
  589                                },
  590                            },
  591                        );
  592                        log::error!(
  593                            "Failed to start language server {server_name:?}: {}",
  594                            redact_command(&format!("{err:?}"))
  595                        );
  596                        if !log.is_empty() {
  597                            log::error!("server stderr: {}", redact_command(&log));
  598                        }
  599                        None
  600                    }
  601                }
  602            })
  603        };
  604        let state = LanguageServerState::Starting {
  605            startup,
  606            pending_workspace_folders,
  607        };
  608
  609        if update_binary_status {
  610            self.languages
  611                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  612        }
  613
  614        self.language_servers.insert(server_id, state);
  615        self.language_server_ids
  616            .entry(key)
  617            .or_insert(UnifiedLanguageServer {
  618                id: server_id,
  619                project_roots: Default::default(),
  620            });
  621        server_id
  622    }
  623
  624    fn get_language_server_binary(
  625        &self,
  626        worktree_abs_path: Arc<Path>,
  627        adapter: Arc<CachedLspAdapter>,
  628        settings: Arc<LspSettings>,
  629        toolchain: Option<Toolchain>,
  630        delegate: Arc<dyn LspAdapterDelegate>,
  631        allow_binary_download: bool,
  632        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  633        cx: &mut App,
  634    ) -> Task<Result<LanguageServerBinary>> {
  635        if let Some(settings) = &settings.binary
  636            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  637        {
  638            let settings = settings.clone();
  639            let languages = self.languages.clone();
  640            return cx.background_spawn(async move {
  641                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  642                    let already_trusted =  *wait_until_worktree_trust.borrow();
  643                    if !already_trusted {
  644                        log::info!(
  645                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  646                            adapter.name(),
  647                        );
  648                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  649                            if worktree_trusted {
  650                                break;
  651                            }
  652                        }
  653                        log::info!(
  654                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  655                            adapter.name(),
  656                        );
  657                    }
  658                    languages
  659                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  660                }
  661                let mut env = delegate.shell_env().await;
  662                env.extend(settings.env.unwrap_or_default());
  663
  664                Ok(LanguageServerBinary {
  665                    path: delegate.resolve_executable_path(path),
  666                    env: Some(env),
  667                    arguments: settings
  668                        .arguments
  669                        .unwrap_or_default()
  670                        .iter()
  671                        .map(Into::into)
  672                        .collect(),
  673                })
  674            });
  675        }
  676        let lsp_binary_options = LanguageServerBinaryOptions {
  677            allow_path_lookup: !settings
  678                .binary
  679                .as_ref()
  680                .and_then(|b| b.ignore_system_version)
  681                .unwrap_or_default(),
  682            allow_binary_download,
  683            pre_release: settings
  684                .fetch
  685                .as_ref()
  686                .and_then(|f| f.pre_release)
  687                .unwrap_or(false),
  688        };
  689
  690        cx.spawn(async move |cx| {
  691            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  692                let already_trusted =  *wait_until_worktree_trust.borrow();
  693                if !already_trusted {
  694                    log::info!(
  695                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  696                        adapter.name(),
  697                    );
  698                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  699                        if worktree_trusted {
  700                            break;
  701                        }
  702                    }
  703                    log::info!(
  704                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  705                            adapter.name(),
  706                    );
  707                }
  708            }
  709
  710            let (existing_binary, maybe_download_binary) = adapter
  711                .clone()
  712                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  713                .await
  714                .await;
  715
  716            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  717
  718            let mut binary = match (existing_binary, maybe_download_binary) {
  719                (binary, None) => binary?,
  720                (Err(_), Some(downloader)) => downloader.await?,
  721                (Ok(existing_binary), Some(downloader)) => {
  722                    let mut download_timeout = cx
  723                        .background_executor()
  724                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  725                        .fuse();
  726                    let mut downloader = downloader.fuse();
  727                    futures::select! {
  728                        _ = download_timeout => {
  729                            // Return existing binary and kick the existing work to the background.
  730                            cx.spawn(async move |_| downloader.await).detach();
  731                            Ok(existing_binary)
  732                        },
  733                        downloaded_or_existing_binary = downloader => {
  734                            // If download fails, this results in the existing binary.
  735                            downloaded_or_existing_binary
  736                        }
  737                    }?
  738                }
  739            };
  740            let mut shell_env = delegate.shell_env().await;
  741
  742            shell_env.extend(binary.env.unwrap_or_default());
  743
  744            if let Some(settings) = settings.binary.as_ref() {
  745                if let Some(arguments) = &settings.arguments {
  746                    binary.arguments = arguments.iter().map(Into::into).collect();
  747                }
  748                if let Some(env) = &settings.env {
  749                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  750                }
  751            }
  752
  753            binary.env = Some(shell_env);
  754            Ok(binary)
  755        })
  756    }
  757
  758    fn setup_lsp_messages(
  759        lsp_store: WeakEntity<LspStore>,
  760        language_server: &LanguageServer,
  761        delegate: Arc<dyn LspAdapterDelegate>,
  762        adapter: Arc<CachedLspAdapter>,
  763    ) {
  764        let name = language_server.name();
  765        let server_id = language_server.server_id();
  766        language_server
  767            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  768                let adapter = adapter.clone();
  769                let this = lsp_store.clone();
  770                move |mut params, cx| {
  771                    let adapter = adapter.clone();
  772                    if let Some(this) = this.upgrade() {
  773                        this.update(cx, |this, cx| {
  774                            {
  775                                let buffer = params
  776                                    .uri
  777                                    .to_file_path()
  778                                    .map(|file_path| this.get_buffer(&file_path, cx))
  779                                    .ok()
  780                                    .flatten();
  781                                adapter.process_diagnostics(&mut params, server_id, buffer);
  782                            }
  783
  784                            this.merge_lsp_diagnostics(
  785                                DiagnosticSourceKind::Pushed,
  786                                vec![DocumentDiagnosticsUpdate {
  787                                    server_id,
  788                                    diagnostics: params,
  789                                    result_id: None,
  790                                    disk_based_sources: Cow::Borrowed(
  791                                        &adapter.disk_based_diagnostic_sources,
  792                                    ),
  793                                    registration_id: None,
  794                                }],
  795                                |_, diagnostic, cx| match diagnostic.source_kind {
  796                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  797                                        adapter.retain_old_diagnostic(diagnostic, cx)
  798                                    }
  799                                    DiagnosticSourceKind::Pulled => true,
  800                                },
  801                                cx,
  802                            )
  803                            .log_err();
  804                        })
  805                        .ok();
  806                    }
  807                }
  808            })
  809            .detach();
  810        language_server
  811            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  812                let adapter = adapter.adapter.clone();
  813                let delegate = delegate.clone();
  814                let this = lsp_store.clone();
  815                move |params, cx| {
  816                    let adapter = adapter.clone();
  817                    let delegate = delegate.clone();
  818                    let this = this.clone();
  819                    let mut cx = cx.clone();
  820                    async move {
  821                        let toolchain_for_id = this
  822                            .update(&mut cx, |this, _| {
  823                                this.as_local()?.language_server_ids.iter().find_map(
  824                                    |(seed, value)| {
  825                                        (value.id == server_id).then(|| seed.toolchain.clone())
  826                                    },
  827                                )
  828                            })?
  829                            .context("Expected the LSP store to be in a local mode")?;
  830
  831                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  832                        for item in &params.items {
  833                            let scope_uri = item.scope_uri.clone();
  834                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  835                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  836                            else {
  837                                // We've already queried workspace configuration of this URI.
  838                                continue;
  839                            };
  840                            let workspace_config = Self::workspace_configuration_for_adapter(
  841                                adapter.clone(),
  842                                &delegate,
  843                                toolchain_for_id.clone(),
  844                                scope_uri,
  845                                &mut cx,
  846                            )
  847                            .await?;
  848                            new_scope_uri.insert(workspace_config);
  849                        }
  850
  851                        Ok(params
  852                            .items
  853                            .into_iter()
  854                            .filter_map(|item| {
  855                                let workspace_config =
  856                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  857                                if let Some(section) = &item.section {
  858                                    Some(
  859                                        workspace_config
  860                                            .get(section)
  861                                            .cloned()
  862                                            .unwrap_or(serde_json::Value::Null),
  863                                    )
  864                                } else {
  865                                    Some(workspace_config.clone())
  866                                }
  867                            })
  868                            .collect())
  869                    }
  870                }
  871            })
  872            .detach();
  873
  874        language_server
  875            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  876                let this = lsp_store.clone();
  877                move |_, cx| {
  878                    let this = this.clone();
  879                    let cx = cx.clone();
  880                    async move {
  881                        let Some(server) =
  882                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  883                        else {
  884                            return Ok(None);
  885                        };
  886                        let root = server.workspace_folders();
  887                        Ok(Some(
  888                            root.into_iter()
  889                                .map(|uri| WorkspaceFolder {
  890                                    uri,
  891                                    name: Default::default(),
  892                                })
  893                                .collect(),
  894                        ))
  895                    }
  896                }
  897            })
  898            .detach();
  899        // Even though we don't have handling for these requests, respond to them to
  900        // avoid stalling any language server like `gopls` which waits for a response
  901        // to these requests when initializing.
  902        language_server
  903            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  904                let this = lsp_store.clone();
  905                move |params, cx| {
  906                    let this = this.clone();
  907                    let mut cx = cx.clone();
  908                    async move {
  909                        this.update(&mut cx, |this, _| {
  910                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  911                            {
  912                                status
  913                                    .progress_tokens
  914                                    .insert(ProgressToken::from_lsp(params.token));
  915                            }
  916                        })?;
  917
  918                        Ok(())
  919                    }
  920                }
  921            })
  922            .detach();
  923
  924        language_server
  925            .on_request::<lsp::request::RegisterCapability, _, _>({
  926                let lsp_store = lsp_store.clone();
  927                move |params, cx| {
  928                    let lsp_store = lsp_store.clone();
  929                    let mut cx = cx.clone();
  930                    async move {
  931                        lsp_store
  932                            .update(&mut cx, |lsp_store, cx| {
  933                                if lsp_store.as_local().is_some() {
  934                                    match lsp_store
  935                                        .register_server_capabilities(server_id, params, cx)
  936                                    {
  937                                        Ok(()) => {}
  938                                        Err(e) => {
  939                                            log::error!(
  940                                                "Failed to register server capabilities: {e:#}"
  941                                            );
  942                                        }
  943                                    };
  944                                }
  945                            })
  946                            .ok();
  947                        Ok(())
  948                    }
  949                }
  950            })
  951            .detach();
  952
  953        language_server
  954            .on_request::<lsp::request::UnregisterCapability, _, _>({
  955                let lsp_store = lsp_store.clone();
  956                move |params, cx| {
  957                    let lsp_store = lsp_store.clone();
  958                    let mut cx = cx.clone();
  959                    async move {
  960                        lsp_store
  961                            .update(&mut cx, |lsp_store, cx| {
  962                                if lsp_store.as_local().is_some() {
  963                                    match lsp_store
  964                                        .unregister_server_capabilities(server_id, params, cx)
  965                                    {
  966                                        Ok(()) => {}
  967                                        Err(e) => {
  968                                            log::error!(
  969                                                "Failed to unregister server capabilities: {e:#}"
  970                                            );
  971                                        }
  972                                    }
  973                                }
  974                            })
  975                            .ok();
  976                        Ok(())
  977                    }
  978                }
  979            })
  980            .detach();
  981
  982        language_server
  983            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  984                let this = lsp_store.clone();
  985                move |params, cx| {
  986                    let mut cx = cx.clone();
  987                    let this = this.clone();
  988                    async move {
  989                        LocalLspStore::on_lsp_workspace_edit(
  990                            this.clone(),
  991                            params,
  992                            server_id,
  993                            &mut cx,
  994                        )
  995                        .await
  996                    }
  997                }
  998            })
  999            .detach();
 1000
 1001        language_server
 1002            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1003                let lsp_store = lsp_store.clone();
 1004                let request_id = Arc::new(AtomicUsize::new(0));
 1005                move |(), cx| {
 1006                    let lsp_store = lsp_store.clone();
 1007                    let request_id = request_id.clone();
 1008                    let mut cx = cx.clone();
 1009                    async move {
 1010                        lsp_store
 1011                            .update(&mut cx, |lsp_store, cx| {
 1012                                let request_id =
 1013                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1014                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1015                                    server_id,
 1016                                    request_id,
 1017                                });
 1018                                lsp_store
 1019                                    .downstream_client
 1020                                    .as_ref()
 1021                                    .map(|(client, project_id)| {
 1022                                        client.send(proto::RefreshInlayHints {
 1023                                            project_id: *project_id,
 1024                                            server_id: server_id.to_proto(),
 1025                                            request_id: request_id.map(|id| id as u64),
 1026                                        })
 1027                                    })
 1028                            })?
 1029                            .transpose()?;
 1030                        Ok(())
 1031                    }
 1032                }
 1033            })
 1034            .detach();
 1035
 1036        language_server
 1037            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1038                let this = lsp_store.clone();
 1039                move |(), cx| {
 1040                    let this = this.clone();
 1041                    let mut cx = cx.clone();
 1042                    async move {
 1043                        this.update(&mut cx, |this, cx| {
 1044                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1045                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1046                                client.send(proto::RefreshCodeLens {
 1047                                    project_id: *project_id,
 1048                                })
 1049                            })
 1050                        })?
 1051                        .transpose()?;
 1052                        Ok(())
 1053                    }
 1054                }
 1055            })
 1056            .detach();
 1057
 1058        language_server
 1059            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1060                let this = lsp_store.clone();
 1061                move |(), cx| {
 1062                    let this = this.clone();
 1063                    let mut cx = cx.clone();
 1064                    async move {
 1065                        this.update(&mut cx, |lsp_store, cx| {
 1066                            lsp_store.pull_workspace_diagnostics(server_id);
 1067                            lsp_store.pull_document_diagnostics_for_server(server_id, cx);
 1068                            lsp_store
 1069                                .downstream_client
 1070                                .as_ref()
 1071                                .map(|(client, project_id)| {
 1072                                    client.send(proto::PullWorkspaceDiagnostics {
 1073                                        project_id: *project_id,
 1074                                        server_id: server_id.to_proto(),
 1075                                    })
 1076                                })
 1077                        })?
 1078                        .transpose()?;
 1079                        Ok(())
 1080                    }
 1081                }
 1082            })
 1083            .detach();
 1084
 1085        language_server
 1086            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1087                let this = lsp_store.clone();
 1088                let name = name.to_string();
 1089                let adapter = adapter.clone();
 1090                move |params, cx| {
 1091                    let this = this.clone();
 1092                    let name = name.to_string();
 1093                    let adapter = adapter.clone();
 1094                    let mut cx = cx.clone();
 1095                    async move {
 1096                        let actions = params.actions.unwrap_or_default();
 1097                        let message = params.message.clone();
 1098                        let (tx, rx) = smol::channel::bounded(1);
 1099                        let request = LanguageServerPromptRequest {
 1100                            level: match params.typ {
 1101                                lsp::MessageType::ERROR => PromptLevel::Critical,
 1102                                lsp::MessageType::WARNING => PromptLevel::Warning,
 1103                                _ => PromptLevel::Info,
 1104                            },
 1105                            message: params.message,
 1106                            actions,
 1107                            response_channel: tx,
 1108                            lsp_name: name.clone(),
 1109                        };
 1110
 1111                        let did_update = this
 1112                            .update(&mut cx, |_, cx| {
 1113                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1114                            })
 1115                            .is_ok();
 1116                        if did_update {
 1117                            let response = rx.recv().await.ok();
 1118                            if let Some(ref selected_action) = response {
 1119                                let context = language::PromptResponseContext {
 1120                                    message,
 1121                                    selected_action: selected_action.clone(),
 1122                                };
 1123                                adapter.process_prompt_response(&context, &mut cx)
 1124                            }
 1125
 1126                            Ok(response)
 1127                        } else {
 1128                            Ok(None)
 1129                        }
 1130                    }
 1131                }
 1132            })
 1133            .detach();
 1134        language_server
 1135            .on_notification::<lsp::notification::ShowMessage, _>({
 1136                let this = lsp_store.clone();
 1137                let name = name.to_string();
 1138                move |params, cx| {
 1139                    let this = this.clone();
 1140                    let name = name.to_string();
 1141                    let mut cx = cx.clone();
 1142
 1143                    let (tx, _) = smol::channel::bounded(1);
 1144                    let request = LanguageServerPromptRequest {
 1145                        level: match params.typ {
 1146                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1147                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1148                            _ => PromptLevel::Info,
 1149                        },
 1150                        message: params.message,
 1151                        actions: vec![],
 1152                        response_channel: tx,
 1153                        lsp_name: name,
 1154                    };
 1155
 1156                    let _ = this.update(&mut cx, |_, cx| {
 1157                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1158                    });
 1159                }
 1160            })
 1161            .detach();
 1162
 1163        let disk_based_diagnostics_progress_token =
 1164            adapter.disk_based_diagnostics_progress_token.clone();
 1165
 1166        language_server
 1167            .on_notification::<lsp::notification::Progress, _>({
 1168                let this = lsp_store.clone();
 1169                move |params, cx| {
 1170                    if let Some(this) = this.upgrade() {
 1171                        this.update(cx, |this, cx| {
 1172                            this.on_lsp_progress(
 1173                                params,
 1174                                server_id,
 1175                                disk_based_diagnostics_progress_token.clone(),
 1176                                cx,
 1177                            );
 1178                        })
 1179                        .ok();
 1180                    }
 1181                }
 1182            })
 1183            .detach();
 1184
 1185        language_server
 1186            .on_notification::<lsp::notification::LogMessage, _>({
 1187                let this = lsp_store.clone();
 1188                move |params, cx| {
 1189                    if let Some(this) = this.upgrade() {
 1190                        this.update(cx, |_, cx| {
 1191                            cx.emit(LspStoreEvent::LanguageServerLog(
 1192                                server_id,
 1193                                LanguageServerLogType::Log(params.typ),
 1194                                params.message,
 1195                            ));
 1196                        })
 1197                        .ok();
 1198                    }
 1199                }
 1200            })
 1201            .detach();
 1202
 1203        language_server
 1204            .on_notification::<lsp::notification::LogTrace, _>({
 1205                let this = lsp_store.clone();
 1206                move |params, cx| {
 1207                    let mut cx = cx.clone();
 1208                    if let Some(this) = this.upgrade() {
 1209                        this.update(&mut cx, |_, cx| {
 1210                            cx.emit(LspStoreEvent::LanguageServerLog(
 1211                                server_id,
 1212                                LanguageServerLogType::Trace {
 1213                                    verbose_info: params.verbose,
 1214                                },
 1215                                params.message,
 1216                            ));
 1217                        })
 1218                        .ok();
 1219                    }
 1220                }
 1221            })
 1222            .detach();
 1223
 1224        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1225        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1226        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1227        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1228    }
 1229
 1230    fn shutdown_language_servers_on_quit(
 1231        &mut self,
 1232        _: &mut Context<LspStore>,
 1233    ) -> impl Future<Output = ()> + use<> {
 1234        let shutdown_futures = self
 1235            .language_servers
 1236            .drain()
 1237            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1238            .collect::<Vec<_>>();
 1239
 1240        async move {
 1241            join_all(shutdown_futures).await;
 1242        }
 1243    }
 1244
 1245    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1246        match server_state {
 1247            LanguageServerState::Running { server, .. } => {
 1248                if let Some(shutdown) = server.shutdown() {
 1249                    shutdown.await;
 1250                }
 1251            }
 1252            LanguageServerState::Starting { startup, .. } => {
 1253                if let Some(server) = startup.await
 1254                    && let Some(shutdown) = server.shutdown()
 1255                {
 1256                    shutdown.await;
 1257                }
 1258            }
 1259        }
 1260        Ok(())
 1261    }
 1262
 1263    fn language_servers_for_worktree(
 1264        &self,
 1265        worktree_id: WorktreeId,
 1266    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1267        self.language_server_ids
 1268            .iter()
 1269            .filter_map(move |(seed, state)| {
 1270                if seed.worktree_id != worktree_id {
 1271                    return None;
 1272                }
 1273
 1274                if let Some(LanguageServerState::Running { server, .. }) =
 1275                    self.language_servers.get(&state.id)
 1276                {
 1277                    Some(server)
 1278                } else {
 1279                    None
 1280                }
 1281            })
 1282    }
 1283
 1284    fn language_server_ids_for_project_path(
 1285        &self,
 1286        project_path: ProjectPath,
 1287        language: &Language,
 1288        cx: &mut App,
 1289    ) -> Vec<LanguageServerId> {
 1290        let Some(worktree) = self
 1291            .worktree_store
 1292            .read(cx)
 1293            .worktree_for_id(project_path.worktree_id, cx)
 1294        else {
 1295            return Vec::new();
 1296        };
 1297        let delegate: Arc<dyn ManifestDelegate> =
 1298            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1299
 1300        self.lsp_tree
 1301            .get(
 1302                project_path,
 1303                language.name(),
 1304                language.manifest(),
 1305                &delegate,
 1306                cx,
 1307            )
 1308            .collect::<Vec<_>>()
 1309    }
 1310
 1311    fn language_server_ids_for_buffer(
 1312        &self,
 1313        buffer: &Buffer,
 1314        cx: &mut App,
 1315    ) -> Vec<LanguageServerId> {
 1316        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1317            let worktree_id = file.worktree_id(cx);
 1318
 1319            let path: Arc<RelPath> = file
 1320                .path()
 1321                .parent()
 1322                .map(Arc::from)
 1323                .unwrap_or_else(|| file.path().clone());
 1324            let worktree_path = ProjectPath { worktree_id, path };
 1325            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1326        } else {
 1327            Vec::new()
 1328        }
 1329    }
 1330
 1331    fn language_servers_for_buffer<'a>(
 1332        &'a self,
 1333        buffer: &'a Buffer,
 1334        cx: &'a mut App,
 1335    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1336        self.language_server_ids_for_buffer(buffer, cx)
 1337            .into_iter()
 1338            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1339                LanguageServerState::Running {
 1340                    adapter, server, ..
 1341                } => Some((adapter, server)),
 1342                _ => None,
 1343            })
 1344    }
 1345
 1346    async fn execute_code_action_kind_locally(
 1347        lsp_store: WeakEntity<LspStore>,
 1348        mut buffers: Vec<Entity<Buffer>>,
 1349        kind: CodeActionKind,
 1350        push_to_history: bool,
 1351        cx: &mut AsyncApp,
 1352    ) -> anyhow::Result<ProjectTransaction> {
 1353        // Do not allow multiple concurrent code actions requests for the
 1354        // same buffer.
 1355        lsp_store.update(cx, |this, cx| {
 1356            let this = this.as_local_mut().unwrap();
 1357            buffers.retain(|buffer| {
 1358                this.buffers_being_formatted
 1359                    .insert(buffer.read(cx).remote_id())
 1360            });
 1361        })?;
 1362        let _cleanup = defer({
 1363            let this = lsp_store.clone();
 1364            let mut cx = cx.clone();
 1365            let buffers = &buffers;
 1366            move || {
 1367                this.update(&mut cx, |this, cx| {
 1368                    let this = this.as_local_mut().unwrap();
 1369                    for buffer in buffers {
 1370                        this.buffers_being_formatted
 1371                            .remove(&buffer.read(cx).remote_id());
 1372                    }
 1373                })
 1374                .ok();
 1375            }
 1376        });
 1377        let mut project_transaction = ProjectTransaction::default();
 1378
 1379        for buffer in &buffers {
 1380            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1381                buffer.update(cx, |buffer, cx| {
 1382                    lsp_store
 1383                        .as_local()
 1384                        .unwrap()
 1385                        .language_servers_for_buffer(buffer, cx)
 1386                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1387                        .collect::<Vec<_>>()
 1388                })
 1389            })?;
 1390            for (_, language_server) in adapters_and_servers.iter() {
 1391                let actions = Self::get_server_code_actions_from_action_kinds(
 1392                    &lsp_store,
 1393                    language_server.server_id(),
 1394                    vec![kind.clone()],
 1395                    buffer,
 1396                    cx,
 1397                )
 1398                .await?;
 1399                Self::execute_code_actions_on_server(
 1400                    &lsp_store,
 1401                    language_server,
 1402                    actions,
 1403                    push_to_history,
 1404                    &mut project_transaction,
 1405                    cx,
 1406                )
 1407                .await?;
 1408            }
 1409        }
 1410        Ok(project_transaction)
 1411    }
 1412
 1413    async fn format_locally(
 1414        lsp_store: WeakEntity<LspStore>,
 1415        mut buffers: Vec<FormattableBuffer>,
 1416        push_to_history: bool,
 1417        trigger: FormatTrigger,
 1418        logger: zlog::Logger,
 1419        cx: &mut AsyncApp,
 1420    ) -> anyhow::Result<ProjectTransaction> {
 1421        // Do not allow multiple concurrent formatting requests for the
 1422        // same buffer.
 1423        lsp_store.update(cx, |this, cx| {
 1424            let this = this.as_local_mut().unwrap();
 1425            buffers.retain(|buffer| {
 1426                this.buffers_being_formatted
 1427                    .insert(buffer.handle.read(cx).remote_id())
 1428            });
 1429        })?;
 1430
 1431        let _cleanup = defer({
 1432            let this = lsp_store.clone();
 1433            let mut cx = cx.clone();
 1434            let buffers = &buffers;
 1435            move || {
 1436                this.update(&mut cx, |this, cx| {
 1437                    let this = this.as_local_mut().unwrap();
 1438                    for buffer in buffers {
 1439                        this.buffers_being_formatted
 1440                            .remove(&buffer.handle.read(cx).remote_id());
 1441                    }
 1442                })
 1443                .ok();
 1444            }
 1445        });
 1446
 1447        let mut project_transaction = ProjectTransaction::default();
 1448
 1449        for buffer in &buffers {
 1450            zlog::debug!(
 1451                logger =>
 1452                "formatting buffer '{:?}'",
 1453                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1454            );
 1455            // Create an empty transaction to hold all of the formatting edits.
 1456            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1457                // ensure no transactions created while formatting are
 1458                // grouped with the previous transaction in the history
 1459                // based on the transaction group interval
 1460                buffer.finalize_last_transaction();
 1461                buffer
 1462                    .start_transaction()
 1463                    .context("transaction already open")?;
 1464                buffer.end_transaction(cx);
 1465                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1466                buffer.finalize_last_transaction();
 1467                anyhow::Ok(transaction_id)
 1468            })??;
 1469
 1470            let result = Self::format_buffer_locally(
 1471                lsp_store.clone(),
 1472                buffer,
 1473                formatting_transaction_id,
 1474                trigger,
 1475                logger,
 1476                cx,
 1477            )
 1478            .await;
 1479
 1480            buffer.handle.update(cx, |buffer, cx| {
 1481                let Some(formatting_transaction) =
 1482                    buffer.get_transaction(formatting_transaction_id).cloned()
 1483                else {
 1484                    zlog::warn!(logger => "no formatting transaction");
 1485                    return;
 1486                };
 1487                if formatting_transaction.edit_ids.is_empty() {
 1488                    zlog::debug!(logger => "no changes made while formatting");
 1489                    buffer.forget_transaction(formatting_transaction_id);
 1490                    return;
 1491                }
 1492                if !push_to_history {
 1493                    zlog::trace!(logger => "forgetting format transaction");
 1494                    buffer.forget_transaction(formatting_transaction.id);
 1495                }
 1496                project_transaction
 1497                    .0
 1498                    .insert(cx.entity(), formatting_transaction);
 1499            })?;
 1500
 1501            result?;
 1502        }
 1503
 1504        Ok(project_transaction)
 1505    }
 1506
 1507    async fn format_buffer_locally(
 1508        lsp_store: WeakEntity<LspStore>,
 1509        buffer: &FormattableBuffer,
 1510        formatting_transaction_id: clock::Lamport,
 1511        trigger: FormatTrigger,
 1512        logger: zlog::Logger,
 1513        cx: &mut AsyncApp,
 1514    ) -> Result<()> {
 1515        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1516            buffer.handle.update(cx, |buffer, cx| {
 1517                let adapters_and_servers = lsp_store
 1518                    .as_local()
 1519                    .unwrap()
 1520                    .language_servers_for_buffer(buffer, cx)
 1521                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1522                    .collect::<Vec<_>>();
 1523                let settings =
 1524                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1525                        .into_owned();
 1526                (adapters_and_servers, settings)
 1527            })
 1528        })?;
 1529
 1530        /// Apply edits to the buffer that will become part of the formatting transaction.
 1531        /// Fails if the buffer has been edited since the start of that transaction.
 1532        fn extend_formatting_transaction(
 1533            buffer: &FormattableBuffer,
 1534            formatting_transaction_id: text::TransactionId,
 1535            cx: &mut AsyncApp,
 1536            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1537        ) -> anyhow::Result<()> {
 1538            buffer.handle.update(cx, |buffer, cx| {
 1539                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1540                if last_transaction_id != Some(formatting_transaction_id) {
 1541                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1542                }
 1543                buffer.start_transaction();
 1544                operation(buffer, cx);
 1545                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1546                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1547                }
 1548                Ok(())
 1549            })?
 1550        }
 1551
 1552        // handle whitespace formatting
 1553        if settings.remove_trailing_whitespace_on_save {
 1554            zlog::trace!(logger => "removing trailing whitespace");
 1555            let diff = buffer
 1556                .handle
 1557                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1558                .await;
 1559            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1560                buffer.apply_diff(diff, cx);
 1561            })?;
 1562        }
 1563
 1564        if settings.ensure_final_newline_on_save {
 1565            zlog::trace!(logger => "ensuring final newline");
 1566            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1567                buffer.ensure_final_newline(cx);
 1568            })?;
 1569        }
 1570
 1571        // Formatter for `code_actions_on_format` that runs before
 1572        // the rest of the formatters
 1573        let mut code_actions_on_format_formatters = None;
 1574        let should_run_code_actions_on_format = !matches!(
 1575            (trigger, &settings.format_on_save),
 1576            (FormatTrigger::Save, &FormatOnSave::Off)
 1577        );
 1578        if should_run_code_actions_on_format {
 1579            let have_code_actions_to_run_on_format = settings
 1580                .code_actions_on_format
 1581                .values()
 1582                .any(|enabled| *enabled);
 1583            if have_code_actions_to_run_on_format {
 1584                zlog::trace!(logger => "going to run code actions on format");
 1585                code_actions_on_format_formatters = Some(
 1586                    settings
 1587                        .code_actions_on_format
 1588                        .iter()
 1589                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1590                        .cloned()
 1591                        .map(Formatter::CodeAction)
 1592                        .collect::<Vec<_>>(),
 1593                );
 1594            }
 1595        }
 1596
 1597        let formatters = match (trigger, &settings.format_on_save) {
 1598            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1599            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1600                settings.formatter.as_ref()
 1601            }
 1602        };
 1603
 1604        let formatters = code_actions_on_format_formatters
 1605            .iter()
 1606            .flatten()
 1607            .chain(formatters);
 1608
 1609        for formatter in formatters {
 1610            let formatter = if formatter == &Formatter::Auto {
 1611                if settings.prettier.allowed {
 1612                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1613                    &Formatter::Prettier
 1614                } else {
 1615                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1616                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1617                }
 1618            } else {
 1619                formatter
 1620            };
 1621            match formatter {
 1622                Formatter::Auto => unreachable!("Auto resolved above"),
 1623                Formatter::Prettier => {
 1624                    let logger = zlog::scoped!(logger => "prettier");
 1625                    zlog::trace!(logger => "formatting");
 1626                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1627
 1628                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1629                        lsp_store.prettier_store().unwrap().downgrade()
 1630                    })?;
 1631                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1632                        .await
 1633                        .transpose()?;
 1634                    let Some(diff) = diff else {
 1635                        zlog::trace!(logger => "No changes");
 1636                        continue;
 1637                    };
 1638
 1639                    extend_formatting_transaction(
 1640                        buffer,
 1641                        formatting_transaction_id,
 1642                        cx,
 1643                        |buffer, cx| {
 1644                            buffer.apply_diff(diff, cx);
 1645                        },
 1646                    )?;
 1647                }
 1648                Formatter::External { command, arguments } => {
 1649                    let logger = zlog::scoped!(logger => "command");
 1650                    zlog::trace!(logger => "formatting");
 1651                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1652
 1653                    let diff = Self::format_via_external_command(
 1654                        buffer,
 1655                        command.as_ref(),
 1656                        arguments.as_deref(),
 1657                        cx,
 1658                    )
 1659                    .await
 1660                    .with_context(|| {
 1661                        format!("Failed to format buffer via external command: {}", command)
 1662                    })?;
 1663                    let Some(diff) = diff else {
 1664                        zlog::trace!(logger => "No changes");
 1665                        continue;
 1666                    };
 1667
 1668                    extend_formatting_transaction(
 1669                        buffer,
 1670                        formatting_transaction_id,
 1671                        cx,
 1672                        |buffer, cx| {
 1673                            buffer.apply_diff(diff, cx);
 1674                        },
 1675                    )?;
 1676                }
 1677                Formatter::LanguageServer(specifier) => {
 1678                    let logger = zlog::scoped!(logger => "language-server");
 1679                    zlog::trace!(logger => "formatting");
 1680                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1681
 1682                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1683                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1684                        continue;
 1685                    };
 1686
 1687                    let language_server = match specifier {
 1688                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1689                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1690                                if adapter.name.0.as_ref() == name {
 1691                                    Some(server.clone())
 1692                                } else {
 1693                                    None
 1694                                }
 1695                            })
 1696                        }
 1697                        settings::LanguageServerFormatterSpecifier::Current => {
 1698                            adapters_and_servers.first().map(|e| e.1.clone())
 1699                        }
 1700                    };
 1701
 1702                    let Some(language_server) = language_server else {
 1703                        log::debug!(
 1704                            "No language server found to format buffer '{:?}'. Skipping",
 1705                            buffer_path_abs.as_path().to_string_lossy()
 1706                        );
 1707                        continue;
 1708                    };
 1709
 1710                    zlog::trace!(
 1711                        logger =>
 1712                        "Formatting buffer '{:?}' using language server '{:?}'",
 1713                        buffer_path_abs.as_path().to_string_lossy(),
 1714                        language_server.name()
 1715                    );
 1716
 1717                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1718                        zlog::trace!(logger => "formatting ranges");
 1719                        Self::format_ranges_via_lsp(
 1720                            &lsp_store,
 1721                            &buffer.handle,
 1722                            ranges,
 1723                            buffer_path_abs,
 1724                            &language_server,
 1725                            &settings,
 1726                            cx,
 1727                        )
 1728                        .await
 1729                        .context("Failed to format ranges via language server")?
 1730                    } else {
 1731                        zlog::trace!(logger => "formatting full");
 1732                        Self::format_via_lsp(
 1733                            &lsp_store,
 1734                            &buffer.handle,
 1735                            buffer_path_abs,
 1736                            &language_server,
 1737                            &settings,
 1738                            cx,
 1739                        )
 1740                        .await
 1741                        .context("failed to format via language server")?
 1742                    };
 1743
 1744                    if edits.is_empty() {
 1745                        zlog::trace!(logger => "No changes");
 1746                        continue;
 1747                    }
 1748                    extend_formatting_transaction(
 1749                        buffer,
 1750                        formatting_transaction_id,
 1751                        cx,
 1752                        |buffer, cx| {
 1753                            buffer.edit(edits, None, cx);
 1754                        },
 1755                    )?;
 1756                }
 1757                Formatter::CodeAction(code_action_name) => {
 1758                    let logger = zlog::scoped!(logger => "code-actions");
 1759                    zlog::trace!(logger => "formatting");
 1760                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1761
 1762                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1763                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1764                        continue;
 1765                    };
 1766
 1767                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1768                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1769
 1770                    let mut actions_and_servers = Vec::new();
 1771
 1772                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1773                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1774                            &lsp_store,
 1775                            language_server.server_id(),
 1776                            vec![code_action_kind.clone()],
 1777                            &buffer.handle,
 1778                            cx,
 1779                        )
 1780                        .await
 1781                        .with_context(|| {
 1782                            format!(
 1783                                "Failed to resolve code action {:?} with language server {}",
 1784                                code_action_kind,
 1785                                language_server.name()
 1786                            )
 1787                        });
 1788                        let Ok(actions) = actions_result else {
 1789                            // note: it may be better to set result to the error and break formatters here
 1790                            // but for now we try to execute the actions that we can resolve and skip the rest
 1791                            zlog::error!(
 1792                                logger =>
 1793                                "Failed to resolve code action {:?} with language server {}",
 1794                                code_action_kind,
 1795                                language_server.name()
 1796                            );
 1797                            continue;
 1798                        };
 1799                        for action in actions {
 1800                            actions_and_servers.push((action, index));
 1801                        }
 1802                    }
 1803
 1804                    if actions_and_servers.is_empty() {
 1805                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1806                        continue;
 1807                    }
 1808
 1809                    'actions: for (mut action, server_index) in actions_and_servers {
 1810                        let server = &adapters_and_servers[server_index].1;
 1811
 1812                        let describe_code_action = |action: &CodeAction| {
 1813                            format!(
 1814                                "code action '{}' with title \"{}\" on server {}",
 1815                                action
 1816                                    .lsp_action
 1817                                    .action_kind()
 1818                                    .unwrap_or("unknown".into())
 1819                                    .as_str(),
 1820                                action.lsp_action.title(),
 1821                                server.name(),
 1822                            )
 1823                        };
 1824
 1825                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1826
 1827                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1828                            zlog::error!(
 1829                                logger =>
 1830                                "Failed to resolve {}. Error: {}",
 1831                                describe_code_action(&action),
 1832                                err
 1833                            );
 1834                            continue;
 1835                        }
 1836
 1837                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1838                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1839                            // but filters out and logs warnings for code actions that require unreasonably
 1840                            // difficult handling on our part, such as:
 1841                            // - applying edits that call commands
 1842                            //   which can result in arbitrary workspace edits being sent from the server that
 1843                            //   have no way of being tied back to the command that initiated them (i.e. we
 1844                            //   can't know which edits are part of the format request, or if the server is done sending
 1845                            //   actions in response to the command)
 1846                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1847                            //   as we then would need to handle such changes correctly in the local history as well
 1848                            //   as the remote history through the ProjectTransaction
 1849                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1850                            // Supporting these actions is not impossible, but not supported as of yet.
 1851                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1852                                zlog::trace!(
 1853                                    logger =>
 1854                                    "No changes for code action. Skipping {}",
 1855                                    describe_code_action(&action),
 1856                                );
 1857                                continue;
 1858                            }
 1859
 1860                            let mut operations = Vec::new();
 1861                            if let Some(document_changes) = edit.document_changes {
 1862                                match document_changes {
 1863                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1864                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1865                                    ),
 1866                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1867                                }
 1868                            } else if let Some(changes) = edit.changes {
 1869                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1870                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1871                                        text_document:
 1872                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1873                                                uri,
 1874                                                version: None,
 1875                                            },
 1876                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1877                                    })
 1878                                }));
 1879                            }
 1880
 1881                            let mut edits = Vec::with_capacity(operations.len());
 1882
 1883                            if operations.is_empty() {
 1884                                zlog::trace!(
 1885                                    logger =>
 1886                                    "No changes for code action. Skipping {}",
 1887                                    describe_code_action(&action),
 1888                                );
 1889                                continue;
 1890                            }
 1891                            for operation in operations {
 1892                                let op = match operation {
 1893                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1894                                    lsp::DocumentChangeOperation::Op(_) => {
 1895                                        zlog::warn!(
 1896                                            logger =>
 1897                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1898                                            describe_code_action(&action),
 1899                                        );
 1900                                        continue 'actions;
 1901                                    }
 1902                                };
 1903                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1904                                    zlog::warn!(
 1905                                        logger =>
 1906                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1907                                        &op.text_document.uri,
 1908                                        describe_code_action(&action),
 1909                                    );
 1910                                    continue 'actions;
 1911                                };
 1912                                if &file_path != buffer_path_abs {
 1913                                    zlog::warn!(
 1914                                        logger =>
 1915                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1916                                        file_path,
 1917                                        buffer_path_abs,
 1918                                        describe_code_action(&action),
 1919                                    );
 1920                                    continue 'actions;
 1921                                }
 1922
 1923                                let mut lsp_edits = Vec::new();
 1924                                for edit in op.edits {
 1925                                    match edit {
 1926                                        Edit::Plain(edit) => {
 1927                                            if !lsp_edits.contains(&edit) {
 1928                                                lsp_edits.push(edit);
 1929                                            }
 1930                                        }
 1931                                        Edit::Annotated(edit) => {
 1932                                            if !lsp_edits.contains(&edit.text_edit) {
 1933                                                lsp_edits.push(edit.text_edit);
 1934                                            }
 1935                                        }
 1936                                        Edit::Snippet(_) => {
 1937                                            zlog::warn!(
 1938                                                logger =>
 1939                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1940                                                describe_code_action(&action),
 1941                                            );
 1942                                            continue 'actions;
 1943                                        }
 1944                                    }
 1945                                }
 1946                                let edits_result = lsp_store
 1947                                    .update(cx, |lsp_store, cx| {
 1948                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1949                                            &buffer.handle,
 1950                                            lsp_edits,
 1951                                            server.server_id(),
 1952                                            op.text_document.version,
 1953                                            cx,
 1954                                        )
 1955                                    })?
 1956                                    .await;
 1957                                let Ok(resolved_edits) = edits_result else {
 1958                                    zlog::warn!(
 1959                                        logger =>
 1960                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1961                                        buffer_path_abs.as_path(),
 1962                                        describe_code_action(&action),
 1963                                    );
 1964                                    continue 'actions;
 1965                                };
 1966                                edits.extend(resolved_edits);
 1967                            }
 1968
 1969                            if edits.is_empty() {
 1970                                zlog::warn!(logger => "No edits resolved from LSP");
 1971                                continue;
 1972                            }
 1973
 1974                            extend_formatting_transaction(
 1975                                buffer,
 1976                                formatting_transaction_id,
 1977                                cx,
 1978                                |buffer, cx| {
 1979                                    zlog::info!(
 1980                                        "Applying edits {edits:?}. Content: {:?}",
 1981                                        buffer.text()
 1982                                    );
 1983                                    buffer.edit(edits, None, cx);
 1984                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1985                                },
 1986                            )?;
 1987                        }
 1988
 1989                        if let Some(command) = action.lsp_action.command() {
 1990                            zlog::warn!(
 1991                                logger =>
 1992                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1993                                &command.command,
 1994                            );
 1995
 1996                            // bail early if command is invalid
 1997                            let server_capabilities = server.capabilities();
 1998                            let available_commands = server_capabilities
 1999                                .execute_command_provider
 2000                                .as_ref()
 2001                                .map(|options| options.commands.as_slice())
 2002                                .unwrap_or_default();
 2003                            if !available_commands.contains(&command.command) {
 2004                                zlog::warn!(
 2005                                    logger =>
 2006                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2007                                    command.command,
 2008                                    server.name(),
 2009                                );
 2010                                continue;
 2011                            }
 2012
 2013                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 2014                            extend_formatting_transaction(
 2015                                buffer,
 2016                                formatting_transaction_id,
 2017                                cx,
 2018                                |_, _| {},
 2019                            )?;
 2020                            zlog::info!(logger => "Executing command {}", &command.command);
 2021
 2022                            lsp_store.update(cx, |this, _| {
 2023                                this.as_local_mut()
 2024                                    .unwrap()
 2025                                    .last_workspace_edits_by_language_server
 2026                                    .remove(&server.server_id());
 2027                            })?;
 2028
 2029                            let execute_command_result = server
 2030                                .request::<lsp::request::ExecuteCommand>(
 2031                                    lsp::ExecuteCommandParams {
 2032                                        command: command.command.clone(),
 2033                                        arguments: command.arguments.clone().unwrap_or_default(),
 2034                                        ..Default::default()
 2035                                    },
 2036                                )
 2037                                .await
 2038                                .into_response();
 2039
 2040                            if execute_command_result.is_err() {
 2041                                zlog::error!(
 2042                                    logger =>
 2043                                    "Failed to execute command '{}' as part of {}",
 2044                                    &command.command,
 2045                                    describe_code_action(&action),
 2046                                );
 2047                                continue 'actions;
 2048                            }
 2049
 2050                            let mut project_transaction_command =
 2051                                lsp_store.update(cx, |this, _| {
 2052                                    this.as_local_mut()
 2053                                        .unwrap()
 2054                                        .last_workspace_edits_by_language_server
 2055                                        .remove(&server.server_id())
 2056                                        .unwrap_or_default()
 2057                                })?;
 2058
 2059                            if let Some(transaction) =
 2060                                project_transaction_command.0.remove(&buffer.handle)
 2061                            {
 2062                                zlog::trace!(
 2063                                    logger =>
 2064                                    "Successfully captured {} edits that resulted from command {}",
 2065                                    transaction.edit_ids.len(),
 2066                                    &command.command,
 2067                                );
 2068                                let transaction_id_project_transaction = transaction.id;
 2069                                buffer.handle.update(cx, |buffer, _| {
 2070                                    // it may have been removed from history if push_to_history was
 2071                                    // false in deserialize_workspace_edit. If so push it so we
 2072                                    // can merge it with the format transaction
 2073                                    // and pop the combined transaction off the history stack
 2074                                    // later if push_to_history is false
 2075                                    if buffer.get_transaction(transaction.id).is_none() {
 2076                                        buffer.push_transaction(transaction, Instant::now());
 2077                                    }
 2078                                    buffer.merge_transactions(
 2079                                        transaction_id_project_transaction,
 2080                                        formatting_transaction_id,
 2081                                    );
 2082                                })?;
 2083                            }
 2084
 2085                            if !project_transaction_command.0.is_empty() {
 2086                                let mut extra_buffers = String::new();
 2087                                for buffer in project_transaction_command.0.keys() {
 2088                                    buffer
 2089                                        .read_with(cx, |b, cx| {
 2090                                            if let Some(path) = b.project_path(cx) {
 2091                                                if !extra_buffers.is_empty() {
 2092                                                    extra_buffers.push_str(", ");
 2093                                                }
 2094                                                extra_buffers.push_str(path.path.as_unix_str());
 2095                                            }
 2096                                        })
 2097                                        .ok();
 2098                                }
 2099                                zlog::warn!(
 2100                                    logger =>
 2101                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2102                                    &command.command,
 2103                                    extra_buffers,
 2104                                );
 2105                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2106                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2107                                // add it so it's included, and merge it into the format transaction when its created later
 2108                            }
 2109                        }
 2110                    }
 2111                }
 2112            }
 2113        }
 2114
 2115        Ok(())
 2116    }
 2117
 2118    pub async fn format_ranges_via_lsp(
 2119        this: &WeakEntity<LspStore>,
 2120        buffer_handle: &Entity<Buffer>,
 2121        ranges: &[Range<Anchor>],
 2122        abs_path: &Path,
 2123        language_server: &Arc<LanguageServer>,
 2124        settings: &LanguageSettings,
 2125        cx: &mut AsyncApp,
 2126    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2127        let capabilities = &language_server.capabilities();
 2128        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2129        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2130            anyhow::bail!(
 2131                "{} language server does not support range formatting",
 2132                language_server.name()
 2133            );
 2134        }
 2135
 2136        let uri = file_path_to_lsp_url(abs_path)?;
 2137        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2138
 2139        let lsp_edits = {
 2140            let mut lsp_ranges = Vec::new();
 2141            this.update(cx, |_this, cx| {
 2142                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2143                // not have been sent to the language server. This seems like a fairly systemic
 2144                // issue, though, the resolution probably is not specific to formatting.
 2145                //
 2146                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2147                // LSP.
 2148                let snapshot = buffer_handle.read(cx).snapshot();
 2149                for range in ranges {
 2150                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2151                }
 2152                anyhow::Ok(())
 2153            })??;
 2154
 2155            let mut edits = None;
 2156            for range in lsp_ranges {
 2157                if let Some(mut edit) = language_server
 2158                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2159                        text_document: text_document.clone(),
 2160                        range,
 2161                        options: lsp_command::lsp_formatting_options(settings),
 2162                        work_done_progress_params: Default::default(),
 2163                    })
 2164                    .await
 2165                    .into_response()?
 2166                {
 2167                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2168                }
 2169            }
 2170            edits
 2171        };
 2172
 2173        if let Some(lsp_edits) = lsp_edits {
 2174            this.update(cx, |this, cx| {
 2175                this.as_local_mut().unwrap().edits_from_lsp(
 2176                    buffer_handle,
 2177                    lsp_edits,
 2178                    language_server.server_id(),
 2179                    None,
 2180                    cx,
 2181                )
 2182            })?
 2183            .await
 2184        } else {
 2185            Ok(Vec::with_capacity(0))
 2186        }
 2187    }
 2188
 2189    async fn format_via_lsp(
 2190        this: &WeakEntity<LspStore>,
 2191        buffer: &Entity<Buffer>,
 2192        abs_path: &Path,
 2193        language_server: &Arc<LanguageServer>,
 2194        settings: &LanguageSettings,
 2195        cx: &mut AsyncApp,
 2196    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2197        let logger = zlog::scoped!("lsp_format");
 2198        zlog::debug!(logger => "Formatting via LSP");
 2199
 2200        let uri = file_path_to_lsp_url(abs_path)?;
 2201        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2202        let capabilities = &language_server.capabilities();
 2203
 2204        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2205        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2206
 2207        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2208            let _timer = zlog::time!(logger => "format-full");
 2209            language_server
 2210                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2211                    text_document,
 2212                    options: lsp_command::lsp_formatting_options(settings),
 2213                    work_done_progress_params: Default::default(),
 2214                })
 2215                .await
 2216                .into_response()?
 2217        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2218            let _timer = zlog::time!(logger => "format-range");
 2219            let buffer_start = lsp::Position::new(0, 0);
 2220            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2221            language_server
 2222                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2223                    text_document: text_document.clone(),
 2224                    range: lsp::Range::new(buffer_start, buffer_end),
 2225                    options: lsp_command::lsp_formatting_options(settings),
 2226                    work_done_progress_params: Default::default(),
 2227                })
 2228                .await
 2229                .into_response()?
 2230        } else {
 2231            None
 2232        };
 2233
 2234        if let Some(lsp_edits) = lsp_edits {
 2235            this.update(cx, |this, cx| {
 2236                this.as_local_mut().unwrap().edits_from_lsp(
 2237                    buffer,
 2238                    lsp_edits,
 2239                    language_server.server_id(),
 2240                    None,
 2241                    cx,
 2242                )
 2243            })?
 2244            .await
 2245        } else {
 2246            Ok(Vec::with_capacity(0))
 2247        }
 2248    }
 2249
 2250    async fn format_via_external_command(
 2251        buffer: &FormattableBuffer,
 2252        command: &str,
 2253        arguments: Option<&[String]>,
 2254        cx: &mut AsyncApp,
 2255    ) -> Result<Option<Diff>> {
 2256        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2257            let file = File::from_dyn(buffer.file())?;
 2258            let worktree = file.worktree.read(cx);
 2259            let mut worktree_path = worktree.abs_path().to_path_buf();
 2260            if worktree.root_entry()?.is_file() {
 2261                worktree_path.pop();
 2262            }
 2263            Some(worktree_path)
 2264        })?;
 2265
 2266        let mut child = util::command::new_smol_command(command);
 2267
 2268        if let Some(buffer_env) = buffer.env.as_ref() {
 2269            child.envs(buffer_env);
 2270        }
 2271
 2272        if let Some(working_dir_path) = working_dir_path {
 2273            child.current_dir(working_dir_path);
 2274        }
 2275
 2276        if let Some(arguments) = arguments {
 2277            child.args(arguments.iter().map(|arg| {
 2278                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2279                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2280                } else {
 2281                    arg.replace("{buffer_path}", "Untitled")
 2282                }
 2283            }));
 2284        }
 2285
 2286        let mut child = child
 2287            .stdin(smol::process::Stdio::piped())
 2288            .stdout(smol::process::Stdio::piped())
 2289            .stderr(smol::process::Stdio::piped())
 2290            .spawn()?;
 2291
 2292        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2293        let text = buffer
 2294            .handle
 2295            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2296        for chunk in text.chunks() {
 2297            stdin.write_all(chunk.as_bytes()).await?;
 2298        }
 2299        stdin.flush().await?;
 2300
 2301        let output = child.output().await?;
 2302        anyhow::ensure!(
 2303            output.status.success(),
 2304            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2305            output.status.code(),
 2306            String::from_utf8_lossy(&output.stdout),
 2307            String::from_utf8_lossy(&output.stderr),
 2308        );
 2309
 2310        let stdout = String::from_utf8(output.stdout)?;
 2311        Ok(Some(
 2312            buffer
 2313                .handle
 2314                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2315                .await,
 2316        ))
 2317    }
 2318
 2319    async fn try_resolve_code_action(
 2320        lang_server: &LanguageServer,
 2321        action: &mut CodeAction,
 2322    ) -> anyhow::Result<()> {
 2323        match &mut action.lsp_action {
 2324            LspAction::Action(lsp_action) => {
 2325                if !action.resolved
 2326                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2327                    && lsp_action.data.is_some()
 2328                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2329                {
 2330                    **lsp_action = lang_server
 2331                        .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2332                        .await
 2333                        .into_response()?;
 2334                }
 2335            }
 2336            LspAction::CodeLens(lens) => {
 2337                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2338                    *lens = lang_server
 2339                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2340                        .await
 2341                        .into_response()?;
 2342                }
 2343            }
 2344            LspAction::Command(_) => {}
 2345        }
 2346
 2347        action.resolved = true;
 2348        anyhow::Ok(())
 2349    }
 2350
 2351    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2352        let buffer = buffer_handle.read(cx);
 2353
 2354        let file = buffer.file().cloned();
 2355
 2356        let Some(file) = File::from_dyn(file.as_ref()) else {
 2357            return;
 2358        };
 2359        if !file.is_local() {
 2360            return;
 2361        }
 2362        let path = ProjectPath::from_file(file, cx);
 2363        let worktree_id = file.worktree_id(cx);
 2364        let language = buffer.language().cloned();
 2365
 2366        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2367            for (server_id, diagnostics) in
 2368                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2369            {
 2370                self.update_buffer_diagnostics(
 2371                    buffer_handle,
 2372                    server_id,
 2373                    None,
 2374                    None,
 2375                    None,
 2376                    Vec::new(),
 2377                    diagnostics,
 2378                    cx,
 2379                )
 2380                .log_err();
 2381            }
 2382        }
 2383        let Some(language) = language else {
 2384            return;
 2385        };
 2386        let Some(snapshot) = self
 2387            .worktree_store
 2388            .read(cx)
 2389            .worktree_for_id(worktree_id, cx)
 2390            .map(|worktree| worktree.read(cx).snapshot())
 2391        else {
 2392            return;
 2393        };
 2394        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2395
 2396        for server_id in
 2397            self.lsp_tree
 2398                .get(path, language.name(), language.manifest(), &delegate, cx)
 2399        {
 2400            let server = self
 2401                .language_servers
 2402                .get(&server_id)
 2403                .and_then(|server_state| {
 2404                    if let LanguageServerState::Running { server, .. } = server_state {
 2405                        Some(server.clone())
 2406                    } else {
 2407                        None
 2408                    }
 2409                });
 2410            let server = match server {
 2411                Some(server) => server,
 2412                None => continue,
 2413            };
 2414
 2415            buffer_handle.update(cx, |buffer, cx| {
 2416                buffer.set_completion_triggers(
 2417                    server.server_id(),
 2418                    server
 2419                        .capabilities()
 2420                        .completion_provider
 2421                        .as_ref()
 2422                        .and_then(|provider| {
 2423                            provider
 2424                                .trigger_characters
 2425                                .as_ref()
 2426                                .map(|characters| characters.iter().cloned().collect())
 2427                        })
 2428                        .unwrap_or_default(),
 2429                    cx,
 2430                );
 2431            });
 2432        }
 2433    }
 2434
 2435    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2436        buffer.update(cx, |buffer, cx| {
 2437            let Some(language) = buffer.language() else {
 2438                return;
 2439            };
 2440            let path = ProjectPath {
 2441                worktree_id: old_file.worktree_id(cx),
 2442                path: old_file.path.clone(),
 2443            };
 2444            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2445                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2446                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2447            }
 2448        });
 2449    }
 2450
 2451    fn update_buffer_diagnostics(
 2452        &mut self,
 2453        buffer: &Entity<Buffer>,
 2454        server_id: LanguageServerId,
 2455        registration_id: Option<Option<SharedString>>,
 2456        result_id: Option<SharedString>,
 2457        version: Option<i32>,
 2458        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2459        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2460        cx: &mut Context<LspStore>,
 2461    ) -> Result<()> {
 2462        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2463            Ordering::Equal
 2464                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2465                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2466                .then_with(|| a.severity.cmp(&b.severity))
 2467                .then_with(|| a.message.cmp(&b.message))
 2468        }
 2469
 2470        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2471        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2472        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2473
 2474        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2475            Ordering::Equal
 2476                .then_with(|| a.range.start.cmp(&b.range.start))
 2477                .then_with(|| b.range.end.cmp(&a.range.end))
 2478                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2479        });
 2480
 2481        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2482
 2483        let edits_since_save = std::cell::LazyCell::new(|| {
 2484            let saved_version = buffer.read(cx).saved_version();
 2485            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2486        });
 2487
 2488        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2489
 2490        for (new_diagnostic, entry) in diagnostics {
 2491            let start;
 2492            let end;
 2493            if new_diagnostic && entry.diagnostic.is_disk_based {
 2494                // Some diagnostics are based on files on disk instead of buffers'
 2495                // current contents. Adjust these diagnostics' ranges to reflect
 2496                // any unsaved edits.
 2497                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2498                // and were properly adjusted on reuse.
 2499                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2500                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2501            } else {
 2502                start = entry.range.start;
 2503                end = entry.range.end;
 2504            }
 2505
 2506            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2507                ..snapshot.clip_point_utf16(end, Bias::Right);
 2508
 2509            // Expand empty ranges by one codepoint
 2510            if range.start == range.end {
 2511                // This will be go to the next boundary when being clipped
 2512                range.end.column += 1;
 2513                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2514                if range.start == range.end && range.end.column > 0 {
 2515                    range.start.column -= 1;
 2516                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2517                }
 2518            }
 2519
 2520            sanitized_diagnostics.push(DiagnosticEntry {
 2521                range,
 2522                diagnostic: entry.diagnostic,
 2523            });
 2524        }
 2525        drop(edits_since_save);
 2526
 2527        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2528        buffer.update(cx, |buffer, cx| {
 2529            if let Some(registration_id) = registration_id {
 2530                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2531                    self.buffer_pull_diagnostics_result_ids
 2532                        .entry(server_id)
 2533                        .or_default()
 2534                        .entry(registration_id)
 2535                        .or_default()
 2536                        .insert(abs_path, result_id);
 2537                }
 2538            }
 2539
 2540            buffer.update_diagnostics(server_id, set, cx)
 2541        });
 2542
 2543        Ok(())
 2544    }
 2545
 2546    fn register_language_server_for_invisible_worktree(
 2547        &mut self,
 2548        worktree: &Entity<Worktree>,
 2549        language_server_id: LanguageServerId,
 2550        cx: &mut App,
 2551    ) {
 2552        let worktree = worktree.read(cx);
 2553        let worktree_id = worktree.id();
 2554        debug_assert!(!worktree.is_visible());
 2555        let Some(mut origin_seed) = self
 2556            .language_server_ids
 2557            .iter()
 2558            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2559        else {
 2560            return;
 2561        };
 2562        origin_seed.worktree_id = worktree_id;
 2563        self.language_server_ids
 2564            .entry(origin_seed)
 2565            .or_insert_with(|| UnifiedLanguageServer {
 2566                id: language_server_id,
 2567                project_roots: Default::default(),
 2568            });
 2569    }
 2570
 2571    fn register_buffer_with_language_servers(
 2572        &mut self,
 2573        buffer_handle: &Entity<Buffer>,
 2574        only_register_servers: HashSet<LanguageServerSelector>,
 2575        cx: &mut Context<LspStore>,
 2576    ) {
 2577        let buffer = buffer_handle.read(cx);
 2578        let buffer_id = buffer.remote_id();
 2579
 2580        let Some(file) = File::from_dyn(buffer.file()) else {
 2581            return;
 2582        };
 2583        if !file.is_local() {
 2584            return;
 2585        }
 2586
 2587        let abs_path = file.abs_path(cx);
 2588        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2589            return;
 2590        };
 2591        let initial_snapshot = buffer.text_snapshot();
 2592        let worktree_id = file.worktree_id(cx);
 2593
 2594        let Some(language) = buffer.language().cloned() else {
 2595            return;
 2596        };
 2597        let path: Arc<RelPath> = file
 2598            .path()
 2599            .parent()
 2600            .map(Arc::from)
 2601            .unwrap_or_else(|| file.path().clone());
 2602        let Some(worktree) = self
 2603            .worktree_store
 2604            .read(cx)
 2605            .worktree_for_id(worktree_id, cx)
 2606        else {
 2607            return;
 2608        };
 2609        let language_name = language.name();
 2610        let (reused, delegate, servers) = self
 2611            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2612            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2613            .unwrap_or_else(|| {
 2614                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2615                let delegate: Arc<dyn ManifestDelegate> =
 2616                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2617
 2618                let servers = self
 2619                    .lsp_tree
 2620                    .walk(
 2621                        ProjectPath { worktree_id, path },
 2622                        language.name(),
 2623                        language.manifest(),
 2624                        &delegate,
 2625                        cx,
 2626                    )
 2627                    .collect::<Vec<_>>();
 2628                (false, lsp_delegate, servers)
 2629            });
 2630        let servers_and_adapters = servers
 2631            .into_iter()
 2632            .filter_map(|server_node| {
 2633                if reused && server_node.server_id().is_none() {
 2634                    return None;
 2635                }
 2636                if !only_register_servers.is_empty() {
 2637                    if let Some(server_id) = server_node.server_id()
 2638                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2639                    {
 2640                        return None;
 2641                    }
 2642                    if let Some(name) = server_node.name()
 2643                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2644                    {
 2645                        return None;
 2646                    }
 2647                }
 2648
 2649                let server_id = server_node.server_id_or_init(|disposition| {
 2650                    let path = &disposition.path;
 2651
 2652                    {
 2653                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2654
 2655                        let server_id = self.get_or_insert_language_server(
 2656                            &worktree,
 2657                            delegate.clone(),
 2658                            disposition,
 2659                            &language_name,
 2660                            cx,
 2661                        );
 2662
 2663                        if let Some(state) = self.language_servers.get(&server_id)
 2664                            && let Ok(uri) = uri
 2665                        {
 2666                            state.add_workspace_folder(uri);
 2667                        };
 2668                        server_id
 2669                    }
 2670                })?;
 2671                let server_state = self.language_servers.get(&server_id)?;
 2672                if let LanguageServerState::Running {
 2673                    server, adapter, ..
 2674                } = server_state
 2675                {
 2676                    Some((server.clone(), adapter.clone()))
 2677                } else {
 2678                    None
 2679                }
 2680            })
 2681            .collect::<Vec<_>>();
 2682        for (server, adapter) in servers_and_adapters {
 2683            buffer_handle.update(cx, |buffer, cx| {
 2684                buffer.set_completion_triggers(
 2685                    server.server_id(),
 2686                    server
 2687                        .capabilities()
 2688                        .completion_provider
 2689                        .as_ref()
 2690                        .and_then(|provider| {
 2691                            provider
 2692                                .trigger_characters
 2693                                .as_ref()
 2694                                .map(|characters| characters.iter().cloned().collect())
 2695                        })
 2696                        .unwrap_or_default(),
 2697                    cx,
 2698                );
 2699            });
 2700
 2701            let snapshot = LspBufferSnapshot {
 2702                version: 0,
 2703                snapshot: initial_snapshot.clone(),
 2704            };
 2705
 2706            let mut registered = false;
 2707            self.buffer_snapshots
 2708                .entry(buffer_id)
 2709                .or_default()
 2710                .entry(server.server_id())
 2711                .or_insert_with(|| {
 2712                    registered = true;
 2713                    server.register_buffer(
 2714                        uri.clone(),
 2715                        adapter.language_id(&language.name()),
 2716                        0,
 2717                        initial_snapshot.text(),
 2718                    );
 2719
 2720                    vec![snapshot]
 2721                });
 2722
 2723            self.buffers_opened_in_servers
 2724                .entry(buffer_id)
 2725                .or_default()
 2726                .insert(server.server_id());
 2727            if registered {
 2728                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2729                    language_server_id: server.server_id(),
 2730                    name: None,
 2731                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2732                        proto::RegisteredForBuffer {
 2733                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2734                            buffer_id: buffer_id.to_proto(),
 2735                        },
 2736                    ),
 2737                });
 2738            }
 2739        }
 2740    }
 2741
 2742    fn reuse_existing_language_server<'lang_name>(
 2743        &self,
 2744        server_tree: &LanguageServerTree,
 2745        worktree: &Entity<Worktree>,
 2746        language_name: &'lang_name LanguageName,
 2747        cx: &mut App,
 2748    ) -> Option<(
 2749        Arc<LocalLspAdapterDelegate>,
 2750        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2751    )> {
 2752        if worktree.read(cx).is_visible() {
 2753            return None;
 2754        }
 2755
 2756        let worktree_store = self.worktree_store.read(cx);
 2757        let servers = server_tree
 2758            .instances
 2759            .iter()
 2760            .filter(|(worktree_id, _)| {
 2761                worktree_store
 2762                    .worktree_for_id(**worktree_id, cx)
 2763                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2764            })
 2765            .flat_map(|(worktree_id, servers)| {
 2766                servers
 2767                    .roots
 2768                    .iter()
 2769                    .flat_map(|(_, language_servers)| language_servers)
 2770                    .map(move |(_, (server_node, server_languages))| {
 2771                        (worktree_id, server_node, server_languages)
 2772                    })
 2773                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2774                    .map(|(worktree_id, server_node, _)| {
 2775                        (
 2776                            *worktree_id,
 2777                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2778                        )
 2779                    })
 2780            })
 2781            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2782                acc.entry(worktree_id)
 2783                    .or_insert_with(Vec::new)
 2784                    .push(server_node);
 2785                acc
 2786            })
 2787            .into_values()
 2788            .max_by_key(|servers| servers.len())?;
 2789
 2790        let worktree_id = worktree.read(cx).id();
 2791        let apply = move |tree: &mut LanguageServerTree| {
 2792            for server_node in &servers {
 2793                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2794            }
 2795            servers
 2796        };
 2797
 2798        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2799        Some((delegate, apply))
 2800    }
 2801
 2802    pub(crate) fn unregister_old_buffer_from_language_servers(
 2803        &mut self,
 2804        buffer: &Entity<Buffer>,
 2805        old_file: &File,
 2806        cx: &mut App,
 2807    ) {
 2808        let old_path = match old_file.as_local() {
 2809            Some(local) => local.abs_path(cx),
 2810            None => return,
 2811        };
 2812
 2813        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2814            debug_panic!("{old_path:?} is not parseable as an URI");
 2815            return;
 2816        };
 2817        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2818    }
 2819
 2820    pub(crate) fn unregister_buffer_from_language_servers(
 2821        &mut self,
 2822        buffer: &Entity<Buffer>,
 2823        file_url: &lsp::Uri,
 2824        cx: &mut App,
 2825    ) {
 2826        buffer.update(cx, |buffer, cx| {
 2827            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2828
 2829            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2830                if snapshots
 2831                    .as_mut()
 2832                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2833                {
 2834                    language_server.unregister_buffer(file_url.clone());
 2835                }
 2836            }
 2837        });
 2838    }
 2839
 2840    fn buffer_snapshot_for_lsp_version(
 2841        &mut self,
 2842        buffer: &Entity<Buffer>,
 2843        server_id: LanguageServerId,
 2844        version: Option<i32>,
 2845        cx: &App,
 2846    ) -> Result<TextBufferSnapshot> {
 2847        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2848
 2849        if let Some(version) = version {
 2850            let buffer_id = buffer.read(cx).remote_id();
 2851            let snapshots = if let Some(snapshots) = self
 2852                .buffer_snapshots
 2853                .get_mut(&buffer_id)
 2854                .and_then(|m| m.get_mut(&server_id))
 2855            {
 2856                snapshots
 2857            } else if version == 0 {
 2858                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2859                // We detect this case and treat it as if the version was `None`.
 2860                return Ok(buffer.read(cx).text_snapshot());
 2861            } else {
 2862                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2863            };
 2864
 2865            let found_snapshot = snapshots
 2866                    .binary_search_by_key(&version, |e| e.version)
 2867                    .map(|ix| snapshots[ix].snapshot.clone())
 2868                    .map_err(|_| {
 2869                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2870                    })?;
 2871
 2872            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2873            Ok(found_snapshot)
 2874        } else {
 2875            Ok((buffer.read(cx)).text_snapshot())
 2876        }
 2877    }
 2878
 2879    async fn get_server_code_actions_from_action_kinds(
 2880        lsp_store: &WeakEntity<LspStore>,
 2881        language_server_id: LanguageServerId,
 2882        code_action_kinds: Vec<lsp::CodeActionKind>,
 2883        buffer: &Entity<Buffer>,
 2884        cx: &mut AsyncApp,
 2885    ) -> Result<Vec<CodeAction>> {
 2886        let actions = lsp_store
 2887            .update(cx, move |this, cx| {
 2888                let request = GetCodeActions {
 2889                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 2890                    kinds: Some(code_action_kinds),
 2891                };
 2892                let server = LanguageServerToQuery::Other(language_server_id);
 2893                this.request_lsp(buffer.clone(), server, request, cx)
 2894            })?
 2895            .await?;
 2896        Ok(actions)
 2897    }
 2898
 2899    pub async fn execute_code_actions_on_server(
 2900        lsp_store: &WeakEntity<LspStore>,
 2901        language_server: &Arc<LanguageServer>,
 2902
 2903        actions: Vec<CodeAction>,
 2904        push_to_history: bool,
 2905        project_transaction: &mut ProjectTransaction,
 2906        cx: &mut AsyncApp,
 2907    ) -> anyhow::Result<()> {
 2908        for mut action in actions {
 2909            Self::try_resolve_code_action(language_server, &mut action)
 2910                .await
 2911                .context("resolving a formatting code action")?;
 2912
 2913            if let Some(edit) = action.lsp_action.edit() {
 2914                if edit.changes.is_none() && edit.document_changes.is_none() {
 2915                    continue;
 2916                }
 2917
 2918                let new = Self::deserialize_workspace_edit(
 2919                    lsp_store.upgrade().context("project dropped")?,
 2920                    edit.clone(),
 2921                    push_to_history,
 2922                    language_server.clone(),
 2923                    cx,
 2924                )
 2925                .await?;
 2926                project_transaction.0.extend(new.0);
 2927            }
 2928
 2929            if let Some(command) = action.lsp_action.command() {
 2930                let server_capabilities = language_server.capabilities();
 2931                let available_commands = server_capabilities
 2932                    .execute_command_provider
 2933                    .as_ref()
 2934                    .map(|options| options.commands.as_slice())
 2935                    .unwrap_or_default();
 2936                if available_commands.contains(&command.command) {
 2937                    lsp_store.update(cx, |lsp_store, _| {
 2938                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2939                            mode.last_workspace_edits_by_language_server
 2940                                .remove(&language_server.server_id());
 2941                        }
 2942                    })?;
 2943
 2944                    language_server
 2945                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2946                            command: command.command.clone(),
 2947                            arguments: command.arguments.clone().unwrap_or_default(),
 2948                            ..Default::default()
 2949                        })
 2950                        .await
 2951                        .into_response()
 2952                        .context("execute command")?;
 2953
 2954                    lsp_store.update(cx, |this, _| {
 2955                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2956                            project_transaction.0.extend(
 2957                                mode.last_workspace_edits_by_language_server
 2958                                    .remove(&language_server.server_id())
 2959                                    .unwrap_or_default()
 2960                                    .0,
 2961                            )
 2962                        }
 2963                    })?;
 2964                } else {
 2965                    log::warn!(
 2966                        "Cannot execute a command {} not listed in the language server capabilities",
 2967                        command.command
 2968                    )
 2969                }
 2970            }
 2971        }
 2972        Ok(())
 2973    }
 2974
 2975    pub async fn deserialize_text_edits(
 2976        this: Entity<LspStore>,
 2977        buffer_to_edit: Entity<Buffer>,
 2978        edits: Vec<lsp::TextEdit>,
 2979        push_to_history: bool,
 2980        _: Arc<CachedLspAdapter>,
 2981        language_server: Arc<LanguageServer>,
 2982        cx: &mut AsyncApp,
 2983    ) -> Result<Option<Transaction>> {
 2984        let edits = this
 2985            .update(cx, |this, cx| {
 2986                this.as_local_mut().unwrap().edits_from_lsp(
 2987                    &buffer_to_edit,
 2988                    edits,
 2989                    language_server.server_id(),
 2990                    None,
 2991                    cx,
 2992                )
 2993            })?
 2994            .await?;
 2995
 2996        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2997            buffer.finalize_last_transaction();
 2998            buffer.start_transaction();
 2999            for (range, text) in edits {
 3000                buffer.edit([(range, text)], None, cx);
 3001            }
 3002
 3003            if buffer.end_transaction(cx).is_some() {
 3004                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3005                if !push_to_history {
 3006                    buffer.forget_transaction(transaction.id);
 3007                }
 3008                Some(transaction)
 3009            } else {
 3010                None
 3011            }
 3012        })?;
 3013
 3014        Ok(transaction)
 3015    }
 3016
 3017    #[allow(clippy::type_complexity)]
 3018    pub(crate) fn edits_from_lsp(
 3019        &mut self,
 3020        buffer: &Entity<Buffer>,
 3021        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3022        server_id: LanguageServerId,
 3023        version: Option<i32>,
 3024        cx: &mut Context<LspStore>,
 3025    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3026        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3027        cx.background_spawn(async move {
 3028            let snapshot = snapshot?;
 3029            let mut lsp_edits = lsp_edits
 3030                .into_iter()
 3031                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3032                .collect::<Vec<_>>();
 3033
 3034            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 3035
 3036            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3037            let mut edits = Vec::new();
 3038            while let Some((range, mut new_text)) = lsp_edits.next() {
 3039                // Clip invalid ranges provided by the language server.
 3040                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3041                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3042
 3043                // Combine any LSP edits that are adjacent.
 3044                //
 3045                // Also, combine LSP edits that are separated from each other by only
 3046                // a newline. This is important because for some code actions,
 3047                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3048                // are separated by unchanged newline characters.
 3049                //
 3050                // In order for the diffing logic below to work properly, any edits that
 3051                // cancel each other out must be combined into one.
 3052                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3053                    if next_range.start.0 > range.end {
 3054                        if next_range.start.0.row > range.end.row + 1
 3055                            || next_range.start.0.column > 0
 3056                            || snapshot.clip_point_utf16(
 3057                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3058                                Bias::Left,
 3059                            ) > range.end
 3060                        {
 3061                            break;
 3062                        }
 3063                        new_text.push('\n');
 3064                    }
 3065                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3066                    new_text.push_str(next_text);
 3067                    lsp_edits.next();
 3068                }
 3069
 3070                // For multiline edits, perform a diff of the old and new text so that
 3071                // we can identify the changes more precisely, preserving the locations
 3072                // of any anchors positioned in the unchanged regions.
 3073                if range.end.row > range.start.row {
 3074                    let offset = range.start.to_offset(&snapshot);
 3075                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3076                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3077                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3078                        (
 3079                            snapshot.anchor_after(offset + range.start)
 3080                                ..snapshot.anchor_before(offset + range.end),
 3081                            replacement,
 3082                        )
 3083                    }));
 3084                } else if range.end == range.start {
 3085                    let anchor = snapshot.anchor_after(range.start);
 3086                    edits.push((anchor..anchor, new_text.into()));
 3087                } else {
 3088                    let edit_start = snapshot.anchor_after(range.start);
 3089                    let edit_end = snapshot.anchor_before(range.end);
 3090                    edits.push((edit_start..edit_end, new_text.into()));
 3091                }
 3092            }
 3093
 3094            Ok(edits)
 3095        })
 3096    }
 3097
 3098    pub(crate) async fn deserialize_workspace_edit(
 3099        this: Entity<LspStore>,
 3100        edit: lsp::WorkspaceEdit,
 3101        push_to_history: bool,
 3102        language_server: Arc<LanguageServer>,
 3103        cx: &mut AsyncApp,
 3104    ) -> Result<ProjectTransaction> {
 3105        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 3106
 3107        let mut operations = Vec::new();
 3108        if let Some(document_changes) = edit.document_changes {
 3109            match document_changes {
 3110                lsp::DocumentChanges::Edits(edits) => {
 3111                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3112                }
 3113                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3114            }
 3115        } else if let Some(changes) = edit.changes {
 3116            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3117                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3118                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3119                        uri,
 3120                        version: None,
 3121                    },
 3122                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3123                })
 3124            }));
 3125        }
 3126
 3127        let mut project_transaction = ProjectTransaction::default();
 3128        for operation in operations {
 3129            match operation {
 3130                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3131                    let abs_path = op
 3132                        .uri
 3133                        .to_file_path()
 3134                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3135
 3136                    if let Some(parent_path) = abs_path.parent() {
 3137                        fs.create_dir(parent_path).await?;
 3138                    }
 3139                    if abs_path.ends_with("/") {
 3140                        fs.create_dir(&abs_path).await?;
 3141                    } else {
 3142                        fs.create_file(
 3143                            &abs_path,
 3144                            op.options
 3145                                .map(|options| fs::CreateOptions {
 3146                                    overwrite: options.overwrite.unwrap_or(false),
 3147                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3148                                })
 3149                                .unwrap_or_default(),
 3150                        )
 3151                        .await?;
 3152                    }
 3153                }
 3154
 3155                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3156                    let source_abs_path = op
 3157                        .old_uri
 3158                        .to_file_path()
 3159                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3160                    let target_abs_path = op
 3161                        .new_uri
 3162                        .to_file_path()
 3163                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3164
 3165                    let options = fs::RenameOptions {
 3166                        overwrite: op
 3167                            .options
 3168                            .as_ref()
 3169                            .and_then(|options| options.overwrite)
 3170                            .unwrap_or(false),
 3171                        ignore_if_exists: op
 3172                            .options
 3173                            .as_ref()
 3174                            .and_then(|options| options.ignore_if_exists)
 3175                            .unwrap_or(false),
 3176                        create_parents: true,
 3177                    };
 3178
 3179                    fs.rename(&source_abs_path, &target_abs_path, options)
 3180                        .await?;
 3181                }
 3182
 3183                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3184                    let abs_path = op
 3185                        .uri
 3186                        .to_file_path()
 3187                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3188                    let options = op
 3189                        .options
 3190                        .map(|options| fs::RemoveOptions {
 3191                            recursive: options.recursive.unwrap_or(false),
 3192                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3193                        })
 3194                        .unwrap_or_default();
 3195                    if abs_path.ends_with("/") {
 3196                        fs.remove_dir(&abs_path, options).await?;
 3197                    } else {
 3198                        fs.remove_file(&abs_path, options).await?;
 3199                    }
 3200                }
 3201
 3202                lsp::DocumentChangeOperation::Edit(op) => {
 3203                    let buffer_to_edit = this
 3204                        .update(cx, |this, cx| {
 3205                            this.open_local_buffer_via_lsp(
 3206                                op.text_document.uri.clone(),
 3207                                language_server.server_id(),
 3208                                cx,
 3209                            )
 3210                        })?
 3211                        .await?;
 3212
 3213                    let edits = this
 3214                        .update(cx, |this, cx| {
 3215                            let path = buffer_to_edit.read(cx).project_path(cx);
 3216                            let active_entry = this.active_entry;
 3217                            let is_active_entry = path.is_some_and(|project_path| {
 3218                                this.worktree_store
 3219                                    .read(cx)
 3220                                    .entry_for_path(&project_path, cx)
 3221                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3222                            });
 3223                            let local = this.as_local_mut().unwrap();
 3224
 3225                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3226                            for edit in op.edits {
 3227                                match edit {
 3228                                    Edit::Plain(edit) => {
 3229                                        if !edits.contains(&edit) {
 3230                                            edits.push(edit)
 3231                                        }
 3232                                    }
 3233                                    Edit::Annotated(edit) => {
 3234                                        if !edits.contains(&edit.text_edit) {
 3235                                            edits.push(edit.text_edit)
 3236                                        }
 3237                                    }
 3238                                    Edit::Snippet(edit) => {
 3239                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3240                                        else {
 3241                                            continue;
 3242                                        };
 3243
 3244                                        if is_active_entry {
 3245                                            snippet_edits.push((edit.range, snippet));
 3246                                        } else {
 3247                                            // Since this buffer is not focused, apply a normal edit.
 3248                                            let new_edit = TextEdit {
 3249                                                range: edit.range,
 3250                                                new_text: snippet.text,
 3251                                            };
 3252                                            if !edits.contains(&new_edit) {
 3253                                                edits.push(new_edit);
 3254                                            }
 3255                                        }
 3256                                    }
 3257                                }
 3258                            }
 3259                            if !snippet_edits.is_empty() {
 3260                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3261                                let version = if let Some(buffer_version) = op.text_document.version
 3262                                {
 3263                                    local
 3264                                        .buffer_snapshot_for_lsp_version(
 3265                                            &buffer_to_edit,
 3266                                            language_server.server_id(),
 3267                                            Some(buffer_version),
 3268                                            cx,
 3269                                        )
 3270                                        .ok()
 3271                                        .map(|snapshot| snapshot.version)
 3272                                } else {
 3273                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3274                                };
 3275
 3276                                let most_recent_edit =
 3277                                    version.and_then(|version| version.most_recent());
 3278                                // Check if the edit that triggered that edit has been made by this participant.
 3279
 3280                                if let Some(most_recent_edit) = most_recent_edit {
 3281                                    cx.emit(LspStoreEvent::SnippetEdit {
 3282                                        buffer_id,
 3283                                        edits: snippet_edits,
 3284                                        most_recent_edit,
 3285                                    });
 3286                                }
 3287                            }
 3288
 3289                            local.edits_from_lsp(
 3290                                &buffer_to_edit,
 3291                                edits,
 3292                                language_server.server_id(),
 3293                                op.text_document.version,
 3294                                cx,
 3295                            )
 3296                        })?
 3297                        .await?;
 3298
 3299                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3300                        buffer.finalize_last_transaction();
 3301                        buffer.start_transaction();
 3302                        for (range, text) in edits {
 3303                            buffer.edit([(range, text)], None, cx);
 3304                        }
 3305
 3306                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3307                            if push_to_history {
 3308                                buffer.finalize_last_transaction();
 3309                                buffer.get_transaction(transaction_id).cloned()
 3310                            } else {
 3311                                buffer.forget_transaction(transaction_id)
 3312                            }
 3313                        })
 3314                    })?;
 3315                    if let Some(transaction) = transaction {
 3316                        project_transaction.0.insert(buffer_to_edit, transaction);
 3317                    }
 3318                }
 3319            }
 3320        }
 3321
 3322        Ok(project_transaction)
 3323    }
 3324
 3325    async fn on_lsp_workspace_edit(
 3326        this: WeakEntity<LspStore>,
 3327        params: lsp::ApplyWorkspaceEditParams,
 3328        server_id: LanguageServerId,
 3329        cx: &mut AsyncApp,
 3330    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3331        let this = this.upgrade().context("project project closed")?;
 3332        let language_server = this
 3333            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3334            .context("language server not found")?;
 3335        let transaction = Self::deserialize_workspace_edit(
 3336            this.clone(),
 3337            params.edit,
 3338            true,
 3339            language_server.clone(),
 3340            cx,
 3341        )
 3342        .await
 3343        .log_err();
 3344        this.update(cx, |this, cx| {
 3345            if let Some(transaction) = transaction {
 3346                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3347
 3348                this.as_local_mut()
 3349                    .unwrap()
 3350                    .last_workspace_edits_by_language_server
 3351                    .insert(server_id, transaction);
 3352            }
 3353        })?;
 3354        Ok(lsp::ApplyWorkspaceEditResponse {
 3355            applied: true,
 3356            failed_change: None,
 3357            failure_reason: None,
 3358        })
 3359    }
 3360
 3361    fn remove_worktree(
 3362        &mut self,
 3363        id_to_remove: WorktreeId,
 3364        cx: &mut Context<LspStore>,
 3365    ) -> Vec<LanguageServerId> {
 3366        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3367        self.diagnostics.remove(&id_to_remove);
 3368        self.prettier_store.update(cx, |prettier_store, cx| {
 3369            prettier_store.remove_worktree(id_to_remove, cx);
 3370        });
 3371
 3372        let mut servers_to_remove = BTreeSet::default();
 3373        let mut servers_to_preserve = HashSet::default();
 3374        for (seed, state) in &self.language_server_ids {
 3375            if seed.worktree_id == id_to_remove {
 3376                servers_to_remove.insert(state.id);
 3377            } else {
 3378                servers_to_preserve.insert(state.id);
 3379            }
 3380        }
 3381        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3382        self.language_server_ids
 3383            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3384        for server_id_to_remove in &servers_to_remove {
 3385            self.language_server_watched_paths
 3386                .remove(server_id_to_remove);
 3387            self.language_server_paths_watched_for_rename
 3388                .remove(server_id_to_remove);
 3389            self.last_workspace_edits_by_language_server
 3390                .remove(server_id_to_remove);
 3391            self.language_servers.remove(server_id_to_remove);
 3392            self.buffer_pull_diagnostics_result_ids
 3393                .remove(server_id_to_remove);
 3394            self.workspace_pull_diagnostics_result_ids
 3395                .remove(server_id_to_remove);
 3396            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3397                buffer_servers.remove(server_id_to_remove);
 3398            }
 3399            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3400        }
 3401        servers_to_remove.into_iter().collect()
 3402    }
 3403
 3404    fn rebuild_watched_paths_inner<'a>(
 3405        &'a self,
 3406        language_server_id: LanguageServerId,
 3407        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3408        cx: &mut Context<LspStore>,
 3409    ) -> LanguageServerWatchedPathsBuilder {
 3410        let worktrees = self
 3411            .worktree_store
 3412            .read(cx)
 3413            .worktrees()
 3414            .filter_map(|worktree| {
 3415                self.language_servers_for_worktree(worktree.read(cx).id())
 3416                    .find(|server| server.server_id() == language_server_id)
 3417                    .map(|_| worktree)
 3418            })
 3419            .collect::<Vec<_>>();
 3420
 3421        let mut worktree_globs = HashMap::default();
 3422        let mut abs_globs = HashMap::default();
 3423        log::trace!(
 3424            "Processing new watcher paths for language server with id {}",
 3425            language_server_id
 3426        );
 3427
 3428        for watcher in watchers {
 3429            if let Some((worktree, literal_prefix, pattern)) =
 3430                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3431            {
 3432                worktree.update(cx, |worktree, _| {
 3433                    if let Some((tree, glob)) =
 3434                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3435                    {
 3436                        tree.add_path_prefix_to_scan(literal_prefix);
 3437                        worktree_globs
 3438                            .entry(tree.id())
 3439                            .or_insert_with(GlobSetBuilder::new)
 3440                            .add(glob);
 3441                    }
 3442                });
 3443            } else {
 3444                let (path, pattern) = match &watcher.glob_pattern {
 3445                    lsp::GlobPattern::String(s) => {
 3446                        let watcher_path = SanitizedPath::new(s);
 3447                        let path = glob_literal_prefix(watcher_path.as_path());
 3448                        let pattern = watcher_path
 3449                            .as_path()
 3450                            .strip_prefix(&path)
 3451                            .map(|p| p.to_string_lossy().into_owned())
 3452                            .unwrap_or_else(|e| {
 3453                                debug_panic!(
 3454                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3455                                    s,
 3456                                    path.display(),
 3457                                    e
 3458                                );
 3459                                watcher_path.as_path().to_string_lossy().into_owned()
 3460                            });
 3461                        (path, pattern)
 3462                    }
 3463                    lsp::GlobPattern::Relative(rp) => {
 3464                        let Ok(mut base_uri) = match &rp.base_uri {
 3465                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3466                            lsp::OneOf::Right(base_uri) => base_uri,
 3467                        }
 3468                        .to_file_path() else {
 3469                            continue;
 3470                        };
 3471
 3472                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3473                        let pattern = Path::new(&rp.pattern)
 3474                            .strip_prefix(&path)
 3475                            .map(|p| p.to_string_lossy().into_owned())
 3476                            .unwrap_or_else(|e| {
 3477                                debug_panic!(
 3478                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3479                                    rp.pattern,
 3480                                    path.display(),
 3481                                    e
 3482                                );
 3483                                rp.pattern.clone()
 3484                            });
 3485                        base_uri.push(path);
 3486                        (base_uri, pattern)
 3487                    }
 3488                };
 3489
 3490                if let Some(glob) = Glob::new(&pattern).log_err() {
 3491                    if !path
 3492                        .components()
 3493                        .any(|c| matches!(c, path::Component::Normal(_)))
 3494                    {
 3495                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3496                        // rather than adding a new watcher for `/`.
 3497                        for worktree in &worktrees {
 3498                            worktree_globs
 3499                                .entry(worktree.read(cx).id())
 3500                                .or_insert_with(GlobSetBuilder::new)
 3501                                .add(glob.clone());
 3502                        }
 3503                    } else {
 3504                        abs_globs
 3505                            .entry(path.into())
 3506                            .or_insert_with(GlobSetBuilder::new)
 3507                            .add(glob);
 3508                    }
 3509                }
 3510            }
 3511        }
 3512
 3513        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3514        for (worktree_id, builder) in worktree_globs {
 3515            if let Ok(globset) = builder.build() {
 3516                watch_builder.watch_worktree(worktree_id, globset);
 3517            }
 3518        }
 3519        for (abs_path, builder) in abs_globs {
 3520            if let Ok(globset) = builder.build() {
 3521                watch_builder.watch_abs_path(abs_path, globset);
 3522            }
 3523        }
 3524        watch_builder
 3525    }
 3526
 3527    fn worktree_and_path_for_file_watcher(
 3528        worktrees: &[Entity<Worktree>],
 3529        watcher: &FileSystemWatcher,
 3530        cx: &App,
 3531    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3532        worktrees.iter().find_map(|worktree| {
 3533            let tree = worktree.read(cx);
 3534            let worktree_root_path = tree.abs_path();
 3535            let path_style = tree.path_style();
 3536            match &watcher.glob_pattern {
 3537                lsp::GlobPattern::String(s) => {
 3538                    let watcher_path = SanitizedPath::new(s);
 3539                    let relative = watcher_path
 3540                        .as_path()
 3541                        .strip_prefix(&worktree_root_path)
 3542                        .ok()?;
 3543                    let literal_prefix = glob_literal_prefix(relative);
 3544                    Some((
 3545                        worktree.clone(),
 3546                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3547                        relative.to_string_lossy().into_owned(),
 3548                    ))
 3549                }
 3550                lsp::GlobPattern::Relative(rp) => {
 3551                    let base_uri = match &rp.base_uri {
 3552                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3553                        lsp::OneOf::Right(base_uri) => base_uri,
 3554                    }
 3555                    .to_file_path()
 3556                    .ok()?;
 3557                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3558                    let mut literal_prefix = relative.to_owned();
 3559                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3560                    Some((
 3561                        worktree.clone(),
 3562                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3563                        rp.pattern.clone(),
 3564                    ))
 3565                }
 3566            }
 3567        })
 3568    }
 3569
 3570    fn rebuild_watched_paths(
 3571        &mut self,
 3572        language_server_id: LanguageServerId,
 3573        cx: &mut Context<LspStore>,
 3574    ) {
 3575        let Some(registrations) = self
 3576            .language_server_dynamic_registrations
 3577            .get(&language_server_id)
 3578        else {
 3579            return;
 3580        };
 3581
 3582        let watch_builder = self.rebuild_watched_paths_inner(
 3583            language_server_id,
 3584            registrations.did_change_watched_files.values().flatten(),
 3585            cx,
 3586        );
 3587        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3588        self.language_server_watched_paths
 3589            .insert(language_server_id, watcher);
 3590
 3591        cx.notify();
 3592    }
 3593
 3594    fn on_lsp_did_change_watched_files(
 3595        &mut self,
 3596        language_server_id: LanguageServerId,
 3597        registration_id: &str,
 3598        params: DidChangeWatchedFilesRegistrationOptions,
 3599        cx: &mut Context<LspStore>,
 3600    ) {
 3601        let registrations = self
 3602            .language_server_dynamic_registrations
 3603            .entry(language_server_id)
 3604            .or_default();
 3605
 3606        registrations
 3607            .did_change_watched_files
 3608            .insert(registration_id.to_string(), params.watchers);
 3609
 3610        self.rebuild_watched_paths(language_server_id, cx);
 3611    }
 3612
 3613    fn on_lsp_unregister_did_change_watched_files(
 3614        &mut self,
 3615        language_server_id: LanguageServerId,
 3616        registration_id: &str,
 3617        cx: &mut Context<LspStore>,
 3618    ) {
 3619        let registrations = self
 3620            .language_server_dynamic_registrations
 3621            .entry(language_server_id)
 3622            .or_default();
 3623
 3624        if registrations
 3625            .did_change_watched_files
 3626            .remove(registration_id)
 3627            .is_some()
 3628        {
 3629            log::info!(
 3630                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3631                language_server_id,
 3632                registration_id
 3633            );
 3634        } else {
 3635            log::warn!(
 3636                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3637                language_server_id,
 3638                registration_id
 3639            );
 3640        }
 3641
 3642        self.rebuild_watched_paths(language_server_id, cx);
 3643    }
 3644
 3645    async fn initialization_options_for_adapter(
 3646        adapter: Arc<dyn LspAdapter>,
 3647        delegate: &Arc<dyn LspAdapterDelegate>,
 3648    ) -> Result<Option<serde_json::Value>> {
 3649        let Some(mut initialization_config) =
 3650            adapter.clone().initialization_options(delegate).await?
 3651        else {
 3652            return Ok(None);
 3653        };
 3654
 3655        for other_adapter in delegate.registered_lsp_adapters() {
 3656            if other_adapter.name() == adapter.name() {
 3657                continue;
 3658            }
 3659            if let Ok(Some(target_config)) = other_adapter
 3660                .clone()
 3661                .additional_initialization_options(adapter.name(), delegate)
 3662                .await
 3663            {
 3664                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3665            }
 3666        }
 3667
 3668        Ok(Some(initialization_config))
 3669    }
 3670
 3671    async fn workspace_configuration_for_adapter(
 3672        adapter: Arc<dyn LspAdapter>,
 3673        delegate: &Arc<dyn LspAdapterDelegate>,
 3674        toolchain: Option<Toolchain>,
 3675        requested_uri: Option<Uri>,
 3676        cx: &mut AsyncApp,
 3677    ) -> Result<serde_json::Value> {
 3678        let mut workspace_config = adapter
 3679            .clone()
 3680            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3681            .await?;
 3682
 3683        for other_adapter in delegate.registered_lsp_adapters() {
 3684            if other_adapter.name() == adapter.name() {
 3685                continue;
 3686            }
 3687            if let Ok(Some(target_config)) = other_adapter
 3688                .clone()
 3689                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3690                .await
 3691            {
 3692                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3693            }
 3694        }
 3695
 3696        Ok(workspace_config)
 3697    }
 3698
 3699    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3700        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3701            Some(server.clone())
 3702        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3703            Some(Arc::clone(server))
 3704        } else {
 3705            None
 3706        }
 3707    }
 3708}
 3709
 3710fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3711    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3712        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3713            language_server_id: server.server_id(),
 3714            name: Some(server.name()),
 3715            message: proto::update_language_server::Variant::MetadataUpdated(
 3716                proto::ServerMetadataUpdated {
 3717                    capabilities: Some(capabilities),
 3718                    binary: Some(proto::LanguageServerBinaryInfo {
 3719                        path: server.binary().path.to_string_lossy().into_owned(),
 3720                        arguments: server
 3721                            .binary()
 3722                            .arguments
 3723                            .iter()
 3724                            .map(|arg| arg.to_string_lossy().into_owned())
 3725                            .collect(),
 3726                    }),
 3727                    configuration: serde_json::to_string(server.configuration()).ok(),
 3728                    workspace_folders: server
 3729                        .workspace_folders()
 3730                        .iter()
 3731                        .map(|uri| uri.to_string())
 3732                        .collect(),
 3733                },
 3734            ),
 3735        });
 3736    }
 3737}
 3738
 3739#[derive(Debug)]
 3740pub struct FormattableBuffer {
 3741    handle: Entity<Buffer>,
 3742    abs_path: Option<PathBuf>,
 3743    env: Option<HashMap<String, String>>,
 3744    ranges: Option<Vec<Range<Anchor>>>,
 3745}
 3746
 3747pub struct RemoteLspStore {
 3748    upstream_client: Option<AnyProtoClient>,
 3749    upstream_project_id: u64,
 3750}
 3751
 3752pub(crate) enum LspStoreMode {
 3753    Local(LocalLspStore),   // ssh host and collab host
 3754    Remote(RemoteLspStore), // collab guest
 3755}
 3756
 3757impl LspStoreMode {
 3758    fn is_local(&self) -> bool {
 3759        matches!(self, LspStoreMode::Local(_))
 3760    }
 3761}
 3762
 3763pub struct LspStore {
 3764    mode: LspStoreMode,
 3765    last_formatting_failure: Option<String>,
 3766    downstream_client: Option<(AnyProtoClient, u64)>,
 3767    nonce: u128,
 3768    buffer_store: Entity<BufferStore>,
 3769    worktree_store: Entity<WorktreeStore>,
 3770    pub languages: Arc<LanguageRegistry>,
 3771    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3772    active_entry: Option<ProjectEntryId>,
 3773    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3774    _maintain_buffer_languages: Task<()>,
 3775    diagnostic_summaries:
 3776        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3777    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3778    lsp_data: HashMap<BufferId, BufferLspData>,
 3779    next_hint_id: Arc<AtomicUsize>,
 3780}
 3781
 3782#[derive(Debug)]
 3783pub struct BufferLspData {
 3784    buffer_version: Global,
 3785    document_colors: Option<DocumentColorData>,
 3786    code_lens: Option<CodeLensData>,
 3787    inlay_hints: BufferInlayHints,
 3788    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3789    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3790}
 3791
 3792#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3793struct LspKey {
 3794    request_type: TypeId,
 3795    server_queried: Option<LanguageServerId>,
 3796}
 3797
 3798impl BufferLspData {
 3799    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3800        Self {
 3801            buffer_version: buffer.read(cx).version(),
 3802            document_colors: None,
 3803            code_lens: None,
 3804            inlay_hints: BufferInlayHints::new(buffer, cx),
 3805            lsp_requests: HashMap::default(),
 3806            chunk_lsp_requests: HashMap::default(),
 3807        }
 3808    }
 3809
 3810    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3811        if let Some(document_colors) = &mut self.document_colors {
 3812            document_colors.colors.remove(&for_server);
 3813            document_colors.cache_version += 1;
 3814        }
 3815
 3816        if let Some(code_lens) = &mut self.code_lens {
 3817            code_lens.lens.remove(&for_server);
 3818        }
 3819
 3820        self.inlay_hints.remove_server_data(for_server);
 3821    }
 3822
 3823    #[cfg(any(test, feature = "test-support"))]
 3824    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3825        &self.inlay_hints
 3826    }
 3827}
 3828
 3829#[derive(Debug, Default, Clone)]
 3830pub struct DocumentColors {
 3831    pub colors: HashSet<DocumentColor>,
 3832    pub cache_version: Option<usize>,
 3833}
 3834
 3835type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3836type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3837
 3838#[derive(Debug, Default)]
 3839struct DocumentColorData {
 3840    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3841    cache_version: usize,
 3842    colors_update: Option<(Global, DocumentColorTask)>,
 3843}
 3844
 3845#[derive(Debug, Default)]
 3846struct CodeLensData {
 3847    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3848    update: Option<(Global, CodeLensTask)>,
 3849}
 3850
 3851#[derive(Debug)]
 3852pub enum LspStoreEvent {
 3853    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3854    LanguageServerRemoved(LanguageServerId),
 3855    LanguageServerUpdate {
 3856        language_server_id: LanguageServerId,
 3857        name: Option<LanguageServerName>,
 3858        message: proto::update_language_server::Variant,
 3859    },
 3860    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3861    LanguageServerPrompt(LanguageServerPromptRequest),
 3862    LanguageDetected {
 3863        buffer: Entity<Buffer>,
 3864        new_language: Option<Arc<Language>>,
 3865    },
 3866    Notification(String),
 3867    RefreshInlayHints {
 3868        server_id: LanguageServerId,
 3869        request_id: Option<usize>,
 3870    },
 3871    RefreshCodeLens,
 3872    DiagnosticsUpdated {
 3873        server_id: LanguageServerId,
 3874        paths: Vec<ProjectPath>,
 3875    },
 3876    DiskBasedDiagnosticsStarted {
 3877        language_server_id: LanguageServerId,
 3878    },
 3879    DiskBasedDiagnosticsFinished {
 3880        language_server_id: LanguageServerId,
 3881    },
 3882    SnippetEdit {
 3883        buffer_id: BufferId,
 3884        edits: Vec<(lsp::Range, Snippet)>,
 3885        most_recent_edit: clock::Lamport,
 3886    },
 3887    WorkspaceEditApplied(ProjectTransaction),
 3888}
 3889
 3890#[derive(Clone, Debug, Serialize)]
 3891pub struct LanguageServerStatus {
 3892    pub name: LanguageServerName,
 3893    pub server_version: Option<SharedString>,
 3894    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3895    pub has_pending_diagnostic_updates: bool,
 3896    pub progress_tokens: HashSet<ProgressToken>,
 3897    pub worktree: Option<WorktreeId>,
 3898    pub binary: Option<LanguageServerBinary>,
 3899    pub configuration: Option<Value>,
 3900    pub workspace_folders: BTreeSet<Uri>,
 3901}
 3902
 3903#[derive(Clone, Debug)]
 3904struct CoreSymbol {
 3905    pub language_server_name: LanguageServerName,
 3906    pub source_worktree_id: WorktreeId,
 3907    pub source_language_server_id: LanguageServerId,
 3908    pub path: SymbolLocation,
 3909    pub name: String,
 3910    pub kind: lsp::SymbolKind,
 3911    pub range: Range<Unclipped<PointUtf16>>,
 3912}
 3913
 3914#[derive(Clone, Debug, PartialEq, Eq)]
 3915pub enum SymbolLocation {
 3916    InProject(ProjectPath),
 3917    OutsideProject {
 3918        abs_path: Arc<Path>,
 3919        signature: [u8; 32],
 3920    },
 3921}
 3922
 3923impl SymbolLocation {
 3924    fn file_name(&self) -> Option<&str> {
 3925        match self {
 3926            Self::InProject(path) => path.path.file_name(),
 3927            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3928        }
 3929    }
 3930}
 3931
 3932impl LspStore {
 3933    pub fn init(client: &AnyProtoClient) {
 3934        client.add_entity_request_handler(Self::handle_lsp_query);
 3935        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3936        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3937        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3938        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3939        client.add_entity_message_handler(Self::handle_start_language_server);
 3940        client.add_entity_message_handler(Self::handle_update_language_server);
 3941        client.add_entity_message_handler(Self::handle_language_server_log);
 3942        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3943        client.add_entity_request_handler(Self::handle_format_buffers);
 3944        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3945        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3946        client.add_entity_request_handler(Self::handle_apply_code_action);
 3947        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3948        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3949        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3950        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3951        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3952        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3953        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3954        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3955        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3956        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3957        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3958        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3959        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3960        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3961        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3962        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3963        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3964
 3965        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3966        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3967        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3968        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3969        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3970        client.add_entity_request_handler(
 3971            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3972        );
 3973        client.add_entity_request_handler(
 3974            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3975        );
 3976        client.add_entity_request_handler(
 3977            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3978        );
 3979    }
 3980
 3981    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3982        match &self.mode {
 3983            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3984            _ => None,
 3985        }
 3986    }
 3987
 3988    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3989        match &self.mode {
 3990            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3991            _ => None,
 3992        }
 3993    }
 3994
 3995    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3996        match &mut self.mode {
 3997            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3998            _ => None,
 3999        }
 4000    }
 4001
 4002    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4003        match &self.mode {
 4004            LspStoreMode::Remote(RemoteLspStore {
 4005                upstream_client: Some(upstream_client),
 4006                upstream_project_id,
 4007                ..
 4008            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4009
 4010            LspStoreMode::Remote(RemoteLspStore {
 4011                upstream_client: None,
 4012                ..
 4013            }) => None,
 4014            LspStoreMode::Local(_) => None,
 4015        }
 4016    }
 4017
 4018    pub fn new_local(
 4019        buffer_store: Entity<BufferStore>,
 4020        worktree_store: Entity<WorktreeStore>,
 4021        prettier_store: Entity<PrettierStore>,
 4022        toolchain_store: Entity<LocalToolchainStore>,
 4023        environment: Entity<ProjectEnvironment>,
 4024        manifest_tree: Entity<ManifestTree>,
 4025        languages: Arc<LanguageRegistry>,
 4026        http_client: Arc<dyn HttpClient>,
 4027        fs: Arc<dyn Fs>,
 4028        cx: &mut Context<Self>,
 4029    ) -> Self {
 4030        let yarn = YarnPathStore::new(fs.clone(), cx);
 4031        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4032            .detach();
 4033        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4034            .detach();
 4035        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4036            .detach();
 4037        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4038            .detach();
 4039        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4040            .detach();
 4041        subscribe_to_binary_statuses(&languages, cx).detach();
 4042
 4043        let _maintain_workspace_config = {
 4044            let (sender, receiver) = watch::channel();
 4045            (Self::maintain_workspace_config(receiver, cx), sender)
 4046        };
 4047
 4048        Self {
 4049            mode: LspStoreMode::Local(LocalLspStore {
 4050                weak: cx.weak_entity(),
 4051                worktree_store: worktree_store.clone(),
 4052
 4053                supplementary_language_servers: Default::default(),
 4054                languages: languages.clone(),
 4055                language_server_ids: Default::default(),
 4056                language_servers: Default::default(),
 4057                last_workspace_edits_by_language_server: Default::default(),
 4058                language_server_watched_paths: Default::default(),
 4059                language_server_paths_watched_for_rename: Default::default(),
 4060                language_server_dynamic_registrations: Default::default(),
 4061                buffers_being_formatted: Default::default(),
 4062                buffer_snapshots: Default::default(),
 4063                prettier_store,
 4064                environment,
 4065                http_client,
 4066                fs,
 4067                yarn,
 4068                next_diagnostic_group_id: Default::default(),
 4069                diagnostics: Default::default(),
 4070                _subscription: cx.on_app_quit(|this, cx| {
 4071                    this.as_local_mut()
 4072                        .unwrap()
 4073                        .shutdown_language_servers_on_quit(cx)
 4074                }),
 4075                lsp_tree: LanguageServerTree::new(
 4076                    manifest_tree,
 4077                    languages.clone(),
 4078                    toolchain_store.clone(),
 4079                ),
 4080                toolchain_store,
 4081                registered_buffers: HashMap::default(),
 4082                buffers_opened_in_servers: HashMap::default(),
 4083                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4084                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4085                restricted_worktrees_tasks: HashMap::default(),
 4086                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4087                    .manifest_file_names(),
 4088            }),
 4089            last_formatting_failure: None,
 4090            downstream_client: None,
 4091            buffer_store,
 4092            worktree_store,
 4093            languages: languages.clone(),
 4094            language_server_statuses: Default::default(),
 4095            nonce: StdRng::from_os_rng().random(),
 4096            diagnostic_summaries: HashMap::default(),
 4097            lsp_server_capabilities: HashMap::default(),
 4098            lsp_data: HashMap::default(),
 4099            next_hint_id: Arc::default(),
 4100            active_entry: None,
 4101            _maintain_workspace_config,
 4102            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4103        }
 4104    }
 4105
 4106    fn send_lsp_proto_request<R: LspCommand>(
 4107        &self,
 4108        buffer: Entity<Buffer>,
 4109        client: AnyProtoClient,
 4110        upstream_project_id: u64,
 4111        request: R,
 4112        cx: &mut Context<LspStore>,
 4113    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4114        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4115            return Task::ready(Ok(R::Response::default()));
 4116        }
 4117        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4118        cx.spawn(async move |this, cx| {
 4119            let response = client.request(message).await?;
 4120            let this = this.upgrade().context("project dropped")?;
 4121            request
 4122                .response_from_proto(response, this, buffer, cx.clone())
 4123                .await
 4124        })
 4125    }
 4126
 4127    pub(super) fn new_remote(
 4128        buffer_store: Entity<BufferStore>,
 4129        worktree_store: Entity<WorktreeStore>,
 4130        languages: Arc<LanguageRegistry>,
 4131        upstream_client: AnyProtoClient,
 4132        project_id: u64,
 4133        cx: &mut Context<Self>,
 4134    ) -> Self {
 4135        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4136            .detach();
 4137        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4138            .detach();
 4139        subscribe_to_binary_statuses(&languages, cx).detach();
 4140        let _maintain_workspace_config = {
 4141            let (sender, receiver) = watch::channel();
 4142            (Self::maintain_workspace_config(receiver, cx), sender)
 4143        };
 4144        Self {
 4145            mode: LspStoreMode::Remote(RemoteLspStore {
 4146                upstream_client: Some(upstream_client),
 4147                upstream_project_id: project_id,
 4148            }),
 4149            downstream_client: None,
 4150            last_formatting_failure: None,
 4151            buffer_store,
 4152            worktree_store,
 4153            languages: languages.clone(),
 4154            language_server_statuses: Default::default(),
 4155            nonce: StdRng::from_os_rng().random(),
 4156            diagnostic_summaries: HashMap::default(),
 4157            lsp_server_capabilities: HashMap::default(),
 4158            next_hint_id: Arc::default(),
 4159            lsp_data: HashMap::default(),
 4160            active_entry: None,
 4161
 4162            _maintain_workspace_config,
 4163            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4164        }
 4165    }
 4166
 4167    fn on_buffer_store_event(
 4168        &mut self,
 4169        _: Entity<BufferStore>,
 4170        event: &BufferStoreEvent,
 4171        cx: &mut Context<Self>,
 4172    ) {
 4173        match event {
 4174            BufferStoreEvent::BufferAdded(buffer) => {
 4175                self.on_buffer_added(buffer, cx).log_err();
 4176            }
 4177            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4178                let buffer_id = buffer.read(cx).remote_id();
 4179                if let Some(local) = self.as_local_mut()
 4180                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4181                {
 4182                    local.reset_buffer(buffer, old_file, cx);
 4183
 4184                    if local.registered_buffers.contains_key(&buffer_id) {
 4185                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4186                    }
 4187                }
 4188
 4189                self.detect_language_for_buffer(buffer, cx);
 4190                if let Some(local) = self.as_local_mut() {
 4191                    local.initialize_buffer(buffer, cx);
 4192                    if local.registered_buffers.contains_key(&buffer_id) {
 4193                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4194                    }
 4195                }
 4196            }
 4197            _ => {}
 4198        }
 4199    }
 4200
 4201    fn on_worktree_store_event(
 4202        &mut self,
 4203        _: Entity<WorktreeStore>,
 4204        event: &WorktreeStoreEvent,
 4205        cx: &mut Context<Self>,
 4206    ) {
 4207        match event {
 4208            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4209                if !worktree.read(cx).is_local() {
 4210                    return;
 4211                }
 4212                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4213                    worktree::Event::UpdatedEntries(changes) => {
 4214                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4215                    }
 4216                    worktree::Event::UpdatedGitRepositories(_)
 4217                    | worktree::Event::DeletedEntry(_) => {}
 4218                })
 4219                .detach()
 4220            }
 4221            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4222            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4223                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4224            }
 4225            WorktreeStoreEvent::WorktreeReleased(..)
 4226            | WorktreeStoreEvent::WorktreeOrderChanged
 4227            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4228            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4229            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4230        }
 4231    }
 4232
 4233    fn on_prettier_store_event(
 4234        &mut self,
 4235        _: Entity<PrettierStore>,
 4236        event: &PrettierStoreEvent,
 4237        cx: &mut Context<Self>,
 4238    ) {
 4239        match event {
 4240            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4241                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4242            }
 4243            PrettierStoreEvent::LanguageServerAdded {
 4244                new_server_id,
 4245                name,
 4246                prettier_server,
 4247            } => {
 4248                self.register_supplementary_language_server(
 4249                    *new_server_id,
 4250                    name.clone(),
 4251                    prettier_server.clone(),
 4252                    cx,
 4253                );
 4254            }
 4255        }
 4256    }
 4257
 4258    fn on_toolchain_store_event(
 4259        &mut self,
 4260        _: Entity<LocalToolchainStore>,
 4261        event: &ToolchainStoreEvent,
 4262        _: &mut Context<Self>,
 4263    ) {
 4264        if let ToolchainStoreEvent::ToolchainActivated = event {
 4265            self.request_workspace_config_refresh()
 4266        }
 4267    }
 4268
 4269    fn request_workspace_config_refresh(&mut self) {
 4270        *self._maintain_workspace_config.1.borrow_mut() = ();
 4271    }
 4272
 4273    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4274        self.as_local().map(|local| local.prettier_store.clone())
 4275    }
 4276
 4277    fn on_buffer_event(
 4278        &mut self,
 4279        buffer: Entity<Buffer>,
 4280        event: &language::BufferEvent,
 4281        cx: &mut Context<Self>,
 4282    ) {
 4283        match event {
 4284            language::BufferEvent::Edited => {
 4285                self.on_buffer_edited(buffer, cx);
 4286            }
 4287
 4288            language::BufferEvent::Saved => {
 4289                self.on_buffer_saved(buffer, cx);
 4290            }
 4291
 4292            _ => {}
 4293        }
 4294    }
 4295
 4296    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4297        buffer
 4298            .read(cx)
 4299            .set_language_registry(self.languages.clone());
 4300
 4301        cx.subscribe(buffer, |this, buffer, event, cx| {
 4302            this.on_buffer_event(buffer, event, cx);
 4303        })
 4304        .detach();
 4305
 4306        self.detect_language_for_buffer(buffer, cx);
 4307        if let Some(local) = self.as_local_mut() {
 4308            local.initialize_buffer(buffer, cx);
 4309        }
 4310
 4311        Ok(())
 4312    }
 4313
 4314    pub(crate) fn register_buffer_with_language_servers(
 4315        &mut self,
 4316        buffer: &Entity<Buffer>,
 4317        only_register_servers: HashSet<LanguageServerSelector>,
 4318        ignore_refcounts: bool,
 4319        cx: &mut Context<Self>,
 4320    ) -> OpenLspBufferHandle {
 4321        let buffer_id = buffer.read(cx).remote_id();
 4322        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4323        if let Some(local) = self.as_local_mut() {
 4324            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4325            if !ignore_refcounts {
 4326                *refcount += 1;
 4327            }
 4328
 4329            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4330            // 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
 4331            // 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
 4332            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4333            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4334                return handle;
 4335            };
 4336            if !file.is_local() {
 4337                return handle;
 4338            }
 4339
 4340            if ignore_refcounts || *refcount == 1 {
 4341                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4342            }
 4343            if !ignore_refcounts {
 4344                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4345                    let refcount = {
 4346                        let local = lsp_store.as_local_mut().unwrap();
 4347                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4348                            debug_panic!("bad refcounting");
 4349                            return;
 4350                        };
 4351
 4352                        *refcount -= 1;
 4353                        *refcount
 4354                    };
 4355                    if refcount == 0 {
 4356                        lsp_store.lsp_data.remove(&buffer_id);
 4357                        let local = lsp_store.as_local_mut().unwrap();
 4358                        local.registered_buffers.remove(&buffer_id);
 4359
 4360                        local.buffers_opened_in_servers.remove(&buffer_id);
 4361                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4362                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4363
 4364                            let buffer_abs_path = file.abs_path(cx);
 4365                            for (_, buffer_pull_diagnostics_result_ids) in
 4366                                &mut local.buffer_pull_diagnostics_result_ids
 4367                            {
 4368                                buffer_pull_diagnostics_result_ids.retain(
 4369                                    |_, buffer_result_ids| {
 4370                                        buffer_result_ids.remove(&buffer_abs_path);
 4371                                        !buffer_result_ids.is_empty()
 4372                                    },
 4373                                );
 4374                            }
 4375
 4376                            let diagnostic_updates = local
 4377                                .language_servers
 4378                                .keys()
 4379                                .cloned()
 4380                                .map(|server_id| DocumentDiagnosticsUpdate {
 4381                                    diagnostics: DocumentDiagnostics {
 4382                                        document_abs_path: buffer_abs_path.clone(),
 4383                                        version: None,
 4384                                        diagnostics: Vec::new(),
 4385                                    },
 4386                                    result_id: None,
 4387                                    registration_id: None,
 4388                                    server_id: server_id,
 4389                                    disk_based_sources: Cow::Borrowed(&[]),
 4390                                })
 4391                                .collect::<Vec<_>>();
 4392
 4393                            lsp_store
 4394                                .merge_diagnostic_entries(
 4395                                    diagnostic_updates,
 4396                                    |_, diagnostic, _| {
 4397                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4398                                    },
 4399                                    cx,
 4400                                )
 4401                                .context("Clearing diagnostics for the closed buffer")
 4402                                .log_err();
 4403                        }
 4404                    }
 4405                })
 4406                .detach();
 4407            }
 4408        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4409            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4410            cx.background_spawn(async move {
 4411                upstream_client
 4412                    .request(proto::RegisterBufferWithLanguageServers {
 4413                        project_id: upstream_project_id,
 4414                        buffer_id,
 4415                        only_servers: only_register_servers
 4416                            .into_iter()
 4417                            .map(|selector| {
 4418                                let selector = match selector {
 4419                                    LanguageServerSelector::Id(language_server_id) => {
 4420                                        proto::language_server_selector::Selector::ServerId(
 4421                                            language_server_id.to_proto(),
 4422                                        )
 4423                                    }
 4424                                    LanguageServerSelector::Name(language_server_name) => {
 4425                                        proto::language_server_selector::Selector::Name(
 4426                                            language_server_name.to_string(),
 4427                                        )
 4428                                    }
 4429                                };
 4430                                proto::LanguageServerSelector {
 4431                                    selector: Some(selector),
 4432                                }
 4433                            })
 4434                            .collect(),
 4435                    })
 4436                    .await
 4437            })
 4438            .detach();
 4439        } else {
 4440            // Our remote connection got closed
 4441        }
 4442        handle
 4443    }
 4444
 4445    fn maintain_buffer_languages(
 4446        languages: Arc<LanguageRegistry>,
 4447        cx: &mut Context<Self>,
 4448    ) -> Task<()> {
 4449        let mut subscription = languages.subscribe();
 4450        let mut prev_reload_count = languages.reload_count();
 4451        cx.spawn(async move |this, cx| {
 4452            while let Some(()) = subscription.next().await {
 4453                if let Some(this) = this.upgrade() {
 4454                    // If the language registry has been reloaded, then remove and
 4455                    // re-assign the languages on all open buffers.
 4456                    let reload_count = languages.reload_count();
 4457                    if reload_count > prev_reload_count {
 4458                        prev_reload_count = reload_count;
 4459                        this.update(cx, |this, cx| {
 4460                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4461                                for buffer in buffer_store.buffers() {
 4462                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4463                                    {
 4464                                        buffer.update(cx, |buffer, cx| {
 4465                                            buffer.set_language_async(None, cx)
 4466                                        });
 4467                                        if let Some(local) = this.as_local_mut() {
 4468                                            local.reset_buffer(&buffer, &f, cx);
 4469
 4470                                            if local
 4471                                                .registered_buffers
 4472                                                .contains_key(&buffer.read(cx).remote_id())
 4473                                                && let Some(file_url) =
 4474                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4475                                            {
 4476                                                local.unregister_buffer_from_language_servers(
 4477                                                    &buffer, &file_url, cx,
 4478                                                );
 4479                                            }
 4480                                        }
 4481                                    }
 4482                                }
 4483                            });
 4484                        })
 4485                        .ok();
 4486                    }
 4487
 4488                    this.update(cx, |this, cx| {
 4489                        let mut plain_text_buffers = Vec::new();
 4490                        let mut buffers_with_unknown_injections = Vec::new();
 4491                        for handle in this.buffer_store.read(cx).buffers() {
 4492                            let buffer = handle.read(cx);
 4493                            if buffer.language().is_none()
 4494                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4495                            {
 4496                                plain_text_buffers.push(handle);
 4497                            } else if buffer.contains_unknown_injections() {
 4498                                buffers_with_unknown_injections.push(handle);
 4499                            }
 4500                        }
 4501
 4502                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4503                        // and reused later in the invisible worktrees.
 4504                        plain_text_buffers.sort_by_key(|buffer| {
 4505                            Reverse(
 4506                                File::from_dyn(buffer.read(cx).file())
 4507                                    .map(|file| file.worktree.read(cx).is_visible()),
 4508                            )
 4509                        });
 4510
 4511                        for buffer in plain_text_buffers {
 4512                            this.detect_language_for_buffer(&buffer, cx);
 4513                            if let Some(local) = this.as_local_mut() {
 4514                                local.initialize_buffer(&buffer, cx);
 4515                                if local
 4516                                    .registered_buffers
 4517                                    .contains_key(&buffer.read(cx).remote_id())
 4518                                {
 4519                                    local.register_buffer_with_language_servers(
 4520                                        &buffer,
 4521                                        HashSet::default(),
 4522                                        cx,
 4523                                    );
 4524                                }
 4525                            }
 4526                        }
 4527
 4528                        for buffer in buffers_with_unknown_injections {
 4529                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4530                        }
 4531                    })
 4532                    .ok();
 4533                }
 4534            }
 4535        })
 4536    }
 4537
 4538    fn detect_language_for_buffer(
 4539        &mut self,
 4540        buffer_handle: &Entity<Buffer>,
 4541        cx: &mut Context<Self>,
 4542    ) -> Option<language::AvailableLanguage> {
 4543        // If the buffer has a language, set it and start the language server if we haven't already.
 4544        let buffer = buffer_handle.read(cx);
 4545        let file = buffer.file()?;
 4546
 4547        let content = buffer.as_rope();
 4548        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4549        if let Some(available_language) = &available_language {
 4550            if let Some(Ok(Ok(new_language))) = self
 4551                .languages
 4552                .load_language(available_language)
 4553                .now_or_never()
 4554            {
 4555                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4556            }
 4557        } else {
 4558            cx.emit(LspStoreEvent::LanguageDetected {
 4559                buffer: buffer_handle.clone(),
 4560                new_language: None,
 4561            });
 4562        }
 4563
 4564        available_language
 4565    }
 4566
 4567    pub(crate) fn set_language_for_buffer(
 4568        &mut self,
 4569        buffer_entity: &Entity<Buffer>,
 4570        new_language: Arc<Language>,
 4571        cx: &mut Context<Self>,
 4572    ) {
 4573        let buffer = buffer_entity.read(cx);
 4574        let buffer_file = buffer.file().cloned();
 4575        let buffer_id = buffer.remote_id();
 4576        if let Some(local_store) = self.as_local_mut()
 4577            && local_store.registered_buffers.contains_key(&buffer_id)
 4578            && let Some(abs_path) =
 4579                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4580            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4581        {
 4582            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4583        }
 4584        buffer_entity.update(cx, |buffer, cx| {
 4585            if buffer
 4586                .language()
 4587                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4588            {
 4589                buffer.set_language_async(Some(new_language.clone()), cx);
 4590            }
 4591        });
 4592
 4593        let settings =
 4594            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4595        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4596
 4597        let worktree_id = if let Some(file) = buffer_file {
 4598            let worktree = file.worktree.clone();
 4599
 4600            if let Some(local) = self.as_local_mut()
 4601                && local.registered_buffers.contains_key(&buffer_id)
 4602            {
 4603                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4604            }
 4605            Some(worktree.read(cx).id())
 4606        } else {
 4607            None
 4608        };
 4609
 4610        if settings.prettier.allowed
 4611            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4612        {
 4613            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4614            if let Some(prettier_store) = prettier_store {
 4615                prettier_store.update(cx, |prettier_store, cx| {
 4616                    prettier_store.install_default_prettier(
 4617                        worktree_id,
 4618                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4619                        cx,
 4620                    )
 4621                })
 4622            }
 4623        }
 4624
 4625        cx.emit(LspStoreEvent::LanguageDetected {
 4626            buffer: buffer_entity.clone(),
 4627            new_language: Some(new_language),
 4628        })
 4629    }
 4630
 4631    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4632        self.buffer_store.clone()
 4633    }
 4634
 4635    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4636        self.active_entry = active_entry;
 4637    }
 4638
 4639    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4640        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4641            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4642        {
 4643            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4644                summaries
 4645                    .iter()
 4646                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4647            });
 4648            if let Some(summary) = summaries.next() {
 4649                client
 4650                    .send(proto::UpdateDiagnosticSummary {
 4651                        project_id: downstream_project_id,
 4652                        worktree_id: worktree.id().to_proto(),
 4653                        summary: Some(summary),
 4654                        more_summaries: summaries.collect(),
 4655                    })
 4656                    .log_err();
 4657            }
 4658        }
 4659    }
 4660
 4661    fn is_capable_for_proto_request<R>(
 4662        &self,
 4663        buffer: &Entity<Buffer>,
 4664        request: &R,
 4665        cx: &App,
 4666    ) -> bool
 4667    where
 4668        R: LspCommand,
 4669    {
 4670        self.check_if_capable_for_proto_request(
 4671            buffer,
 4672            |capabilities| {
 4673                request.check_capabilities(AdapterServerCapabilities {
 4674                    server_capabilities: capabilities.clone(),
 4675                    code_action_kinds: None,
 4676                })
 4677            },
 4678            cx,
 4679        )
 4680    }
 4681
 4682    fn check_if_capable_for_proto_request<F>(
 4683        &self,
 4684        buffer: &Entity<Buffer>,
 4685        check: F,
 4686        cx: &App,
 4687    ) -> bool
 4688    where
 4689        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4690    {
 4691        let Some(language) = buffer.read(cx).language().cloned() else {
 4692            return false;
 4693        };
 4694        let registered_language_servers = self
 4695            .languages
 4696            .lsp_adapters(&language.name())
 4697            .into_iter()
 4698            .map(|lsp_adapter| lsp_adapter.name())
 4699            .collect::<HashSet<_>>();
 4700        self.language_server_statuses
 4701            .iter()
 4702            .filter_map(|(server_id, server_status)| {
 4703                // Include servers that are either registered for this language OR
 4704                // available to be loaded (for SSH remote mode where adapters like
 4705                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4706                // but only loaded on the server side)
 4707                let is_relevant = registered_language_servers.contains(&server_status.name)
 4708                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4709                is_relevant.then_some(server_id)
 4710            })
 4711            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4712            .any(check)
 4713    }
 4714
 4715    fn all_capable_for_proto_request<F>(
 4716        &self,
 4717        buffer: &Entity<Buffer>,
 4718        mut check: F,
 4719        cx: &App,
 4720    ) -> Vec<lsp::LanguageServerId>
 4721    where
 4722        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4723    {
 4724        let Some(language) = buffer.read(cx).language().cloned() else {
 4725            return Vec::default();
 4726        };
 4727        let registered_language_servers = self
 4728            .languages
 4729            .lsp_adapters(&language.name())
 4730            .into_iter()
 4731            .map(|lsp_adapter| lsp_adapter.name())
 4732            .collect::<HashSet<_>>();
 4733        self.language_server_statuses
 4734            .iter()
 4735            .filter_map(|(server_id, server_status)| {
 4736                // Include servers that are either registered for this language OR
 4737                // available to be loaded (for SSH remote mode where adapters like
 4738                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4739                // but only loaded on the server side)
 4740                let is_relevant = registered_language_servers.contains(&server_status.name)
 4741                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4742                is_relevant.then_some((server_id, &server_status.name))
 4743            })
 4744            .filter_map(|(server_id, server_name)| {
 4745                self.lsp_server_capabilities
 4746                    .get(server_id)
 4747                    .map(|c| (server_id, server_name, c))
 4748            })
 4749            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4750            .map(|(server_id, _, _)| *server_id)
 4751            .collect()
 4752    }
 4753
 4754    pub fn request_lsp<R>(
 4755        &mut self,
 4756        buffer: Entity<Buffer>,
 4757        server: LanguageServerToQuery,
 4758        request: R,
 4759        cx: &mut Context<Self>,
 4760    ) -> Task<Result<R::Response>>
 4761    where
 4762        R: LspCommand,
 4763        <R::LspRequest as lsp::request::Request>::Result: Send,
 4764        <R::LspRequest as lsp::request::Request>::Params: Send,
 4765    {
 4766        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4767            return self.send_lsp_proto_request(
 4768                buffer,
 4769                upstream_client,
 4770                upstream_project_id,
 4771                request,
 4772                cx,
 4773            );
 4774        }
 4775
 4776        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4777            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4778                local
 4779                    .language_servers_for_buffer(buffer, cx)
 4780                    .find(|(_, server)| {
 4781                        request.check_capabilities(server.adapter_server_capabilities())
 4782                    })
 4783                    .map(|(_, server)| server.clone())
 4784            }),
 4785            LanguageServerToQuery::Other(id) => self
 4786                .language_server_for_local_buffer(buffer, id, cx)
 4787                .and_then(|(_, server)| {
 4788                    request
 4789                        .check_capabilities(server.adapter_server_capabilities())
 4790                        .then(|| Arc::clone(server))
 4791                }),
 4792        }) else {
 4793            return Task::ready(Ok(Default::default()));
 4794        };
 4795
 4796        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4797
 4798        let Some(file) = file else {
 4799            return Task::ready(Ok(Default::default()));
 4800        };
 4801
 4802        let lsp_params = match request.to_lsp_params_or_response(
 4803            &file.abs_path(cx),
 4804            buffer.read(cx),
 4805            &language_server,
 4806            cx,
 4807        ) {
 4808            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4809            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4810            Err(err) => {
 4811                let message = format!(
 4812                    "{} via {} failed: {}",
 4813                    request.display_name(),
 4814                    language_server.name(),
 4815                    err
 4816                );
 4817                // rust-analyzer likes to error with this when its still loading up
 4818                if !message.ends_with("content modified") {
 4819                    log::warn!("{message}");
 4820                }
 4821                return Task::ready(Err(anyhow!(message)));
 4822            }
 4823        };
 4824
 4825        let status = request.status();
 4826        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4827            return Task::ready(Ok(Default::default()));
 4828        }
 4829        cx.spawn(async move |this, cx| {
 4830            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4831
 4832            let id = lsp_request.id();
 4833            let _cleanup = if status.is_some() {
 4834                cx.update(|cx| {
 4835                    this.update(cx, |this, cx| {
 4836                        this.on_lsp_work_start(
 4837                            language_server.server_id(),
 4838                            ProgressToken::Number(id),
 4839                            LanguageServerProgress {
 4840                                is_disk_based_diagnostics_progress: false,
 4841                                is_cancellable: false,
 4842                                title: None,
 4843                                message: status.clone(),
 4844                                percentage: None,
 4845                                last_update_at: cx.background_executor().now(),
 4846                            },
 4847                            cx,
 4848                        );
 4849                    })
 4850                })
 4851                .log_err();
 4852
 4853                Some(defer(|| {
 4854                    cx.update(|cx| {
 4855                        this.update(cx, |this, cx| {
 4856                            this.on_lsp_work_end(
 4857                                language_server.server_id(),
 4858                                ProgressToken::Number(id),
 4859                                cx,
 4860                            );
 4861                        })
 4862                    })
 4863                    .log_err();
 4864                }))
 4865            } else {
 4866                None
 4867            };
 4868
 4869            let result = lsp_request.await.into_response();
 4870
 4871            let response = result.map_err(|err| {
 4872                let message = format!(
 4873                    "{} via {} failed: {}",
 4874                    request.display_name(),
 4875                    language_server.name(),
 4876                    err
 4877                );
 4878                // rust-analyzer likes to error with this when its still loading up
 4879                if !message.ends_with("content modified") {
 4880                    log::warn!("{message}");
 4881                }
 4882                anyhow::anyhow!(message)
 4883            })?;
 4884
 4885            request
 4886                .response_from_lsp(
 4887                    response,
 4888                    this.upgrade().context("no app context")?,
 4889                    buffer,
 4890                    language_server.server_id(),
 4891                    cx.clone(),
 4892                )
 4893                .await
 4894        })
 4895    }
 4896
 4897    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4898        let mut language_formatters_to_check = Vec::new();
 4899        for buffer in self.buffer_store.read(cx).buffers() {
 4900            let buffer = buffer.read(cx);
 4901            let buffer_file = File::from_dyn(buffer.file());
 4902            let buffer_language = buffer.language();
 4903            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4904            if buffer_language.is_some() {
 4905                language_formatters_to_check.push((
 4906                    buffer_file.map(|f| f.worktree_id(cx)),
 4907                    settings.into_owned(),
 4908                ));
 4909            }
 4910        }
 4911
 4912        self.request_workspace_config_refresh();
 4913
 4914        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4915            prettier_store.update(cx, |prettier_store, cx| {
 4916                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4917            })
 4918        }
 4919
 4920        cx.notify();
 4921    }
 4922
 4923    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4924        let buffer_store = self.buffer_store.clone();
 4925        let Some(local) = self.as_local_mut() else {
 4926            return;
 4927        };
 4928        let mut adapters = BTreeMap::default();
 4929        let get_adapter = {
 4930            let languages = local.languages.clone();
 4931            let environment = local.environment.clone();
 4932            let weak = local.weak.clone();
 4933            let worktree_store = local.worktree_store.clone();
 4934            let http_client = local.http_client.clone();
 4935            let fs = local.fs.clone();
 4936            move |worktree_id, cx: &mut App| {
 4937                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4938                Some(LocalLspAdapterDelegate::new(
 4939                    languages.clone(),
 4940                    &environment,
 4941                    weak.clone(),
 4942                    &worktree,
 4943                    http_client.clone(),
 4944                    fs.clone(),
 4945                    cx,
 4946                ))
 4947            }
 4948        };
 4949
 4950        let mut messages_to_report = Vec::new();
 4951        let (new_tree, to_stop) = {
 4952            let mut rebase = local.lsp_tree.rebase();
 4953            let buffers = buffer_store
 4954                .read(cx)
 4955                .buffers()
 4956                .filter_map(|buffer| {
 4957                    let raw_buffer = buffer.read(cx);
 4958                    if !local
 4959                        .registered_buffers
 4960                        .contains_key(&raw_buffer.remote_id())
 4961                    {
 4962                        return None;
 4963                    }
 4964                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4965                    let language = raw_buffer.language().cloned()?;
 4966                    Some((file, language, raw_buffer.remote_id()))
 4967                })
 4968                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4969            for (file, language, buffer_id) in buffers {
 4970                let worktree_id = file.worktree_id(cx);
 4971                let Some(worktree) = local
 4972                    .worktree_store
 4973                    .read(cx)
 4974                    .worktree_for_id(worktree_id, cx)
 4975                else {
 4976                    continue;
 4977                };
 4978
 4979                if let Some((_, apply)) = local.reuse_existing_language_server(
 4980                    rebase.server_tree(),
 4981                    &worktree,
 4982                    &language.name(),
 4983                    cx,
 4984                ) {
 4985                    (apply)(rebase.server_tree());
 4986                } else if let Some(lsp_delegate) = adapters
 4987                    .entry(worktree_id)
 4988                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4989                    .clone()
 4990                {
 4991                    let delegate =
 4992                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4993                    let path = file
 4994                        .path()
 4995                        .parent()
 4996                        .map(Arc::from)
 4997                        .unwrap_or_else(|| file.path().clone());
 4998                    let worktree_path = ProjectPath { worktree_id, path };
 4999                    let abs_path = file.abs_path(cx);
 5000                    let nodes = rebase
 5001                        .walk(
 5002                            worktree_path,
 5003                            language.name(),
 5004                            language.manifest(),
 5005                            delegate.clone(),
 5006                            cx,
 5007                        )
 5008                        .collect::<Vec<_>>();
 5009                    for node in nodes {
 5010                        let server_id = node.server_id_or_init(|disposition| {
 5011                            let path = &disposition.path;
 5012                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5013                            let key = LanguageServerSeed {
 5014                                worktree_id,
 5015                                name: disposition.server_name.clone(),
 5016                                settings: disposition.settings.clone(),
 5017                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5018                                    path.worktree_id,
 5019                                    &path.path,
 5020                                    language.name(),
 5021                                ),
 5022                            };
 5023                            local.language_server_ids.remove(&key);
 5024
 5025                            let server_id = local.get_or_insert_language_server(
 5026                                &worktree,
 5027                                lsp_delegate.clone(),
 5028                                disposition,
 5029                                &language.name(),
 5030                                cx,
 5031                            );
 5032                            if let Some(state) = local.language_servers.get(&server_id)
 5033                                && let Ok(uri) = uri
 5034                            {
 5035                                state.add_workspace_folder(uri);
 5036                            };
 5037                            server_id
 5038                        });
 5039
 5040                        if let Some(language_server_id) = server_id {
 5041                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5042                                language_server_id,
 5043                                name: node.name(),
 5044                                message:
 5045                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5046                                        proto::RegisteredForBuffer {
 5047                                            buffer_abs_path: abs_path
 5048                                                .to_string_lossy()
 5049                                                .into_owned(),
 5050                                            buffer_id: buffer_id.to_proto(),
 5051                                        },
 5052                                    ),
 5053                            });
 5054                        }
 5055                    }
 5056                } else {
 5057                    continue;
 5058                }
 5059            }
 5060            rebase.finish()
 5061        };
 5062        for message in messages_to_report {
 5063            cx.emit(message);
 5064        }
 5065        local.lsp_tree = new_tree;
 5066        for (id, _) in to_stop {
 5067            self.stop_local_language_server(id, cx).detach();
 5068        }
 5069    }
 5070
 5071    pub fn apply_code_action(
 5072        &self,
 5073        buffer_handle: Entity<Buffer>,
 5074        mut action: CodeAction,
 5075        push_to_history: bool,
 5076        cx: &mut Context<Self>,
 5077    ) -> Task<Result<ProjectTransaction>> {
 5078        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5079            let request = proto::ApplyCodeAction {
 5080                project_id,
 5081                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5082                action: Some(Self::serialize_code_action(&action)),
 5083            };
 5084            let buffer_store = self.buffer_store();
 5085            cx.spawn(async move |_, cx| {
 5086                let response = upstream_client
 5087                    .request(request)
 5088                    .await?
 5089                    .transaction
 5090                    .context("missing transaction")?;
 5091
 5092                buffer_store
 5093                    .update(cx, |buffer_store, cx| {
 5094                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5095                    })?
 5096                    .await
 5097            })
 5098        } else if self.mode.is_local() {
 5099            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 5100                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5101                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 5102            }) else {
 5103                return Task::ready(Ok(ProjectTransaction::default()));
 5104            };
 5105            cx.spawn(async move |this,  cx| {
 5106                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 5107                    .await
 5108                    .context("resolving a code action")?;
 5109                if let Some(edit) = action.lsp_action.edit()
 5110                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5111                        return LocalLspStore::deserialize_workspace_edit(
 5112                            this.upgrade().context("no app present")?,
 5113                            edit.clone(),
 5114                            push_to_history,
 5115
 5116                            lang_server.clone(),
 5117                            cx,
 5118                        )
 5119                        .await;
 5120                    }
 5121
 5122                if let Some(command) = action.lsp_action.command() {
 5123                    let server_capabilities = lang_server.capabilities();
 5124                    let available_commands = server_capabilities
 5125                        .execute_command_provider
 5126                        .as_ref()
 5127                        .map(|options| options.commands.as_slice())
 5128                        .unwrap_or_default();
 5129                    if available_commands.contains(&command.command) {
 5130                        this.update(cx, |this, _| {
 5131                            this.as_local_mut()
 5132                                .unwrap()
 5133                                .last_workspace_edits_by_language_server
 5134                                .remove(&lang_server.server_id());
 5135                        })?;
 5136
 5137                        let _result = lang_server
 5138                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5139                                command: command.command.clone(),
 5140                                arguments: command.arguments.clone().unwrap_or_default(),
 5141                                ..lsp::ExecuteCommandParams::default()
 5142                            })
 5143                            .await.into_response()
 5144                            .context("execute command")?;
 5145
 5146                        return this.update(cx, |this, _| {
 5147                            this.as_local_mut()
 5148                                .unwrap()
 5149                                .last_workspace_edits_by_language_server
 5150                                .remove(&lang_server.server_id())
 5151                                .unwrap_or_default()
 5152                        });
 5153                    } else {
 5154                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5155                    }
 5156                }
 5157
 5158                Ok(ProjectTransaction::default())
 5159            })
 5160        } else {
 5161            Task::ready(Err(anyhow!("no upstream client and not local")))
 5162        }
 5163    }
 5164
 5165    pub fn apply_code_action_kind(
 5166        &mut self,
 5167        buffers: HashSet<Entity<Buffer>>,
 5168        kind: CodeActionKind,
 5169        push_to_history: bool,
 5170        cx: &mut Context<Self>,
 5171    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5172        if self.as_local().is_some() {
 5173            cx.spawn(async move |lsp_store, cx| {
 5174                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5175                let result = LocalLspStore::execute_code_action_kind_locally(
 5176                    lsp_store.clone(),
 5177                    buffers,
 5178                    kind,
 5179                    push_to_history,
 5180                    cx,
 5181                )
 5182                .await;
 5183                lsp_store.update(cx, |lsp_store, _| {
 5184                    lsp_store.update_last_formatting_failure(&result);
 5185                })?;
 5186                result
 5187            })
 5188        } else if let Some((client, project_id)) = self.upstream_client() {
 5189            let buffer_store = self.buffer_store();
 5190            cx.spawn(async move |lsp_store, cx| {
 5191                let result = client
 5192                    .request(proto::ApplyCodeActionKind {
 5193                        project_id,
 5194                        kind: kind.as_str().to_owned(),
 5195                        buffer_ids: buffers
 5196                            .iter()
 5197                            .map(|buffer| {
 5198                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5199                            })
 5200                            .collect::<Result<_>>()?,
 5201                    })
 5202                    .await
 5203                    .and_then(|result| result.transaction.context("missing transaction"));
 5204                lsp_store.update(cx, |lsp_store, _| {
 5205                    lsp_store.update_last_formatting_failure(&result);
 5206                })?;
 5207
 5208                let transaction_response = result?;
 5209                buffer_store
 5210                    .update(cx, |buffer_store, cx| {
 5211                        buffer_store.deserialize_project_transaction(
 5212                            transaction_response,
 5213                            push_to_history,
 5214                            cx,
 5215                        )
 5216                    })?
 5217                    .await
 5218            })
 5219        } else {
 5220            Task::ready(Ok(ProjectTransaction::default()))
 5221        }
 5222    }
 5223
 5224    pub fn resolved_hint(
 5225        &mut self,
 5226        buffer_id: BufferId,
 5227        id: InlayId,
 5228        cx: &mut Context<Self>,
 5229    ) -> Option<ResolvedHint> {
 5230        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5231
 5232        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5233        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5234        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5235        let (server_id, resolve_data) = match &hint.resolve_state {
 5236            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5237            ResolveState::Resolving => {
 5238                return Some(ResolvedHint::Resolving(
 5239                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5240                ));
 5241            }
 5242            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5243        };
 5244
 5245        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5246        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5247        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5248            id,
 5249            cx.spawn(async move |lsp_store, cx| {
 5250                let resolved_hint = resolve_task.await;
 5251                lsp_store
 5252                    .update(cx, |lsp_store, _| {
 5253                        if let Some(old_inlay_hint) = lsp_store
 5254                            .lsp_data
 5255                            .get_mut(&buffer_id)
 5256                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5257                        {
 5258                            match resolved_hint {
 5259                                Ok(resolved_hint) => {
 5260                                    *old_inlay_hint = resolved_hint;
 5261                                }
 5262                                Err(e) => {
 5263                                    old_inlay_hint.resolve_state =
 5264                                        ResolveState::CanResolve(server_id, resolve_data);
 5265                                    log::error!("Inlay hint resolve failed: {e:#}");
 5266                                }
 5267                            }
 5268                        }
 5269                    })
 5270                    .ok();
 5271            })
 5272            .shared(),
 5273        );
 5274        debug_assert!(
 5275            previous_task.is_none(),
 5276            "Did not change hint's resolve state after spawning its resolve"
 5277        );
 5278        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5279        None
 5280    }
 5281
 5282    fn resolve_inlay_hint(
 5283        &self,
 5284        mut hint: InlayHint,
 5285        buffer: Entity<Buffer>,
 5286        server_id: LanguageServerId,
 5287        cx: &mut Context<Self>,
 5288    ) -> Task<anyhow::Result<InlayHint>> {
 5289        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5290            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5291            {
 5292                hint.resolve_state = ResolveState::Resolved;
 5293                return Task::ready(Ok(hint));
 5294            }
 5295            let request = proto::ResolveInlayHint {
 5296                project_id,
 5297                buffer_id: buffer.read(cx).remote_id().into(),
 5298                language_server_id: server_id.0 as u64,
 5299                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5300            };
 5301            cx.background_spawn(async move {
 5302                let response = upstream_client
 5303                    .request(request)
 5304                    .await
 5305                    .context("inlay hints proto request")?;
 5306                match response.hint {
 5307                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5308                        .context("inlay hints proto resolve response conversion"),
 5309                    None => Ok(hint),
 5310                }
 5311            })
 5312        } else {
 5313            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5314                self.language_server_for_local_buffer(buffer, server_id, cx)
 5315                    .map(|(_, server)| server.clone())
 5316            }) else {
 5317                return Task::ready(Ok(hint));
 5318            };
 5319            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5320                return Task::ready(Ok(hint));
 5321            }
 5322            let buffer_snapshot = buffer.read(cx).snapshot();
 5323            cx.spawn(async move |_, cx| {
 5324                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5325                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5326                );
 5327                let resolved_hint = resolve_task
 5328                    .await
 5329                    .into_response()
 5330                    .context("inlay hint resolve LSP request")?;
 5331                let resolved_hint = InlayHints::lsp_to_project_hint(
 5332                    resolved_hint,
 5333                    &buffer,
 5334                    server_id,
 5335                    ResolveState::Resolved,
 5336                    false,
 5337                    cx,
 5338                )
 5339                .await?;
 5340                Ok(resolved_hint)
 5341            })
 5342        }
 5343    }
 5344
 5345    pub fn resolve_color_presentation(
 5346        &mut self,
 5347        mut color: DocumentColor,
 5348        buffer: Entity<Buffer>,
 5349        server_id: LanguageServerId,
 5350        cx: &mut Context<Self>,
 5351    ) -> Task<Result<DocumentColor>> {
 5352        if color.resolved {
 5353            return Task::ready(Ok(color));
 5354        }
 5355
 5356        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5357            let start = color.lsp_range.start;
 5358            let end = color.lsp_range.end;
 5359            let request = proto::GetColorPresentation {
 5360                project_id,
 5361                server_id: server_id.to_proto(),
 5362                buffer_id: buffer.read(cx).remote_id().into(),
 5363                color: Some(proto::ColorInformation {
 5364                    red: color.color.red,
 5365                    green: color.color.green,
 5366                    blue: color.color.blue,
 5367                    alpha: color.color.alpha,
 5368                    lsp_range_start: Some(proto::PointUtf16 {
 5369                        row: start.line,
 5370                        column: start.character,
 5371                    }),
 5372                    lsp_range_end: Some(proto::PointUtf16 {
 5373                        row: end.line,
 5374                        column: end.character,
 5375                    }),
 5376                }),
 5377            };
 5378            cx.background_spawn(async move {
 5379                let response = upstream_client
 5380                    .request(request)
 5381                    .await
 5382                    .context("color presentation proto request")?;
 5383                color.resolved = true;
 5384                color.color_presentations = response
 5385                    .presentations
 5386                    .into_iter()
 5387                    .map(|presentation| ColorPresentation {
 5388                        label: SharedString::from(presentation.label),
 5389                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5390                        additional_text_edits: presentation
 5391                            .additional_text_edits
 5392                            .into_iter()
 5393                            .filter_map(deserialize_lsp_edit)
 5394                            .collect(),
 5395                    })
 5396                    .collect();
 5397                Ok(color)
 5398            })
 5399        } else {
 5400            let path = match buffer
 5401                .update(cx, |buffer, cx| {
 5402                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5403                })
 5404                .context("buffer with the missing path")
 5405            {
 5406                Ok(path) => path,
 5407                Err(e) => return Task::ready(Err(e)),
 5408            };
 5409            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5410                self.language_server_for_local_buffer(buffer, server_id, cx)
 5411                    .map(|(_, server)| server.clone())
 5412            }) else {
 5413                return Task::ready(Ok(color));
 5414            };
 5415            cx.background_spawn(async move {
 5416                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5417                    lsp::ColorPresentationParams {
 5418                        text_document: make_text_document_identifier(&path)?,
 5419                        color: color.color,
 5420                        range: color.lsp_range,
 5421                        work_done_progress_params: Default::default(),
 5422                        partial_result_params: Default::default(),
 5423                    },
 5424                );
 5425                color.color_presentations = resolve_task
 5426                    .await
 5427                    .into_response()
 5428                    .context("color presentation resolve LSP request")?
 5429                    .into_iter()
 5430                    .map(|presentation| ColorPresentation {
 5431                        label: SharedString::from(presentation.label),
 5432                        text_edit: presentation.text_edit,
 5433                        additional_text_edits: presentation
 5434                            .additional_text_edits
 5435                            .unwrap_or_default(),
 5436                    })
 5437                    .collect();
 5438                color.resolved = true;
 5439                Ok(color)
 5440            })
 5441        }
 5442    }
 5443
 5444    pub(crate) fn linked_edits(
 5445        &mut self,
 5446        buffer: &Entity<Buffer>,
 5447        position: Anchor,
 5448        cx: &mut Context<Self>,
 5449    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5450        let snapshot = buffer.read(cx).snapshot();
 5451        let scope = snapshot.language_scope_at(position);
 5452        let Some(server_id) = self
 5453            .as_local()
 5454            .and_then(|local| {
 5455                buffer.update(cx, |buffer, cx| {
 5456                    local
 5457                        .language_servers_for_buffer(buffer, cx)
 5458                        .filter(|(_, server)| {
 5459                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5460                        })
 5461                        .filter(|(adapter, _)| {
 5462                            scope
 5463                                .as_ref()
 5464                                .map(|scope| scope.language_allowed(&adapter.name))
 5465                                .unwrap_or(true)
 5466                        })
 5467                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5468                        .next()
 5469                })
 5470            })
 5471            .or_else(|| {
 5472                self.upstream_client()
 5473                    .is_some()
 5474                    .then_some(LanguageServerToQuery::FirstCapable)
 5475            })
 5476            .filter(|_| {
 5477                maybe!({
 5478                    let language = buffer.read(cx).language_at(position)?;
 5479                    Some(
 5480                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5481                            .linked_edits,
 5482                    )
 5483                }) == Some(true)
 5484            })
 5485        else {
 5486            return Task::ready(Ok(Vec::new()));
 5487        };
 5488
 5489        self.request_lsp(
 5490            buffer.clone(),
 5491            server_id,
 5492            LinkedEditingRange { position },
 5493            cx,
 5494        )
 5495    }
 5496
 5497    fn apply_on_type_formatting(
 5498        &mut self,
 5499        buffer: Entity<Buffer>,
 5500        position: Anchor,
 5501        trigger: String,
 5502        cx: &mut Context<Self>,
 5503    ) -> Task<Result<Option<Transaction>>> {
 5504        if let Some((client, project_id)) = self.upstream_client() {
 5505            if !self.check_if_capable_for_proto_request(
 5506                &buffer,
 5507                |capabilities| {
 5508                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5509                },
 5510                cx,
 5511            ) {
 5512                return Task::ready(Ok(None));
 5513            }
 5514            let request = proto::OnTypeFormatting {
 5515                project_id,
 5516                buffer_id: buffer.read(cx).remote_id().into(),
 5517                position: Some(serialize_anchor(&position)),
 5518                trigger,
 5519                version: serialize_version(&buffer.read(cx).version()),
 5520            };
 5521            cx.background_spawn(async move {
 5522                client
 5523                    .request(request)
 5524                    .await?
 5525                    .transaction
 5526                    .map(language::proto::deserialize_transaction)
 5527                    .transpose()
 5528            })
 5529        } else if let Some(local) = self.as_local_mut() {
 5530            let buffer_id = buffer.read(cx).remote_id();
 5531            local.buffers_being_formatted.insert(buffer_id);
 5532            cx.spawn(async move |this, cx| {
 5533                let _cleanup = defer({
 5534                    let this = this.clone();
 5535                    let mut cx = cx.clone();
 5536                    move || {
 5537                        this.update(&mut cx, |this, _| {
 5538                            if let Some(local) = this.as_local_mut() {
 5539                                local.buffers_being_formatted.remove(&buffer_id);
 5540                            }
 5541                        })
 5542                        .ok();
 5543                    }
 5544                });
 5545
 5546                buffer
 5547                    .update(cx, |buffer, _| {
 5548                        buffer.wait_for_edits(Some(position.timestamp))
 5549                    })?
 5550                    .await?;
 5551                this.update(cx, |this, cx| {
 5552                    let position = position.to_point_utf16(buffer.read(cx));
 5553                    this.on_type_format(buffer, position, trigger, false, cx)
 5554                })?
 5555                .await
 5556            })
 5557        } else {
 5558            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5559        }
 5560    }
 5561
 5562    pub fn on_type_format<T: ToPointUtf16>(
 5563        &mut self,
 5564        buffer: Entity<Buffer>,
 5565        position: T,
 5566        trigger: String,
 5567        push_to_history: bool,
 5568        cx: &mut Context<Self>,
 5569    ) -> Task<Result<Option<Transaction>>> {
 5570        let position = position.to_point_utf16(buffer.read(cx));
 5571        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5572    }
 5573
 5574    fn on_type_format_impl(
 5575        &mut self,
 5576        buffer: Entity<Buffer>,
 5577        position: PointUtf16,
 5578        trigger: String,
 5579        push_to_history: bool,
 5580        cx: &mut Context<Self>,
 5581    ) -> Task<Result<Option<Transaction>>> {
 5582        let options = buffer.update(cx, |buffer, cx| {
 5583            lsp_command::lsp_formatting_options(
 5584                language_settings(
 5585                    buffer.language_at(position).map(|l| l.name()),
 5586                    buffer.file(),
 5587                    cx,
 5588                )
 5589                .as_ref(),
 5590            )
 5591        });
 5592
 5593        cx.spawn(async move |this, cx| {
 5594            if let Some(waiter) =
 5595                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5596            {
 5597                waiter.await?;
 5598            }
 5599            cx.update(|cx| {
 5600                this.update(cx, |this, cx| {
 5601                    this.request_lsp(
 5602                        buffer.clone(),
 5603                        LanguageServerToQuery::FirstCapable,
 5604                        OnTypeFormatting {
 5605                            position,
 5606                            trigger,
 5607                            options,
 5608                            push_to_history,
 5609                        },
 5610                        cx,
 5611                    )
 5612                })
 5613            })??
 5614            .await
 5615        })
 5616    }
 5617
 5618    pub fn definitions(
 5619        &mut self,
 5620        buffer: &Entity<Buffer>,
 5621        position: PointUtf16,
 5622        cx: &mut Context<Self>,
 5623    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5624        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5625            let request = GetDefinitions { position };
 5626            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5627                return Task::ready(Ok(None));
 5628            }
 5629            let request_task = upstream_client.request_lsp(
 5630                project_id,
 5631                None,
 5632                LSP_REQUEST_TIMEOUT,
 5633                cx.background_executor().clone(),
 5634                request.to_proto(project_id, buffer.read(cx)),
 5635            );
 5636            let buffer = buffer.clone();
 5637            cx.spawn(async move |weak_lsp_store, cx| {
 5638                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5639                    return Ok(None);
 5640                };
 5641                let Some(responses) = request_task.await? else {
 5642                    return Ok(None);
 5643                };
 5644                let actions = join_all(responses.payload.into_iter().map(|response| {
 5645                    GetDefinitions { position }.response_from_proto(
 5646                        response.response,
 5647                        lsp_store.clone(),
 5648                        buffer.clone(),
 5649                        cx.clone(),
 5650                    )
 5651                }))
 5652                .await;
 5653
 5654                Ok(Some(
 5655                    actions
 5656                        .into_iter()
 5657                        .collect::<Result<Vec<Vec<_>>>>()?
 5658                        .into_iter()
 5659                        .flatten()
 5660                        .dedup()
 5661                        .collect(),
 5662                ))
 5663            })
 5664        } else {
 5665            let definitions_task = self.request_multiple_lsp_locally(
 5666                buffer,
 5667                Some(position),
 5668                GetDefinitions { position },
 5669                cx,
 5670            );
 5671            cx.background_spawn(async move {
 5672                Ok(Some(
 5673                    definitions_task
 5674                        .await
 5675                        .into_iter()
 5676                        .flat_map(|(_, definitions)| definitions)
 5677                        .dedup()
 5678                        .collect(),
 5679                ))
 5680            })
 5681        }
 5682    }
 5683
 5684    pub fn declarations(
 5685        &mut self,
 5686        buffer: &Entity<Buffer>,
 5687        position: PointUtf16,
 5688        cx: &mut Context<Self>,
 5689    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5690        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5691            let request = GetDeclarations { position };
 5692            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5693                return Task::ready(Ok(None));
 5694            }
 5695            let request_task = upstream_client.request_lsp(
 5696                project_id,
 5697                None,
 5698                LSP_REQUEST_TIMEOUT,
 5699                cx.background_executor().clone(),
 5700                request.to_proto(project_id, buffer.read(cx)),
 5701            );
 5702            let buffer = buffer.clone();
 5703            cx.spawn(async move |weak_lsp_store, cx| {
 5704                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5705                    return Ok(None);
 5706                };
 5707                let Some(responses) = request_task.await? else {
 5708                    return Ok(None);
 5709                };
 5710                let actions = join_all(responses.payload.into_iter().map(|response| {
 5711                    GetDeclarations { position }.response_from_proto(
 5712                        response.response,
 5713                        lsp_store.clone(),
 5714                        buffer.clone(),
 5715                        cx.clone(),
 5716                    )
 5717                }))
 5718                .await;
 5719
 5720                Ok(Some(
 5721                    actions
 5722                        .into_iter()
 5723                        .collect::<Result<Vec<Vec<_>>>>()?
 5724                        .into_iter()
 5725                        .flatten()
 5726                        .dedup()
 5727                        .collect(),
 5728                ))
 5729            })
 5730        } else {
 5731            let declarations_task = self.request_multiple_lsp_locally(
 5732                buffer,
 5733                Some(position),
 5734                GetDeclarations { position },
 5735                cx,
 5736            );
 5737            cx.background_spawn(async move {
 5738                Ok(Some(
 5739                    declarations_task
 5740                        .await
 5741                        .into_iter()
 5742                        .flat_map(|(_, declarations)| declarations)
 5743                        .dedup()
 5744                        .collect(),
 5745                ))
 5746            })
 5747        }
 5748    }
 5749
 5750    pub fn type_definitions(
 5751        &mut self,
 5752        buffer: &Entity<Buffer>,
 5753        position: PointUtf16,
 5754        cx: &mut Context<Self>,
 5755    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5756        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5757            let request = GetTypeDefinitions { position };
 5758            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5759                return Task::ready(Ok(None));
 5760            }
 5761            let request_task = upstream_client.request_lsp(
 5762                project_id,
 5763                None,
 5764                LSP_REQUEST_TIMEOUT,
 5765                cx.background_executor().clone(),
 5766                request.to_proto(project_id, buffer.read(cx)),
 5767            );
 5768            let buffer = buffer.clone();
 5769            cx.spawn(async move |weak_lsp_store, cx| {
 5770                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5771                    return Ok(None);
 5772                };
 5773                let Some(responses) = request_task.await? else {
 5774                    return Ok(None);
 5775                };
 5776                let actions = join_all(responses.payload.into_iter().map(|response| {
 5777                    GetTypeDefinitions { position }.response_from_proto(
 5778                        response.response,
 5779                        lsp_store.clone(),
 5780                        buffer.clone(),
 5781                        cx.clone(),
 5782                    )
 5783                }))
 5784                .await;
 5785
 5786                Ok(Some(
 5787                    actions
 5788                        .into_iter()
 5789                        .collect::<Result<Vec<Vec<_>>>>()?
 5790                        .into_iter()
 5791                        .flatten()
 5792                        .dedup()
 5793                        .collect(),
 5794                ))
 5795            })
 5796        } else {
 5797            let type_definitions_task = self.request_multiple_lsp_locally(
 5798                buffer,
 5799                Some(position),
 5800                GetTypeDefinitions { position },
 5801                cx,
 5802            );
 5803            cx.background_spawn(async move {
 5804                Ok(Some(
 5805                    type_definitions_task
 5806                        .await
 5807                        .into_iter()
 5808                        .flat_map(|(_, type_definitions)| type_definitions)
 5809                        .dedup()
 5810                        .collect(),
 5811                ))
 5812            })
 5813        }
 5814    }
 5815
 5816    pub fn implementations(
 5817        &mut self,
 5818        buffer: &Entity<Buffer>,
 5819        position: PointUtf16,
 5820        cx: &mut Context<Self>,
 5821    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5822        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5823            let request = GetImplementations { position };
 5824            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5825                return Task::ready(Ok(None));
 5826            }
 5827            let request_task = upstream_client.request_lsp(
 5828                project_id,
 5829                None,
 5830                LSP_REQUEST_TIMEOUT,
 5831                cx.background_executor().clone(),
 5832                request.to_proto(project_id, buffer.read(cx)),
 5833            );
 5834            let buffer = buffer.clone();
 5835            cx.spawn(async move |weak_lsp_store, cx| {
 5836                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5837                    return Ok(None);
 5838                };
 5839                let Some(responses) = request_task.await? else {
 5840                    return Ok(None);
 5841                };
 5842                let actions = join_all(responses.payload.into_iter().map(|response| {
 5843                    GetImplementations { position }.response_from_proto(
 5844                        response.response,
 5845                        lsp_store.clone(),
 5846                        buffer.clone(),
 5847                        cx.clone(),
 5848                    )
 5849                }))
 5850                .await;
 5851
 5852                Ok(Some(
 5853                    actions
 5854                        .into_iter()
 5855                        .collect::<Result<Vec<Vec<_>>>>()?
 5856                        .into_iter()
 5857                        .flatten()
 5858                        .dedup()
 5859                        .collect(),
 5860                ))
 5861            })
 5862        } else {
 5863            let implementations_task = self.request_multiple_lsp_locally(
 5864                buffer,
 5865                Some(position),
 5866                GetImplementations { position },
 5867                cx,
 5868            );
 5869            cx.background_spawn(async move {
 5870                Ok(Some(
 5871                    implementations_task
 5872                        .await
 5873                        .into_iter()
 5874                        .flat_map(|(_, implementations)| implementations)
 5875                        .dedup()
 5876                        .collect(),
 5877                ))
 5878            })
 5879        }
 5880    }
 5881
 5882    pub fn references(
 5883        &mut self,
 5884        buffer: &Entity<Buffer>,
 5885        position: PointUtf16,
 5886        cx: &mut Context<Self>,
 5887    ) -> Task<Result<Option<Vec<Location>>>> {
 5888        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5889            let request = GetReferences { position };
 5890            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5891                return Task::ready(Ok(None));
 5892            }
 5893
 5894            let request_task = upstream_client.request_lsp(
 5895                project_id,
 5896                None,
 5897                LSP_REQUEST_TIMEOUT,
 5898                cx.background_executor().clone(),
 5899                request.to_proto(project_id, buffer.read(cx)),
 5900            );
 5901            let buffer = buffer.clone();
 5902            cx.spawn(async move |weak_lsp_store, cx| {
 5903                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5904                    return Ok(None);
 5905                };
 5906                let Some(responses) = request_task.await? else {
 5907                    return Ok(None);
 5908                };
 5909
 5910                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5911                    GetReferences { position }.response_from_proto(
 5912                        lsp_response.response,
 5913                        lsp_store.clone(),
 5914                        buffer.clone(),
 5915                        cx.clone(),
 5916                    )
 5917                }))
 5918                .await
 5919                .into_iter()
 5920                .collect::<Result<Vec<Vec<_>>>>()?
 5921                .into_iter()
 5922                .flatten()
 5923                .dedup()
 5924                .collect();
 5925                Ok(Some(locations))
 5926            })
 5927        } else {
 5928            let references_task = self.request_multiple_lsp_locally(
 5929                buffer,
 5930                Some(position),
 5931                GetReferences { position },
 5932                cx,
 5933            );
 5934            cx.background_spawn(async move {
 5935                Ok(Some(
 5936                    references_task
 5937                        .await
 5938                        .into_iter()
 5939                        .flat_map(|(_, references)| references)
 5940                        .dedup()
 5941                        .collect(),
 5942                ))
 5943            })
 5944        }
 5945    }
 5946
 5947    pub fn code_actions(
 5948        &mut self,
 5949        buffer: &Entity<Buffer>,
 5950        range: Range<Anchor>,
 5951        kinds: Option<Vec<CodeActionKind>>,
 5952        cx: &mut Context<Self>,
 5953    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5954        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5955            let request = GetCodeActions {
 5956                range: range.clone(),
 5957                kinds: kinds.clone(),
 5958            };
 5959            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5960                return Task::ready(Ok(None));
 5961            }
 5962            let request_task = upstream_client.request_lsp(
 5963                project_id,
 5964                None,
 5965                LSP_REQUEST_TIMEOUT,
 5966                cx.background_executor().clone(),
 5967                request.to_proto(project_id, buffer.read(cx)),
 5968            );
 5969            let buffer = buffer.clone();
 5970            cx.spawn(async move |weak_lsp_store, cx| {
 5971                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5972                    return Ok(None);
 5973                };
 5974                let Some(responses) = request_task.await? else {
 5975                    return Ok(None);
 5976                };
 5977                let actions = join_all(responses.payload.into_iter().map(|response| {
 5978                    GetCodeActions {
 5979                        range: range.clone(),
 5980                        kinds: kinds.clone(),
 5981                    }
 5982                    .response_from_proto(
 5983                        response.response,
 5984                        lsp_store.clone(),
 5985                        buffer.clone(),
 5986                        cx.clone(),
 5987                    )
 5988                }))
 5989                .await;
 5990
 5991                Ok(Some(
 5992                    actions
 5993                        .into_iter()
 5994                        .collect::<Result<Vec<Vec<_>>>>()?
 5995                        .into_iter()
 5996                        .flatten()
 5997                        .collect(),
 5998                ))
 5999            })
 6000        } else {
 6001            let all_actions_task = self.request_multiple_lsp_locally(
 6002                buffer,
 6003                Some(range.start),
 6004                GetCodeActions { range, kinds },
 6005                cx,
 6006            );
 6007            cx.background_spawn(async move {
 6008                Ok(Some(
 6009                    all_actions_task
 6010                        .await
 6011                        .into_iter()
 6012                        .flat_map(|(_, actions)| actions)
 6013                        .collect(),
 6014                ))
 6015            })
 6016        }
 6017    }
 6018
 6019    pub fn code_lens_actions(
 6020        &mut self,
 6021        buffer: &Entity<Buffer>,
 6022        cx: &mut Context<Self>,
 6023    ) -> CodeLensTask {
 6024        let version_queried_for = buffer.read(cx).version();
 6025        let buffer_id = buffer.read(cx).remote_id();
 6026        let existing_servers = self.as_local().map(|local| {
 6027            local
 6028                .buffers_opened_in_servers
 6029                .get(&buffer_id)
 6030                .cloned()
 6031                .unwrap_or_default()
 6032        });
 6033
 6034        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 6035            if let Some(cached_lens) = &lsp_data.code_lens {
 6036                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 6037                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 6038                        existing_servers != cached_lens.lens.keys().copied().collect()
 6039                    });
 6040                    if !has_different_servers {
 6041                        return Task::ready(Ok(Some(
 6042                            cached_lens.lens.values().flatten().cloned().collect(),
 6043                        )))
 6044                        .shared();
 6045                    }
 6046                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 6047                    if !version_queried_for.changed_since(updating_for) {
 6048                        return running_update.clone();
 6049                    }
 6050                }
 6051            }
 6052        }
 6053
 6054        let lens_lsp_data = self
 6055            .latest_lsp_data(buffer, cx)
 6056            .code_lens
 6057            .get_or_insert_default();
 6058        let buffer = buffer.clone();
 6059        let query_version_queried_for = version_queried_for.clone();
 6060        let new_task = cx
 6061            .spawn(async move |lsp_store, cx| {
 6062                cx.background_executor()
 6063                    .timer(Duration::from_millis(30))
 6064                    .await;
 6065                let fetched_lens = lsp_store
 6066                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 6067                    .map_err(Arc::new)?
 6068                    .await
 6069                    .context("fetching code lens")
 6070                    .map_err(Arc::new);
 6071                let fetched_lens = match fetched_lens {
 6072                    Ok(fetched_lens) => fetched_lens,
 6073                    Err(e) => {
 6074                        lsp_store
 6075                            .update(cx, |lsp_store, _| {
 6076                                if let Some(lens_lsp_data) = lsp_store
 6077                                    .lsp_data
 6078                                    .get_mut(&buffer_id)
 6079                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 6080                                {
 6081                                    lens_lsp_data.update = None;
 6082                                }
 6083                            })
 6084                            .ok();
 6085                        return Err(e);
 6086                    }
 6087                };
 6088
 6089                lsp_store
 6090                    .update(cx, |lsp_store, _| {
 6091                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 6092                        let code_lens = lsp_data.code_lens.as_mut()?;
 6093                        if let Some(fetched_lens) = fetched_lens {
 6094                            if lsp_data.buffer_version == query_version_queried_for {
 6095                                code_lens.lens.extend(fetched_lens);
 6096                            } else if !lsp_data
 6097                                .buffer_version
 6098                                .changed_since(&query_version_queried_for)
 6099                            {
 6100                                lsp_data.buffer_version = query_version_queried_for;
 6101                                code_lens.lens = fetched_lens;
 6102                            }
 6103                        }
 6104                        code_lens.update = None;
 6105                        Some(code_lens.lens.values().flatten().cloned().collect())
 6106                    })
 6107                    .map_err(Arc::new)
 6108            })
 6109            .shared();
 6110        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 6111        new_task
 6112    }
 6113
 6114    fn fetch_code_lens(
 6115        &mut self,
 6116        buffer: &Entity<Buffer>,
 6117        cx: &mut Context<Self>,
 6118    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 6119        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6120            let request = GetCodeLens;
 6121            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6122                return Task::ready(Ok(None));
 6123            }
 6124            let request_task = upstream_client.request_lsp(
 6125                project_id,
 6126                None,
 6127                LSP_REQUEST_TIMEOUT,
 6128                cx.background_executor().clone(),
 6129                request.to_proto(project_id, buffer.read(cx)),
 6130            );
 6131            let buffer = buffer.clone();
 6132            cx.spawn(async move |weak_lsp_store, cx| {
 6133                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6134                    return Ok(None);
 6135                };
 6136                let Some(responses) = request_task.await? else {
 6137                    return Ok(None);
 6138                };
 6139
 6140                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 6141                    let lsp_store = lsp_store.clone();
 6142                    let buffer = buffer.clone();
 6143                    let cx = cx.clone();
 6144                    async move {
 6145                        (
 6146                            LanguageServerId::from_proto(response.server_id),
 6147                            GetCodeLens
 6148                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6149                                .await,
 6150                        )
 6151                    }
 6152                }))
 6153                .await;
 6154
 6155                let mut has_errors = false;
 6156                let code_lens_actions = code_lens_actions
 6157                    .into_iter()
 6158                    .filter_map(|(server_id, code_lens)| match code_lens {
 6159                        Ok(code_lens) => Some((server_id, code_lens)),
 6160                        Err(e) => {
 6161                            has_errors = true;
 6162                            log::error!("{e:#}");
 6163                            None
 6164                        }
 6165                    })
 6166                    .collect::<HashMap<_, _>>();
 6167                anyhow::ensure!(
 6168                    !has_errors || !code_lens_actions.is_empty(),
 6169                    "Failed to fetch code lens"
 6170                );
 6171                Ok(Some(code_lens_actions))
 6172            })
 6173        } else {
 6174            let code_lens_actions_task =
 6175                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 6176            cx.background_spawn(async move {
 6177                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 6178            })
 6179        }
 6180    }
 6181
 6182    #[inline(never)]
 6183    pub fn completions(
 6184        &self,
 6185        buffer: &Entity<Buffer>,
 6186        position: PointUtf16,
 6187        context: CompletionContext,
 6188        cx: &mut Context<Self>,
 6189    ) -> Task<Result<Vec<CompletionResponse>>> {
 6190        let language_registry = self.languages.clone();
 6191
 6192        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6193            let snapshot = buffer.read(cx).snapshot();
 6194            let offset = position.to_offset(&snapshot);
 6195            let scope = snapshot.language_scope_at(offset);
 6196            let capable_lsps = self.all_capable_for_proto_request(
 6197                buffer,
 6198                |server_name, capabilities| {
 6199                    capabilities.completion_provider.is_some()
 6200                        && scope
 6201                            .as_ref()
 6202                            .map(|scope| scope.language_allowed(server_name))
 6203                            .unwrap_or(true)
 6204                },
 6205                cx,
 6206            );
 6207            if capable_lsps.is_empty() {
 6208                return Task::ready(Ok(Vec::new()));
 6209            }
 6210
 6211            let language = buffer.read(cx).language().cloned();
 6212
 6213            // In the future, we should provide project guests with the names of LSP adapters,
 6214            // so that they can use the correct LSP adapter when computing labels. For now,
 6215            // guests just use the first LSP adapter associated with the buffer's language.
 6216            let lsp_adapter = language.as_ref().and_then(|language| {
 6217                language_registry
 6218                    .lsp_adapters(&language.name())
 6219                    .first()
 6220                    .cloned()
 6221            });
 6222
 6223            let buffer = buffer.clone();
 6224
 6225            cx.spawn(async move |this, cx| {
 6226                let requests = join_all(
 6227                    capable_lsps
 6228                        .into_iter()
 6229                        .map(|id| {
 6230                            let request = GetCompletions {
 6231                                position,
 6232                                context: context.clone(),
 6233                                server_id: Some(id),
 6234                            };
 6235                            let buffer = buffer.clone();
 6236                            let language = language.clone();
 6237                            let lsp_adapter = lsp_adapter.clone();
 6238                            let upstream_client = upstream_client.clone();
 6239                            let response = this
 6240                                .update(cx, |this, cx| {
 6241                                    this.send_lsp_proto_request(
 6242                                        buffer,
 6243                                        upstream_client,
 6244                                        project_id,
 6245                                        request,
 6246                                        cx,
 6247                                    )
 6248                                })
 6249                                .log_err();
 6250                            async move {
 6251                                let response = response?.await.log_err()?;
 6252
 6253                                let completions = populate_labels_for_completions(
 6254                                    response.completions,
 6255                                    language,
 6256                                    lsp_adapter,
 6257                                )
 6258                                .await;
 6259
 6260                                Some(CompletionResponse {
 6261                                    completions,
 6262                                    display_options: CompletionDisplayOptions::default(),
 6263                                    is_incomplete: response.is_incomplete,
 6264                                })
 6265                            }
 6266                        })
 6267                        .collect::<Vec<_>>(),
 6268                );
 6269                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6270            })
 6271        } else if let Some(local) = self.as_local() {
 6272            let snapshot = buffer.read(cx).snapshot();
 6273            let offset = position.to_offset(&snapshot);
 6274            let scope = snapshot.language_scope_at(offset);
 6275            let language = snapshot.language().cloned();
 6276            let completion_settings = language_settings(
 6277                language.as_ref().map(|language| language.name()),
 6278                buffer.read(cx).file(),
 6279                cx,
 6280            )
 6281            .completions
 6282            .clone();
 6283            if !completion_settings.lsp {
 6284                return Task::ready(Ok(Vec::new()));
 6285            }
 6286
 6287            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6288                local
 6289                    .language_servers_for_buffer(buffer, cx)
 6290                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6291                    .filter(|(adapter, _)| {
 6292                        scope
 6293                            .as_ref()
 6294                            .map(|scope| scope.language_allowed(&adapter.name))
 6295                            .unwrap_or(true)
 6296                    })
 6297                    .map(|(_, server)| server.server_id())
 6298                    .collect()
 6299            });
 6300
 6301            let buffer = buffer.clone();
 6302            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6303            let lsp_timeout = if lsp_timeout > 0 {
 6304                Some(Duration::from_millis(lsp_timeout))
 6305            } else {
 6306                None
 6307            };
 6308            cx.spawn(async move |this,  cx| {
 6309                let mut tasks = Vec::with_capacity(server_ids.len());
 6310                this.update(cx, |lsp_store, cx| {
 6311                    for server_id in server_ids {
 6312                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6313                        let lsp_timeout = lsp_timeout
 6314                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6315                        let mut timeout = cx.background_spawn(async move {
 6316                            match lsp_timeout {
 6317                                Some(lsp_timeout) => {
 6318                                    lsp_timeout.await;
 6319                                    true
 6320                                },
 6321                                None => false,
 6322                            }
 6323                        }).fuse();
 6324                        let mut lsp_request = lsp_store.request_lsp(
 6325                            buffer.clone(),
 6326                            LanguageServerToQuery::Other(server_id),
 6327                            GetCompletions {
 6328                                position,
 6329                                context: context.clone(),
 6330                                server_id: Some(server_id),
 6331                            },
 6332                            cx,
 6333                        ).fuse();
 6334                        let new_task = cx.background_spawn(async move {
 6335                            select_biased! {
 6336                                response = lsp_request => anyhow::Ok(Some(response?)),
 6337                                timeout_happened = timeout => {
 6338                                    if timeout_happened {
 6339                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6340                                        Ok(None)
 6341                                    } else {
 6342                                        let completions = lsp_request.await?;
 6343                                        Ok(Some(completions))
 6344                                    }
 6345                                },
 6346                            }
 6347                        });
 6348                        tasks.push((lsp_adapter, new_task));
 6349                    }
 6350                })?;
 6351
 6352                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6353                    let completion_response = task.await.ok()??;
 6354                    let completions = populate_labels_for_completions(
 6355                            completion_response.completions,
 6356                            language.clone(),
 6357                            lsp_adapter,
 6358                        )
 6359                        .await;
 6360                    Some(CompletionResponse {
 6361                        completions,
 6362                        display_options: CompletionDisplayOptions::default(),
 6363                        is_incomplete: completion_response.is_incomplete,
 6364                    })
 6365                });
 6366
 6367                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6368
 6369                Ok(responses.into_iter().flatten().collect())
 6370            })
 6371        } else {
 6372            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6373        }
 6374    }
 6375
 6376    pub fn resolve_completions(
 6377        &self,
 6378        buffer: Entity<Buffer>,
 6379        completion_indices: Vec<usize>,
 6380        completions: Rc<RefCell<Box<[Completion]>>>,
 6381        cx: &mut Context<Self>,
 6382    ) -> Task<Result<bool>> {
 6383        let client = self.upstream_client();
 6384        let buffer_id = buffer.read(cx).remote_id();
 6385        let buffer_snapshot = buffer.read(cx).snapshot();
 6386
 6387        if !self.check_if_capable_for_proto_request(
 6388            &buffer,
 6389            GetCompletions::can_resolve_completions,
 6390            cx,
 6391        ) {
 6392            return Task::ready(Ok(false));
 6393        }
 6394        cx.spawn(async move |lsp_store, cx| {
 6395            let mut did_resolve = false;
 6396            if let Some((client, project_id)) = client {
 6397                for completion_index in completion_indices {
 6398                    let server_id = {
 6399                        let completion = &completions.borrow()[completion_index];
 6400                        completion.source.server_id()
 6401                    };
 6402                    if let Some(server_id) = server_id {
 6403                        if Self::resolve_completion_remote(
 6404                            project_id,
 6405                            server_id,
 6406                            buffer_id,
 6407                            completions.clone(),
 6408                            completion_index,
 6409                            client.clone(),
 6410                        )
 6411                        .await
 6412                        .log_err()
 6413                        .is_some()
 6414                        {
 6415                            did_resolve = true;
 6416                        }
 6417                    } else {
 6418                        resolve_word_completion(
 6419                            &buffer_snapshot,
 6420                            &mut completions.borrow_mut()[completion_index],
 6421                        );
 6422                    }
 6423                }
 6424            } else {
 6425                for completion_index in completion_indices {
 6426                    let server_id = {
 6427                        let completion = &completions.borrow()[completion_index];
 6428                        completion.source.server_id()
 6429                    };
 6430                    if let Some(server_id) = server_id {
 6431                        let server_and_adapter = lsp_store
 6432                            .read_with(cx, |lsp_store, _| {
 6433                                let server = lsp_store.language_server_for_id(server_id)?;
 6434                                let adapter =
 6435                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6436                                Some((server, adapter))
 6437                            })
 6438                            .ok()
 6439                            .flatten();
 6440                        let Some((server, adapter)) = server_and_adapter else {
 6441                            continue;
 6442                        };
 6443
 6444                        let resolved = Self::resolve_completion_local(
 6445                            server,
 6446                            completions.clone(),
 6447                            completion_index,
 6448                        )
 6449                        .await
 6450                        .log_err()
 6451                        .is_some();
 6452                        if resolved {
 6453                            Self::regenerate_completion_labels(
 6454                                adapter,
 6455                                &buffer_snapshot,
 6456                                completions.clone(),
 6457                                completion_index,
 6458                            )
 6459                            .await
 6460                            .log_err();
 6461                            did_resolve = true;
 6462                        }
 6463                    } else {
 6464                        resolve_word_completion(
 6465                            &buffer_snapshot,
 6466                            &mut completions.borrow_mut()[completion_index],
 6467                        );
 6468                    }
 6469                }
 6470            }
 6471
 6472            Ok(did_resolve)
 6473        })
 6474    }
 6475
 6476    async fn resolve_completion_local(
 6477        server: Arc<lsp::LanguageServer>,
 6478        completions: Rc<RefCell<Box<[Completion]>>>,
 6479        completion_index: usize,
 6480    ) -> Result<()> {
 6481        let server_id = server.server_id();
 6482        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6483            return Ok(());
 6484        }
 6485
 6486        let request = {
 6487            let completion = &completions.borrow()[completion_index];
 6488            match &completion.source {
 6489                CompletionSource::Lsp {
 6490                    lsp_completion,
 6491                    resolved,
 6492                    server_id: completion_server_id,
 6493                    ..
 6494                } => {
 6495                    if *resolved {
 6496                        return Ok(());
 6497                    }
 6498                    anyhow::ensure!(
 6499                        server_id == *completion_server_id,
 6500                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6501                    );
 6502                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6503                }
 6504                CompletionSource::BufferWord { .. }
 6505                | CompletionSource::Dap { .. }
 6506                | CompletionSource::Custom => {
 6507                    return Ok(());
 6508                }
 6509            }
 6510        };
 6511        let resolved_completion = request
 6512            .await
 6513            .into_response()
 6514            .context("resolve completion")?;
 6515
 6516        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6517        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6518
 6519        let mut completions = completions.borrow_mut();
 6520        let completion = &mut completions[completion_index];
 6521        if let CompletionSource::Lsp {
 6522            lsp_completion,
 6523            resolved,
 6524            server_id: completion_server_id,
 6525            ..
 6526        } = &mut completion.source
 6527        {
 6528            if *resolved {
 6529                return Ok(());
 6530            }
 6531            anyhow::ensure!(
 6532                server_id == *completion_server_id,
 6533                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6534            );
 6535            **lsp_completion = resolved_completion;
 6536            *resolved = true;
 6537        }
 6538        Ok(())
 6539    }
 6540
 6541    async fn regenerate_completion_labels(
 6542        adapter: Arc<CachedLspAdapter>,
 6543        snapshot: &BufferSnapshot,
 6544        completions: Rc<RefCell<Box<[Completion]>>>,
 6545        completion_index: usize,
 6546    ) -> Result<()> {
 6547        let completion_item = completions.borrow()[completion_index]
 6548            .source
 6549            .lsp_completion(true)
 6550            .map(Cow::into_owned);
 6551        if let Some(lsp_documentation) = completion_item
 6552            .as_ref()
 6553            .and_then(|completion_item| completion_item.documentation.clone())
 6554        {
 6555            let mut completions = completions.borrow_mut();
 6556            let completion = &mut completions[completion_index];
 6557            completion.documentation = Some(lsp_documentation.into());
 6558        } else {
 6559            let mut completions = completions.borrow_mut();
 6560            let completion = &mut completions[completion_index];
 6561            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6562        }
 6563
 6564        let mut new_label = match completion_item {
 6565            Some(completion_item) => {
 6566                // Some language servers always return `detail` lazily via resolve, regardless of
 6567                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6568                // See: https://github.com/yioneko/vtsls/issues/213
 6569                let language = snapshot.language();
 6570                match language {
 6571                    Some(language) => {
 6572                        adapter
 6573                            .labels_for_completions(
 6574                                std::slice::from_ref(&completion_item),
 6575                                language,
 6576                            )
 6577                            .await?
 6578                    }
 6579                    None => Vec::new(),
 6580                }
 6581                .pop()
 6582                .flatten()
 6583                .unwrap_or_else(|| {
 6584                    CodeLabel::fallback_for_completion(
 6585                        &completion_item,
 6586                        language.map(|language| language.as_ref()),
 6587                    )
 6588                })
 6589            }
 6590            None => CodeLabel::plain(
 6591                completions.borrow()[completion_index].new_text.clone(),
 6592                None,
 6593            ),
 6594        };
 6595        ensure_uniform_list_compatible_label(&mut new_label);
 6596
 6597        let mut completions = completions.borrow_mut();
 6598        let completion = &mut completions[completion_index];
 6599        if completion.label.filter_text() == new_label.filter_text() {
 6600            completion.label = new_label;
 6601        } else {
 6602            log::error!(
 6603                "Resolved completion changed display label from {} to {}. \
 6604                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6605                completion.label.text(),
 6606                new_label.text(),
 6607                completion.label.filter_text(),
 6608                new_label.filter_text()
 6609            );
 6610        }
 6611
 6612        Ok(())
 6613    }
 6614
 6615    async fn resolve_completion_remote(
 6616        project_id: u64,
 6617        server_id: LanguageServerId,
 6618        buffer_id: BufferId,
 6619        completions: Rc<RefCell<Box<[Completion]>>>,
 6620        completion_index: usize,
 6621        client: AnyProtoClient,
 6622    ) -> Result<()> {
 6623        let lsp_completion = {
 6624            let completion = &completions.borrow()[completion_index];
 6625            match &completion.source {
 6626                CompletionSource::Lsp {
 6627                    lsp_completion,
 6628                    resolved,
 6629                    server_id: completion_server_id,
 6630                    ..
 6631                } => {
 6632                    anyhow::ensure!(
 6633                        server_id == *completion_server_id,
 6634                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6635                    );
 6636                    if *resolved {
 6637                        return Ok(());
 6638                    }
 6639                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6640                }
 6641                CompletionSource::Custom
 6642                | CompletionSource::Dap { .. }
 6643                | CompletionSource::BufferWord { .. } => {
 6644                    return Ok(());
 6645                }
 6646            }
 6647        };
 6648        let request = proto::ResolveCompletionDocumentation {
 6649            project_id,
 6650            language_server_id: server_id.0 as u64,
 6651            lsp_completion,
 6652            buffer_id: buffer_id.into(),
 6653        };
 6654
 6655        let response = client
 6656            .request(request)
 6657            .await
 6658            .context("completion documentation resolve proto request")?;
 6659        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6660
 6661        let documentation = if response.documentation.is_empty() {
 6662            CompletionDocumentation::Undocumented
 6663        } else if response.documentation_is_markdown {
 6664            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6665        } else if response.documentation.lines().count() <= 1 {
 6666            CompletionDocumentation::SingleLine(response.documentation.into())
 6667        } else {
 6668            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6669        };
 6670
 6671        let mut completions = completions.borrow_mut();
 6672        let completion = &mut completions[completion_index];
 6673        completion.documentation = Some(documentation);
 6674        if let CompletionSource::Lsp {
 6675            insert_range,
 6676            lsp_completion,
 6677            resolved,
 6678            server_id: completion_server_id,
 6679            lsp_defaults: _,
 6680        } = &mut completion.source
 6681        {
 6682            let completion_insert_range = response
 6683                .old_insert_start
 6684                .and_then(deserialize_anchor)
 6685                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6686            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6687
 6688            if *resolved {
 6689                return Ok(());
 6690            }
 6691            anyhow::ensure!(
 6692                server_id == *completion_server_id,
 6693                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6694            );
 6695            **lsp_completion = resolved_lsp_completion;
 6696            *resolved = true;
 6697        }
 6698
 6699        let replace_range = response
 6700            .old_replace_start
 6701            .and_then(deserialize_anchor)
 6702            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6703        if let Some((old_replace_start, old_replace_end)) = replace_range
 6704            && !response.new_text.is_empty()
 6705        {
 6706            completion.new_text = response.new_text;
 6707            completion.replace_range = old_replace_start..old_replace_end;
 6708        }
 6709
 6710        Ok(())
 6711    }
 6712
 6713    pub fn apply_additional_edits_for_completion(
 6714        &self,
 6715        buffer_handle: Entity<Buffer>,
 6716        completions: Rc<RefCell<Box<[Completion]>>>,
 6717        completion_index: usize,
 6718        push_to_history: bool,
 6719        cx: &mut Context<Self>,
 6720    ) -> Task<Result<Option<Transaction>>> {
 6721        if let Some((client, project_id)) = self.upstream_client() {
 6722            let buffer = buffer_handle.read(cx);
 6723            let buffer_id = buffer.remote_id();
 6724            cx.spawn(async move |_, cx| {
 6725                let request = {
 6726                    let completion = completions.borrow()[completion_index].clone();
 6727                    proto::ApplyCompletionAdditionalEdits {
 6728                        project_id,
 6729                        buffer_id: buffer_id.into(),
 6730                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6731                            replace_range: completion.replace_range,
 6732                            new_text: completion.new_text,
 6733                            source: completion.source,
 6734                        })),
 6735                    }
 6736                };
 6737
 6738                if let Some(transaction) = client.request(request).await?.transaction {
 6739                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6740                    buffer_handle
 6741                        .update(cx, |buffer, _| {
 6742                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6743                        })?
 6744                        .await?;
 6745                    if push_to_history {
 6746                        buffer_handle.update(cx, |buffer, _| {
 6747                            buffer.push_transaction(transaction.clone(), Instant::now());
 6748                            buffer.finalize_last_transaction();
 6749                        })?;
 6750                    }
 6751                    Ok(Some(transaction))
 6752                } else {
 6753                    Ok(None)
 6754                }
 6755            })
 6756        } else {
 6757            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6758                let completion = &completions.borrow()[completion_index];
 6759                let server_id = completion.source.server_id()?;
 6760                Some(
 6761                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6762                        .1
 6763                        .clone(),
 6764                )
 6765            }) else {
 6766                return Task::ready(Ok(None));
 6767            };
 6768
 6769            cx.spawn(async move |this, cx| {
 6770                Self::resolve_completion_local(
 6771                    server.clone(),
 6772                    completions.clone(),
 6773                    completion_index,
 6774                )
 6775                .await
 6776                .context("resolving completion")?;
 6777                let completion = completions.borrow()[completion_index].clone();
 6778                let additional_text_edits = completion
 6779                    .source
 6780                    .lsp_completion(true)
 6781                    .as_ref()
 6782                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6783                if let Some(edits) = additional_text_edits {
 6784                    let edits = this
 6785                        .update(cx, |this, cx| {
 6786                            this.as_local_mut().unwrap().edits_from_lsp(
 6787                                &buffer_handle,
 6788                                edits,
 6789                                server.server_id(),
 6790                                None,
 6791                                cx,
 6792                            )
 6793                        })?
 6794                        .await?;
 6795
 6796                    buffer_handle.update(cx, |buffer, cx| {
 6797                        buffer.finalize_last_transaction();
 6798                        buffer.start_transaction();
 6799
 6800                        for (range, text) in edits {
 6801                            let primary = &completion.replace_range;
 6802
 6803                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6804                            // and the primary completion is just an insertion (empty range), then this is likely
 6805                            // an auto-import scenario and should not be considered overlapping
 6806                            // https://github.com/zed-industries/zed/issues/26136
 6807                            let is_file_start_auto_import = {
 6808                                let snapshot = buffer.snapshot();
 6809                                let primary_start_point = primary.start.to_point(&snapshot);
 6810                                let range_start_point = range.start.to_point(&snapshot);
 6811
 6812                                let result = primary_start_point.row == 0
 6813                                    && primary_start_point.column == 0
 6814                                    && range_start_point.row == 0
 6815                                    && range_start_point.column == 0;
 6816
 6817                                result
 6818                            };
 6819
 6820                            let has_overlap = if is_file_start_auto_import {
 6821                                false
 6822                            } else {
 6823                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6824                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6825                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6826                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6827                                let result = start_within || end_within;
 6828                                result
 6829                            };
 6830
 6831                            //Skip additional edits which overlap with the primary completion edit
 6832                            //https://github.com/zed-industries/zed/pull/1871
 6833                            if !has_overlap {
 6834                                buffer.edit([(range, text)], None, cx);
 6835                            }
 6836                        }
 6837
 6838                        let transaction = if buffer.end_transaction(cx).is_some() {
 6839                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6840                            if !push_to_history {
 6841                                buffer.forget_transaction(transaction.id);
 6842                            }
 6843                            Some(transaction)
 6844                        } else {
 6845                            None
 6846                        };
 6847                        Ok(transaction)
 6848                    })?
 6849                } else {
 6850                    Ok(None)
 6851                }
 6852            })
 6853        }
 6854    }
 6855
 6856    pub fn pull_diagnostics(
 6857        &mut self,
 6858        buffer: Entity<Buffer>,
 6859        cx: &mut Context<Self>,
 6860    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6861        let buffer_id = buffer.read(cx).remote_id();
 6862
 6863        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6864            let mut suitable_capabilities = None;
 6865            // Are we capable for proto request?
 6866            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6867                &buffer,
 6868                |capabilities| {
 6869                    if let Some(caps) = &capabilities.diagnostic_provider {
 6870                        suitable_capabilities = Some(caps.clone());
 6871                        true
 6872                    } else {
 6873                        false
 6874                    }
 6875                },
 6876                cx,
 6877            );
 6878            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6879            let Some(dynamic_caps) = suitable_capabilities else {
 6880                return Task::ready(Ok(None));
 6881            };
 6882            assert!(any_server_has_diagnostics_provider);
 6883
 6884            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6885            let request = GetDocumentDiagnostics {
 6886                previous_result_id: None,
 6887                identifier,
 6888                registration_id: None,
 6889            };
 6890            let request_task = client.request_lsp(
 6891                upstream_project_id,
 6892                None,
 6893                LSP_REQUEST_TIMEOUT,
 6894                cx.background_executor().clone(),
 6895                request.to_proto(upstream_project_id, buffer.read(cx)),
 6896            );
 6897            cx.background_spawn(async move {
 6898                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6899                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6900                // Do not attempt to further process the dummy responses here.
 6901                let _response = request_task.await?;
 6902                Ok(None)
 6903            })
 6904        } else {
 6905            let servers = buffer.update(cx, |buffer, cx| {
 6906                self.running_language_servers_for_local_buffer(buffer, cx)
 6907                    .map(|(_, server)| server.clone())
 6908                    .collect::<Vec<_>>()
 6909            });
 6910
 6911            let pull_diagnostics = servers
 6912                .into_iter()
 6913                .flat_map(|server| {
 6914                    let result = maybe!({
 6915                        let local = self.as_local()?;
 6916                        let server_id = server.server_id();
 6917                        let providers_with_identifiers = local
 6918                            .language_server_dynamic_registrations
 6919                            .get(&server_id)
 6920                            .into_iter()
 6921                            .flat_map(|registrations| registrations.diagnostics.clone())
 6922                            .collect::<Vec<_>>();
 6923                        Some(
 6924                            providers_with_identifiers
 6925                                .into_iter()
 6926                                .map(|(registration_id, dynamic_caps)| {
 6927                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6928                                    let registration_id = registration_id.map(SharedString::from);
 6929                                    let result_id = self.result_id_for_buffer_pull(
 6930                                        server_id,
 6931                                        buffer_id,
 6932                                        &registration_id,
 6933                                        cx,
 6934                                    );
 6935                                    self.request_lsp(
 6936                                        buffer.clone(),
 6937                                        LanguageServerToQuery::Other(server_id),
 6938                                        GetDocumentDiagnostics {
 6939                                            previous_result_id: result_id,
 6940                                            registration_id,
 6941                                            identifier,
 6942                                        },
 6943                                        cx,
 6944                                    )
 6945                                })
 6946                                .collect::<Vec<_>>(),
 6947                        )
 6948                    });
 6949
 6950                    result.unwrap_or_default()
 6951                })
 6952                .collect::<Vec<_>>();
 6953
 6954            cx.background_spawn(async move {
 6955                let mut responses = Vec::new();
 6956                for diagnostics in join_all(pull_diagnostics).await {
 6957                    responses.extend(diagnostics?);
 6958                }
 6959                Ok(Some(responses))
 6960            })
 6961        }
 6962    }
 6963
 6964    pub fn applicable_inlay_chunks(
 6965        &mut self,
 6966        buffer: &Entity<Buffer>,
 6967        ranges: &[Range<text::Anchor>],
 6968        cx: &mut Context<Self>,
 6969    ) -> Vec<Range<BufferRow>> {
 6970        let buffer_snapshot = buffer.read(cx).snapshot();
 6971        let ranges = ranges
 6972            .iter()
 6973            .map(|range| range.to_point(&buffer_snapshot))
 6974            .collect::<Vec<_>>();
 6975
 6976        self.latest_lsp_data(buffer, cx)
 6977            .inlay_hints
 6978            .applicable_chunks(ranges.as_slice())
 6979            .map(|chunk| chunk.row_range())
 6980            .collect()
 6981    }
 6982
 6983    pub fn invalidate_inlay_hints<'a>(
 6984        &'a mut self,
 6985        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6986    ) {
 6987        for buffer_id in for_buffers {
 6988            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6989                lsp_data.inlay_hints.clear();
 6990            }
 6991        }
 6992    }
 6993
 6994    pub fn inlay_hints(
 6995        &mut self,
 6996        invalidate: InvalidationStrategy,
 6997        buffer: Entity<Buffer>,
 6998        ranges: Vec<Range<text::Anchor>>,
 6999        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 7000        cx: &mut Context<Self>,
 7001    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 7002        let next_hint_id = self.next_hint_id.clone();
 7003        let lsp_data = self.latest_lsp_data(&buffer, cx);
 7004        let query_version = lsp_data.buffer_version.clone();
 7005        let mut lsp_refresh_requested = false;
 7006        let for_server = if let InvalidationStrategy::RefreshRequested {
 7007            server_id,
 7008            request_id,
 7009        } = invalidate
 7010        {
 7011            let invalidated = lsp_data
 7012                .inlay_hints
 7013                .invalidate_for_server_refresh(server_id, request_id);
 7014            lsp_refresh_requested = invalidated;
 7015            Some(server_id)
 7016        } else {
 7017            None
 7018        };
 7019        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 7020        let known_chunks = known_chunks
 7021            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 7022            .map(|(_, known_chunks)| known_chunks)
 7023            .unwrap_or_default();
 7024
 7025        let buffer_snapshot = buffer.read(cx).snapshot();
 7026        let ranges = ranges
 7027            .iter()
 7028            .map(|range| range.to_point(&buffer_snapshot))
 7029            .collect::<Vec<_>>();
 7030
 7031        let mut hint_fetch_tasks = Vec::new();
 7032        let mut cached_inlay_hints = None;
 7033        let mut ranges_to_query = None;
 7034        let applicable_chunks = existing_inlay_hints
 7035            .applicable_chunks(ranges.as_slice())
 7036            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7037            .collect::<Vec<_>>();
 7038        if applicable_chunks.is_empty() {
 7039            return HashMap::default();
 7040        }
 7041
 7042        for row_chunk in applicable_chunks {
 7043            match (
 7044                existing_inlay_hints
 7045                    .cached_hints(&row_chunk)
 7046                    .filter(|_| !lsp_refresh_requested)
 7047                    .cloned(),
 7048                existing_inlay_hints
 7049                    .fetched_hints(&row_chunk)
 7050                    .as_ref()
 7051                    .filter(|_| !lsp_refresh_requested)
 7052                    .cloned(),
 7053            ) {
 7054                (None, None) => {
 7055                    let chunk_range = row_chunk.anchor_range();
 7056                    ranges_to_query
 7057                        .get_or_insert_with(Vec::new)
 7058                        .push((row_chunk, chunk_range));
 7059                }
 7060                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7061                (Some(cached_hints), None) => {
 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                (Some(cached_hints), Some(fetched_hints)) => {
 7075                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7076                    for (server_id, cached_hints) in cached_hints {
 7077                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7078                            cached_inlay_hints
 7079                                .get_or_insert_with(HashMap::default)
 7080                                .entry(row_chunk.row_range())
 7081                                .or_insert_with(HashMap::default)
 7082                                .entry(server_id)
 7083                                .or_insert_with(Vec::new)
 7084                                .extend(cached_hints);
 7085                        }
 7086                    }
 7087                }
 7088            }
 7089        }
 7090
 7091        if hint_fetch_tasks.is_empty()
 7092            && ranges_to_query
 7093                .as_ref()
 7094                .is_none_or(|ranges| ranges.is_empty())
 7095            && let Some(cached_inlay_hints) = cached_inlay_hints
 7096        {
 7097            cached_inlay_hints
 7098                .into_iter()
 7099                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7100                .collect()
 7101        } else {
 7102            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7103                let next_hint_id = next_hint_id.clone();
 7104                let buffer = buffer.clone();
 7105                let query_version = query_version.clone();
 7106                let new_inlay_hints = cx
 7107                    .spawn(async move |lsp_store, cx| {
 7108                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7109                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7110                        })?;
 7111                        new_fetch_task
 7112                            .await
 7113                            .and_then(|new_hints_by_server| {
 7114                                lsp_store.update(cx, |lsp_store, cx| {
 7115                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7116                                    let update_cache = lsp_data.buffer_version == query_version;
 7117                                    if new_hints_by_server.is_empty() {
 7118                                        if update_cache {
 7119                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7120                                        }
 7121                                        HashMap::default()
 7122                                    } else {
 7123                                        new_hints_by_server
 7124                                            .into_iter()
 7125                                            .map(|(server_id, new_hints)| {
 7126                                                let new_hints = new_hints
 7127                                                    .into_iter()
 7128                                                    .map(|new_hint| {
 7129                                                        (
 7130                                                            InlayId::Hint(next_hint_id.fetch_add(
 7131                                                                1,
 7132                                                                atomic::Ordering::AcqRel,
 7133                                                            )),
 7134                                                            new_hint,
 7135                                                        )
 7136                                                    })
 7137                                                    .collect::<Vec<_>>();
 7138                                                if update_cache {
 7139                                                    lsp_data.inlay_hints.insert_new_hints(
 7140                                                        chunk,
 7141                                                        server_id,
 7142                                                        new_hints.clone(),
 7143                                                    );
 7144                                                }
 7145                                                (server_id, new_hints)
 7146                                            })
 7147                                            .collect()
 7148                                    }
 7149                                })
 7150                            })
 7151                            .map_err(Arc::new)
 7152                    })
 7153                    .shared();
 7154
 7155                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7156                *fetch_task = Some(new_inlay_hints.clone());
 7157                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7158            }
 7159
 7160            cached_inlay_hints
 7161                .unwrap_or_default()
 7162                .into_iter()
 7163                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7164                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7165                    (
 7166                        chunk.row_range(),
 7167                        cx.spawn(async move |_, _| {
 7168                            hints_fetch.await.map_err(|e| {
 7169                                if e.error_code() != ErrorCode::Internal {
 7170                                    anyhow!(e.error_code())
 7171                                } else {
 7172                                    anyhow!("{e:#}")
 7173                                }
 7174                            })
 7175                        }),
 7176                    )
 7177                }))
 7178                .collect()
 7179        }
 7180    }
 7181
 7182    fn fetch_inlay_hints(
 7183        &mut self,
 7184        for_server: Option<LanguageServerId>,
 7185        buffer: &Entity<Buffer>,
 7186        range: Range<Anchor>,
 7187        cx: &mut Context<Self>,
 7188    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7189        let request = InlayHints {
 7190            range: range.clone(),
 7191        };
 7192        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7193            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7194                return Task::ready(Ok(HashMap::default()));
 7195            }
 7196            let request_task = upstream_client.request_lsp(
 7197                project_id,
 7198                for_server.map(|id| id.to_proto()),
 7199                LSP_REQUEST_TIMEOUT,
 7200                cx.background_executor().clone(),
 7201                request.to_proto(project_id, buffer.read(cx)),
 7202            );
 7203            let buffer = buffer.clone();
 7204            cx.spawn(async move |weak_lsp_store, cx| {
 7205                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7206                    return Ok(HashMap::default());
 7207                };
 7208                let Some(responses) = request_task.await? else {
 7209                    return Ok(HashMap::default());
 7210                };
 7211
 7212                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7213                    let lsp_store = lsp_store.clone();
 7214                    let buffer = buffer.clone();
 7215                    let cx = cx.clone();
 7216                    let request = request.clone();
 7217                    async move {
 7218                        (
 7219                            LanguageServerId::from_proto(response.server_id),
 7220                            request
 7221                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7222                                .await,
 7223                        )
 7224                    }
 7225                }))
 7226                .await;
 7227
 7228                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot())?;
 7229                let mut has_errors = false;
 7230                let inlay_hints = inlay_hints
 7231                    .into_iter()
 7232                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7233                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7234                        Err(e) => {
 7235                            has_errors = true;
 7236                            log::error!("{e:#}");
 7237                            None
 7238                        }
 7239                    })
 7240                    .map(|(server_id, mut new_hints)| {
 7241                        new_hints.retain(|hint| {
 7242                            hint.position.is_valid(&buffer_snapshot)
 7243                                && range.start.is_valid(&buffer_snapshot)
 7244                                && range.end.is_valid(&buffer_snapshot)
 7245                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7246                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7247                        });
 7248                        (server_id, new_hints)
 7249                    })
 7250                    .collect::<HashMap<_, _>>();
 7251                anyhow::ensure!(
 7252                    !has_errors || !inlay_hints.is_empty(),
 7253                    "Failed to fetch inlay hints"
 7254                );
 7255                Ok(inlay_hints)
 7256            })
 7257        } else {
 7258            let inlay_hints_task = match for_server {
 7259                Some(server_id) => {
 7260                    let server_task = self.request_lsp(
 7261                        buffer.clone(),
 7262                        LanguageServerToQuery::Other(server_id),
 7263                        request,
 7264                        cx,
 7265                    );
 7266                    cx.background_spawn(async move {
 7267                        let mut responses = Vec::new();
 7268                        match server_task.await {
 7269                            Ok(response) => responses.push((server_id, response)),
 7270                            // rust-analyzer likes to error with this when its still loading up
 7271                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7272                            Err(e) => log::error!(
 7273                                "Error handling response for inlay hints request: {e:#}"
 7274                            ),
 7275                        }
 7276                        responses
 7277                    })
 7278                }
 7279                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7280            };
 7281            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7282            cx.background_spawn(async move {
 7283                Ok(inlay_hints_task
 7284                    .await
 7285                    .into_iter()
 7286                    .map(|(server_id, mut new_hints)| {
 7287                        new_hints.retain(|hint| {
 7288                            hint.position.is_valid(&buffer_snapshot)
 7289                                && range.start.is_valid(&buffer_snapshot)
 7290                                && range.end.is_valid(&buffer_snapshot)
 7291                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7292                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7293                        });
 7294                        (server_id, new_hints)
 7295                    })
 7296                    .collect())
 7297            })
 7298        }
 7299    }
 7300
 7301    fn diagnostic_registration_exists(
 7302        &self,
 7303        server_id: LanguageServerId,
 7304        registration_id: &Option<SharedString>,
 7305    ) -> bool {
 7306        let Some(local) = self.as_local() else {
 7307            return false;
 7308        };
 7309        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7310        else {
 7311            return false;
 7312        };
 7313        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7314        registrations.diagnostics.contains_key(&registration_key)
 7315    }
 7316
 7317    pub fn pull_diagnostics_for_buffer(
 7318        &mut self,
 7319        buffer: Entity<Buffer>,
 7320        cx: &mut Context<Self>,
 7321    ) -> Task<anyhow::Result<()>> {
 7322        let diagnostics = self.pull_diagnostics(buffer, cx);
 7323        cx.spawn(async move |lsp_store, cx| {
 7324            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7325                return Ok(());
 7326            };
 7327            lsp_store.update(cx, |lsp_store, cx| {
 7328                if lsp_store.as_local().is_none() {
 7329                    return;
 7330                }
 7331
 7332                let mut unchanged_buffers = HashMap::default();
 7333                let server_diagnostics_updates = diagnostics
 7334                    .into_iter()
 7335                    .filter_map(|diagnostics_set| match diagnostics_set {
 7336                        LspPullDiagnostics::Response {
 7337                            server_id,
 7338                            uri,
 7339                            diagnostics,
 7340                            registration_id,
 7341                        } => Some((server_id, uri, diagnostics, registration_id)),
 7342                        LspPullDiagnostics::Default => None,
 7343                    })
 7344                    .filter(|(server_id, _, _, registration_id)| {
 7345                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7346                    })
 7347                    .fold(
 7348                        HashMap::default(),
 7349                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7350                            let (result_id, diagnostics) = match diagnostics {
 7351                                PulledDiagnostics::Unchanged { result_id } => {
 7352                                    unchanged_buffers
 7353                                        .entry(new_registration_id.clone())
 7354                                        .or_insert_with(HashSet::default)
 7355                                        .insert(uri.clone());
 7356                                    (Some(result_id), Vec::new())
 7357                                }
 7358                                PulledDiagnostics::Changed {
 7359                                    result_id,
 7360                                    diagnostics,
 7361                                } => (result_id, diagnostics),
 7362                            };
 7363                            let disk_based_sources = Cow::Owned(
 7364                                lsp_store
 7365                                    .language_server_adapter_for_id(server_id)
 7366                                    .as_ref()
 7367                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7368                                    .unwrap_or(&[])
 7369                                    .to_vec(),
 7370                            );
 7371                            acc.entry(server_id)
 7372                                .or_insert_with(HashMap::default)
 7373                                .entry(new_registration_id.clone())
 7374                                .or_insert_with(Vec::new)
 7375                                .push(DocumentDiagnosticsUpdate {
 7376                                    server_id,
 7377                                    diagnostics: lsp::PublishDiagnosticsParams {
 7378                                        uri,
 7379                                        diagnostics,
 7380                                        version: None,
 7381                                    },
 7382                                    result_id,
 7383                                    disk_based_sources,
 7384                                    registration_id: new_registration_id,
 7385                                });
 7386                            acc
 7387                        },
 7388                    );
 7389
 7390                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7391                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7392                        lsp_store
 7393                            .merge_lsp_diagnostics(
 7394                                DiagnosticSourceKind::Pulled,
 7395                                diagnostic_updates,
 7396                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7397                                    DiagnosticSourceKind::Pulled => {
 7398                                        old_diagnostic.registration_id != registration_id
 7399                                            || unchanged_buffers
 7400                                                .get(&old_diagnostic.registration_id)
 7401                                                .is_some_and(|unchanged_buffers| {
 7402                                                    unchanged_buffers.contains(&document_uri)
 7403                                                })
 7404                                    }
 7405                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7406                                        true
 7407                                    }
 7408                                },
 7409                                cx,
 7410                            )
 7411                            .log_err();
 7412                    }
 7413                }
 7414            })
 7415        })
 7416    }
 7417
 7418    pub fn document_colors(
 7419        &mut self,
 7420        known_cache_version: Option<usize>,
 7421        buffer: Entity<Buffer>,
 7422        cx: &mut Context<Self>,
 7423    ) -> Option<DocumentColorTask> {
 7424        let version_queried_for = buffer.read(cx).version();
 7425        let buffer_id = buffer.read(cx).remote_id();
 7426
 7427        let current_language_servers = self.as_local().map(|local| {
 7428            local
 7429                .buffers_opened_in_servers
 7430                .get(&buffer_id)
 7431                .cloned()
 7432                .unwrap_or_default()
 7433        });
 7434
 7435        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7436            if let Some(cached_colors) = &lsp_data.document_colors {
 7437                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7438                    let has_different_servers =
 7439                        current_language_servers.is_some_and(|current_language_servers| {
 7440                            current_language_servers
 7441                                != cached_colors.colors.keys().copied().collect()
 7442                        });
 7443                    if !has_different_servers {
 7444                        let cache_version = cached_colors.cache_version;
 7445                        if Some(cache_version) == known_cache_version {
 7446                            return None;
 7447                        } else {
 7448                            return Some(
 7449                                Task::ready(Ok(DocumentColors {
 7450                                    colors: cached_colors
 7451                                        .colors
 7452                                        .values()
 7453                                        .flatten()
 7454                                        .cloned()
 7455                                        .collect(),
 7456                                    cache_version: Some(cache_version),
 7457                                }))
 7458                                .shared(),
 7459                            );
 7460                        }
 7461                    }
 7462                }
 7463            }
 7464        }
 7465
 7466        let color_lsp_data = self
 7467            .latest_lsp_data(&buffer, cx)
 7468            .document_colors
 7469            .get_or_insert_default();
 7470        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7471            && !version_queried_for.changed_since(updating_for)
 7472        {
 7473            return Some(running_update.clone());
 7474        }
 7475        let buffer_version_queried_for = version_queried_for.clone();
 7476        let new_task = cx
 7477            .spawn(async move |lsp_store, cx| {
 7478                cx.background_executor()
 7479                    .timer(Duration::from_millis(30))
 7480                    .await;
 7481                let fetched_colors = lsp_store
 7482                    .update(cx, |lsp_store, cx| {
 7483                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7484                    })?
 7485                    .await
 7486                    .context("fetching document colors")
 7487                    .map_err(Arc::new);
 7488                let fetched_colors = match fetched_colors {
 7489                    Ok(fetched_colors) => {
 7490                        if Some(true)
 7491                            == buffer
 7492                                .update(cx, |buffer, _| {
 7493                                    buffer.version() != buffer_version_queried_for
 7494                                })
 7495                                .ok()
 7496                        {
 7497                            return Ok(DocumentColors::default());
 7498                        }
 7499                        fetched_colors
 7500                    }
 7501                    Err(e) => {
 7502                        lsp_store
 7503                            .update(cx, |lsp_store, _| {
 7504                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7505                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7506                                        document_colors.colors_update = None;
 7507                                    }
 7508                                }
 7509                            })
 7510                            .ok();
 7511                        return Err(e);
 7512                    }
 7513                };
 7514
 7515                lsp_store
 7516                    .update(cx, |lsp_store, cx| {
 7517                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7518                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7519
 7520                        if let Some(fetched_colors) = fetched_colors {
 7521                            if lsp_data.buffer_version == buffer_version_queried_for {
 7522                                lsp_colors.colors.extend(fetched_colors);
 7523                                lsp_colors.cache_version += 1;
 7524                            } else if !lsp_data
 7525                                .buffer_version
 7526                                .changed_since(&buffer_version_queried_for)
 7527                            {
 7528                                lsp_data.buffer_version = buffer_version_queried_for;
 7529                                lsp_colors.colors = fetched_colors;
 7530                                lsp_colors.cache_version += 1;
 7531                            }
 7532                        }
 7533                        lsp_colors.colors_update = None;
 7534                        let colors = lsp_colors
 7535                            .colors
 7536                            .values()
 7537                            .flatten()
 7538                            .cloned()
 7539                            .collect::<HashSet<_>>();
 7540                        DocumentColors {
 7541                            colors,
 7542                            cache_version: Some(lsp_colors.cache_version),
 7543                        }
 7544                    })
 7545                    .map_err(Arc::new)
 7546            })
 7547            .shared();
 7548        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7549        Some(new_task)
 7550    }
 7551
 7552    fn fetch_document_colors_for_buffer(
 7553        &mut self,
 7554        buffer: &Entity<Buffer>,
 7555        cx: &mut Context<Self>,
 7556    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7557        if let Some((client, project_id)) = self.upstream_client() {
 7558            let request = GetDocumentColor {};
 7559            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7560                return Task::ready(Ok(None));
 7561            }
 7562
 7563            let request_task = client.request_lsp(
 7564                project_id,
 7565                None,
 7566                LSP_REQUEST_TIMEOUT,
 7567                cx.background_executor().clone(),
 7568                request.to_proto(project_id, buffer.read(cx)),
 7569            );
 7570            let buffer = buffer.clone();
 7571            cx.spawn(async move |lsp_store, cx| {
 7572                let Some(lsp_store) = lsp_store.upgrade() else {
 7573                    return Ok(None);
 7574                };
 7575                let colors = join_all(
 7576                    request_task
 7577                        .await
 7578                        .log_err()
 7579                        .flatten()
 7580                        .map(|response| response.payload)
 7581                        .unwrap_or_default()
 7582                        .into_iter()
 7583                        .map(|color_response| {
 7584                            let response = request.response_from_proto(
 7585                                color_response.response,
 7586                                lsp_store.clone(),
 7587                                buffer.clone(),
 7588                                cx.clone(),
 7589                            );
 7590                            async move {
 7591                                (
 7592                                    LanguageServerId::from_proto(color_response.server_id),
 7593                                    response.await.log_err().unwrap_or_default(),
 7594                                )
 7595                            }
 7596                        }),
 7597                )
 7598                .await
 7599                .into_iter()
 7600                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7601                    acc.entry(server_id)
 7602                        .or_insert_with(HashSet::default)
 7603                        .extend(colors);
 7604                    acc
 7605                });
 7606                Ok(Some(colors))
 7607            })
 7608        } else {
 7609            let document_colors_task =
 7610                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7611            cx.background_spawn(async move {
 7612                Ok(Some(
 7613                    document_colors_task
 7614                        .await
 7615                        .into_iter()
 7616                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7617                            acc.entry(server_id)
 7618                                .or_insert_with(HashSet::default)
 7619                                .extend(colors);
 7620                            acc
 7621                        })
 7622                        .into_iter()
 7623                        .collect(),
 7624                ))
 7625            })
 7626        }
 7627    }
 7628
 7629    pub fn signature_help<T: ToPointUtf16>(
 7630        &mut self,
 7631        buffer: &Entity<Buffer>,
 7632        position: T,
 7633        cx: &mut Context<Self>,
 7634    ) -> Task<Option<Vec<SignatureHelp>>> {
 7635        let position = position.to_point_utf16(buffer.read(cx));
 7636
 7637        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7638            let request = GetSignatureHelp { position };
 7639            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7640                return Task::ready(None);
 7641            }
 7642            let request_task = client.request_lsp(
 7643                upstream_project_id,
 7644                None,
 7645                LSP_REQUEST_TIMEOUT,
 7646                cx.background_executor().clone(),
 7647                request.to_proto(upstream_project_id, buffer.read(cx)),
 7648            );
 7649            let buffer = buffer.clone();
 7650            cx.spawn(async move |weak_lsp_store, cx| {
 7651                let lsp_store = weak_lsp_store.upgrade()?;
 7652                let signatures = join_all(
 7653                    request_task
 7654                        .await
 7655                        .log_err()
 7656                        .flatten()
 7657                        .map(|response| response.payload)
 7658                        .unwrap_or_default()
 7659                        .into_iter()
 7660                        .map(|response| {
 7661                            let response = GetSignatureHelp { position }.response_from_proto(
 7662                                response.response,
 7663                                lsp_store.clone(),
 7664                                buffer.clone(),
 7665                                cx.clone(),
 7666                            );
 7667                            async move { response.await.log_err().flatten() }
 7668                        }),
 7669                )
 7670                .await
 7671                .into_iter()
 7672                .flatten()
 7673                .collect();
 7674                Some(signatures)
 7675            })
 7676        } else {
 7677            let all_actions_task = self.request_multiple_lsp_locally(
 7678                buffer,
 7679                Some(position),
 7680                GetSignatureHelp { position },
 7681                cx,
 7682            );
 7683            cx.background_spawn(async move {
 7684                Some(
 7685                    all_actions_task
 7686                        .await
 7687                        .into_iter()
 7688                        .flat_map(|(_, actions)| actions)
 7689                        .collect::<Vec<_>>(),
 7690                )
 7691            })
 7692        }
 7693    }
 7694
 7695    pub fn hover(
 7696        &mut self,
 7697        buffer: &Entity<Buffer>,
 7698        position: PointUtf16,
 7699        cx: &mut Context<Self>,
 7700    ) -> Task<Option<Vec<Hover>>> {
 7701        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7702            let request = GetHover { position };
 7703            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7704                return Task::ready(None);
 7705            }
 7706            let request_task = client.request_lsp(
 7707                upstream_project_id,
 7708                None,
 7709                LSP_REQUEST_TIMEOUT,
 7710                cx.background_executor().clone(),
 7711                request.to_proto(upstream_project_id, buffer.read(cx)),
 7712            );
 7713            let buffer = buffer.clone();
 7714            cx.spawn(async move |weak_lsp_store, cx| {
 7715                let lsp_store = weak_lsp_store.upgrade()?;
 7716                let hovers = join_all(
 7717                    request_task
 7718                        .await
 7719                        .log_err()
 7720                        .flatten()
 7721                        .map(|response| response.payload)
 7722                        .unwrap_or_default()
 7723                        .into_iter()
 7724                        .map(|response| {
 7725                            let response = GetHover { position }.response_from_proto(
 7726                                response.response,
 7727                                lsp_store.clone(),
 7728                                buffer.clone(),
 7729                                cx.clone(),
 7730                            );
 7731                            async move {
 7732                                response
 7733                                    .await
 7734                                    .log_err()
 7735                                    .flatten()
 7736                                    .and_then(remove_empty_hover_blocks)
 7737                            }
 7738                        }),
 7739                )
 7740                .await
 7741                .into_iter()
 7742                .flatten()
 7743                .collect();
 7744                Some(hovers)
 7745            })
 7746        } else {
 7747            let all_actions_task = self.request_multiple_lsp_locally(
 7748                buffer,
 7749                Some(position),
 7750                GetHover { position },
 7751                cx,
 7752            );
 7753            cx.background_spawn(async move {
 7754                Some(
 7755                    all_actions_task
 7756                        .await
 7757                        .into_iter()
 7758                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7759                        .collect::<Vec<Hover>>(),
 7760                )
 7761            })
 7762        }
 7763    }
 7764
 7765    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7766        let language_registry = self.languages.clone();
 7767
 7768        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7769            let request = upstream_client.request(proto::GetProjectSymbols {
 7770                project_id: *project_id,
 7771                query: query.to_string(),
 7772            });
 7773            cx.foreground_executor().spawn(async move {
 7774                let response = request.await?;
 7775                let mut symbols = Vec::new();
 7776                let core_symbols = response
 7777                    .symbols
 7778                    .into_iter()
 7779                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7780                    .collect::<Vec<_>>();
 7781                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7782                    .await;
 7783                Ok(symbols)
 7784            })
 7785        } else if let Some(local) = self.as_local() {
 7786            struct WorkspaceSymbolsResult {
 7787                server_id: LanguageServerId,
 7788                lsp_adapter: Arc<CachedLspAdapter>,
 7789                worktree: WeakEntity<Worktree>,
 7790                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7791            }
 7792
 7793            let mut requests = Vec::new();
 7794            let mut requested_servers = BTreeSet::new();
 7795            for (seed, state) in local.language_server_ids.iter() {
 7796                let Some(worktree_handle) = self
 7797                    .worktree_store
 7798                    .read(cx)
 7799                    .worktree_for_id(seed.worktree_id, cx)
 7800                else {
 7801                    continue;
 7802                };
 7803                let worktree = worktree_handle.read(cx);
 7804                if !worktree.is_visible() {
 7805                    continue;
 7806                }
 7807
 7808                if !requested_servers.insert(state.id) {
 7809                    continue;
 7810                }
 7811
 7812                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7813                    Some(LanguageServerState::Running {
 7814                        adapter, server, ..
 7815                    }) => (adapter.clone(), server),
 7816
 7817                    _ => continue,
 7818                };
 7819                let supports_workspace_symbol_request =
 7820                    match server.capabilities().workspace_symbol_provider {
 7821                        Some(OneOf::Left(supported)) => supported,
 7822                        Some(OneOf::Right(_)) => true,
 7823                        None => false,
 7824                    };
 7825                if !supports_workspace_symbol_request {
 7826                    continue;
 7827                }
 7828                let worktree_handle = worktree_handle.clone();
 7829                let server_id = server.server_id();
 7830                requests.push(
 7831                        server
 7832                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7833                                lsp::WorkspaceSymbolParams {
 7834                                    query: query.to_string(),
 7835                                    ..Default::default()
 7836                                },
 7837                            )
 7838                            .map(move |response| {
 7839                                let lsp_symbols = response.into_response()
 7840                                    .context("workspace symbols request")
 7841                                    .log_err()
 7842                                    .flatten()
 7843                                    .map(|symbol_response| match symbol_response {
 7844                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7845                                            flat_responses.into_iter().map(|lsp_symbol| {
 7846                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7847                                            }).collect::<Vec<_>>()
 7848                                        }
 7849                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7850                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7851                                                let location = match lsp_symbol.location {
 7852                                                    OneOf::Left(location) => location,
 7853                                                    OneOf::Right(_) => {
 7854                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7855                                                        return None
 7856                                                    }
 7857                                                };
 7858                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7859                                            }).collect::<Vec<_>>()
 7860                                        }
 7861                                    }).unwrap_or_default();
 7862
 7863                                WorkspaceSymbolsResult {
 7864                                    server_id,
 7865                                    lsp_adapter,
 7866                                    worktree: worktree_handle.downgrade(),
 7867                                    lsp_symbols,
 7868                                }
 7869                            }),
 7870                    );
 7871            }
 7872
 7873            cx.spawn(async move |this, cx| {
 7874                let responses = futures::future::join_all(requests).await;
 7875                let this = match this.upgrade() {
 7876                    Some(this) => this,
 7877                    None => return Ok(Vec::new()),
 7878                };
 7879
 7880                let mut symbols = Vec::new();
 7881                for result in responses {
 7882                    let core_symbols = this.update(cx, |this, cx| {
 7883                        result
 7884                            .lsp_symbols
 7885                            .into_iter()
 7886                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7887                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7888                                let source_worktree = result.worktree.upgrade()?;
 7889                                let source_worktree_id = source_worktree.read(cx).id();
 7890
 7891                                let path = if let Some((tree, rel_path)) =
 7892                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7893                                {
 7894                                    let worktree_id = tree.read(cx).id();
 7895                                    SymbolLocation::InProject(ProjectPath {
 7896                                        worktree_id,
 7897                                        path: rel_path,
 7898                                    })
 7899                                } else {
 7900                                    SymbolLocation::OutsideProject {
 7901                                        signature: this.symbol_signature(&abs_path),
 7902                                        abs_path: abs_path.into(),
 7903                                    }
 7904                                };
 7905
 7906                                Some(CoreSymbol {
 7907                                    source_language_server_id: result.server_id,
 7908                                    language_server_name: result.lsp_adapter.name.clone(),
 7909                                    source_worktree_id,
 7910                                    path,
 7911                                    kind: symbol_kind,
 7912                                    name: symbol_name,
 7913                                    range: range_from_lsp(symbol_location.range),
 7914                                })
 7915                            })
 7916                            .collect()
 7917                    })?;
 7918
 7919                    populate_labels_for_symbols(
 7920                        core_symbols,
 7921                        &language_registry,
 7922                        Some(result.lsp_adapter),
 7923                        &mut symbols,
 7924                    )
 7925                    .await;
 7926                }
 7927
 7928                Ok(symbols)
 7929            })
 7930        } else {
 7931            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7932        }
 7933    }
 7934
 7935    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7936        let mut summary = DiagnosticSummary::default();
 7937        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7938            summary.error_count += path_summary.error_count;
 7939            summary.warning_count += path_summary.warning_count;
 7940        }
 7941        summary
 7942    }
 7943
 7944    /// Returns the diagnostic summary for a specific project path.
 7945    pub fn diagnostic_summary_for_path(
 7946        &self,
 7947        project_path: &ProjectPath,
 7948        _: &App,
 7949    ) -> DiagnosticSummary {
 7950        if let Some(summaries) = self
 7951            .diagnostic_summaries
 7952            .get(&project_path.worktree_id)
 7953            .and_then(|map| map.get(&project_path.path))
 7954        {
 7955            let (error_count, warning_count) = summaries.iter().fold(
 7956                (0, 0),
 7957                |(error_count, warning_count), (_language_server_id, summary)| {
 7958                    (
 7959                        error_count + summary.error_count,
 7960                        warning_count + summary.warning_count,
 7961                    )
 7962                },
 7963            );
 7964
 7965            DiagnosticSummary {
 7966                error_count,
 7967                warning_count,
 7968            }
 7969        } else {
 7970            DiagnosticSummary::default()
 7971        }
 7972    }
 7973
 7974    pub fn diagnostic_summaries<'a>(
 7975        &'a self,
 7976        include_ignored: bool,
 7977        cx: &'a App,
 7978    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7979        self.worktree_store
 7980            .read(cx)
 7981            .visible_worktrees(cx)
 7982            .filter_map(|worktree| {
 7983                let worktree = worktree.read(cx);
 7984                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7985            })
 7986            .flat_map(move |(worktree, summaries)| {
 7987                let worktree_id = worktree.id();
 7988                summaries
 7989                    .iter()
 7990                    .filter(move |(path, _)| {
 7991                        include_ignored
 7992                            || worktree
 7993                                .entry_for_path(path.as_ref())
 7994                                .is_some_and(|entry| !entry.is_ignored)
 7995                    })
 7996                    .flat_map(move |(path, summaries)| {
 7997                        summaries.iter().map(move |(server_id, summary)| {
 7998                            (
 7999                                ProjectPath {
 8000                                    worktree_id,
 8001                                    path: path.clone(),
 8002                                },
 8003                                *server_id,
 8004                                *summary,
 8005                            )
 8006                        })
 8007                    })
 8008            })
 8009    }
 8010
 8011    pub fn on_buffer_edited(
 8012        &mut self,
 8013        buffer: Entity<Buffer>,
 8014        cx: &mut Context<Self>,
 8015    ) -> Option<()> {
 8016        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 8017            Some(
 8018                self.as_local()?
 8019                    .language_servers_for_buffer(buffer, cx)
 8020                    .map(|i| i.1.clone())
 8021                    .collect(),
 8022            )
 8023        })?;
 8024
 8025        let buffer = buffer.read(cx);
 8026        let file = File::from_dyn(buffer.file())?;
 8027        let abs_path = file.as_local()?.abs_path(cx);
 8028        let uri = lsp::Uri::from_file_path(&abs_path)
 8029            .ok()
 8030            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 8031            .log_err()?;
 8032        let next_snapshot = buffer.text_snapshot();
 8033        for language_server in language_servers {
 8034            let language_server = language_server.clone();
 8035
 8036            let buffer_snapshots = self
 8037                .as_local_mut()?
 8038                .buffer_snapshots
 8039                .get_mut(&buffer.remote_id())
 8040                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 8041            let previous_snapshot = buffer_snapshots.last()?;
 8042
 8043            let build_incremental_change = || {
 8044                buffer
 8045                    .edits_since::<Dimensions<PointUtf16, usize>>(
 8046                        previous_snapshot.snapshot.version(),
 8047                    )
 8048                    .map(|edit| {
 8049                        let edit_start = edit.new.start.0;
 8050                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 8051                        let new_text = next_snapshot
 8052                            .text_for_range(edit.new.start.1..edit.new.end.1)
 8053                            .collect();
 8054                        lsp::TextDocumentContentChangeEvent {
 8055                            range: Some(lsp::Range::new(
 8056                                point_to_lsp(edit_start),
 8057                                point_to_lsp(edit_end),
 8058                            )),
 8059                            range_length: None,
 8060                            text: new_text,
 8061                        }
 8062                    })
 8063                    .collect()
 8064            };
 8065
 8066            let document_sync_kind = language_server
 8067                .capabilities()
 8068                .text_document_sync
 8069                .as_ref()
 8070                .and_then(|sync| match sync {
 8071                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 8072                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 8073                });
 8074
 8075            let content_changes: Vec<_> = match document_sync_kind {
 8076                Some(lsp::TextDocumentSyncKind::FULL) => {
 8077                    vec![lsp::TextDocumentContentChangeEvent {
 8078                        range: None,
 8079                        range_length: None,
 8080                        text: next_snapshot.text(),
 8081                    }]
 8082                }
 8083                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8084                _ => {
 8085                    #[cfg(any(test, feature = "test-support"))]
 8086                    {
 8087                        build_incremental_change()
 8088                    }
 8089
 8090                    #[cfg(not(any(test, feature = "test-support")))]
 8091                    {
 8092                        continue;
 8093                    }
 8094                }
 8095            };
 8096
 8097            let next_version = previous_snapshot.version + 1;
 8098            buffer_snapshots.push(LspBufferSnapshot {
 8099                version: next_version,
 8100                snapshot: next_snapshot.clone(),
 8101            });
 8102
 8103            language_server
 8104                .notify::<lsp::notification::DidChangeTextDocument>(
 8105                    lsp::DidChangeTextDocumentParams {
 8106                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8107                            uri.clone(),
 8108                            next_version,
 8109                        ),
 8110                        content_changes,
 8111                    },
 8112                )
 8113                .ok();
 8114            self.pull_workspace_diagnostics(language_server.server_id());
 8115        }
 8116
 8117        None
 8118    }
 8119
 8120    pub fn on_buffer_saved(
 8121        &mut self,
 8122        buffer: Entity<Buffer>,
 8123        cx: &mut Context<Self>,
 8124    ) -> Option<()> {
 8125        let file = File::from_dyn(buffer.read(cx).file())?;
 8126        let worktree_id = file.worktree_id(cx);
 8127        let abs_path = file.as_local()?.abs_path(cx);
 8128        let text_document = lsp::TextDocumentIdentifier {
 8129            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8130        };
 8131        let local = self.as_local()?;
 8132
 8133        for server in local.language_servers_for_worktree(worktree_id) {
 8134            if let Some(include_text) = include_text(server.as_ref()) {
 8135                let text = if include_text {
 8136                    Some(buffer.read(cx).text())
 8137                } else {
 8138                    None
 8139                };
 8140                server
 8141                    .notify::<lsp::notification::DidSaveTextDocument>(
 8142                        lsp::DidSaveTextDocumentParams {
 8143                            text_document: text_document.clone(),
 8144                            text,
 8145                        },
 8146                    )
 8147                    .ok();
 8148            }
 8149        }
 8150
 8151        let language_servers = buffer.update(cx, |buffer, cx| {
 8152            local.language_server_ids_for_buffer(buffer, cx)
 8153        });
 8154        for language_server_id in language_servers {
 8155            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8156        }
 8157
 8158        None
 8159    }
 8160
 8161    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8162        maybe!(async move {
 8163            let mut refreshed_servers = HashSet::default();
 8164            let servers = lsp_store
 8165                .update(cx, |lsp_store, cx| {
 8166                    let local = lsp_store.as_local()?;
 8167
 8168                    let servers = local
 8169                        .language_server_ids
 8170                        .iter()
 8171                        .filter_map(|(seed, state)| {
 8172                            let worktree = lsp_store
 8173                                .worktree_store
 8174                                .read(cx)
 8175                                .worktree_for_id(seed.worktree_id, cx);
 8176                            let delegate: Arc<dyn LspAdapterDelegate> =
 8177                                worktree.map(|worktree| {
 8178                                    LocalLspAdapterDelegate::new(
 8179                                        local.languages.clone(),
 8180                                        &local.environment,
 8181                                        cx.weak_entity(),
 8182                                        &worktree,
 8183                                        local.http_client.clone(),
 8184                                        local.fs.clone(),
 8185                                        cx,
 8186                                    )
 8187                                })?;
 8188                            let server_id = state.id;
 8189
 8190                            let states = local.language_servers.get(&server_id)?;
 8191
 8192                            match states {
 8193                                LanguageServerState::Starting { .. } => None,
 8194                                LanguageServerState::Running {
 8195                                    adapter, server, ..
 8196                                } => {
 8197                                    let adapter = adapter.clone();
 8198                                    let server = server.clone();
 8199                                    refreshed_servers.insert(server.name());
 8200                                    let toolchain = seed.toolchain.clone();
 8201                                    Some(cx.spawn(async move |_, cx| {
 8202                                        let settings =
 8203                                            LocalLspStore::workspace_configuration_for_adapter(
 8204                                                adapter.adapter.clone(),
 8205                                                &delegate,
 8206                                                toolchain,
 8207                                                None,
 8208                                                cx,
 8209                                            )
 8210                                            .await
 8211                                            .ok()?;
 8212                                        server
 8213                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8214                                                lsp::DidChangeConfigurationParams { settings },
 8215                                            )
 8216                                            .ok()?;
 8217                                        Some(())
 8218                                    }))
 8219                                }
 8220                            }
 8221                        })
 8222                        .collect::<Vec<_>>();
 8223
 8224                    Some(servers)
 8225                })
 8226                .ok()
 8227                .flatten()?;
 8228
 8229            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8230            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8231            // to stop and unregister its language server wrapper.
 8232            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8233            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8234            let _: Vec<Option<()>> = join_all(servers).await;
 8235
 8236            Some(())
 8237        })
 8238        .await;
 8239    }
 8240
 8241    fn maintain_workspace_config(
 8242        external_refresh_requests: watch::Receiver<()>,
 8243        cx: &mut Context<Self>,
 8244    ) -> Task<Result<()>> {
 8245        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8246        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8247
 8248        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8249            *settings_changed_tx.borrow_mut() = ();
 8250        });
 8251
 8252        let mut joint_future =
 8253            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8254        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8255        // - 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).
 8256        // - 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.
 8257        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8258        // - 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,
 8259        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8260        cx.spawn(async move |this, cx| {
 8261            while let Some(()) = joint_future.next().await {
 8262                this.update(cx, |this, cx| {
 8263                    this.refresh_server_tree(cx);
 8264                })
 8265                .ok();
 8266
 8267                Self::refresh_workspace_configurations(&this, cx).await;
 8268            }
 8269
 8270            drop(settings_observation);
 8271            anyhow::Ok(())
 8272        })
 8273    }
 8274
 8275    pub fn running_language_servers_for_local_buffer<'a>(
 8276        &'a self,
 8277        buffer: &Buffer,
 8278        cx: &mut App,
 8279    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8280        let local = self.as_local();
 8281        let language_server_ids = local
 8282            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8283            .unwrap_or_default();
 8284
 8285        language_server_ids
 8286            .into_iter()
 8287            .filter_map(
 8288                move |server_id| match local?.language_servers.get(&server_id)? {
 8289                    LanguageServerState::Running {
 8290                        adapter, server, ..
 8291                    } => Some((adapter, server)),
 8292                    _ => None,
 8293                },
 8294            )
 8295    }
 8296
 8297    pub fn language_servers_for_local_buffer(
 8298        &self,
 8299        buffer: &Buffer,
 8300        cx: &mut App,
 8301    ) -> Vec<LanguageServerId> {
 8302        let local = self.as_local();
 8303        local
 8304            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8305            .unwrap_or_default()
 8306    }
 8307
 8308    pub fn language_server_for_local_buffer<'a>(
 8309        &'a self,
 8310        buffer: &'a Buffer,
 8311        server_id: LanguageServerId,
 8312        cx: &'a mut App,
 8313    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8314        self.as_local()?
 8315            .language_servers_for_buffer(buffer, cx)
 8316            .find(|(_, s)| s.server_id() == server_id)
 8317    }
 8318
 8319    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8320        self.diagnostic_summaries.remove(&id_to_remove);
 8321        if let Some(local) = self.as_local_mut() {
 8322            let to_remove = local.remove_worktree(id_to_remove, cx);
 8323            for server in to_remove {
 8324                self.language_server_statuses.remove(&server);
 8325            }
 8326        }
 8327    }
 8328
 8329    pub fn shared(
 8330        &mut self,
 8331        project_id: u64,
 8332        downstream_client: AnyProtoClient,
 8333        _: &mut Context<Self>,
 8334    ) {
 8335        self.downstream_client = Some((downstream_client.clone(), project_id));
 8336
 8337        for (server_id, status) in &self.language_server_statuses {
 8338            if let Some(server) = self.language_server_for_id(*server_id) {
 8339                downstream_client
 8340                    .send(proto::StartLanguageServer {
 8341                        project_id,
 8342                        server: Some(proto::LanguageServer {
 8343                            id: server_id.to_proto(),
 8344                            name: status.name.to_string(),
 8345                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8346                        }),
 8347                        capabilities: serde_json::to_string(&server.capabilities())
 8348                            .expect("serializing server LSP capabilities"),
 8349                    })
 8350                    .log_err();
 8351            }
 8352        }
 8353    }
 8354
 8355    pub fn disconnected_from_host(&mut self) {
 8356        self.downstream_client.take();
 8357    }
 8358
 8359    pub fn disconnected_from_ssh_remote(&mut self) {
 8360        if let LspStoreMode::Remote(RemoteLspStore {
 8361            upstream_client, ..
 8362        }) = &mut self.mode
 8363        {
 8364            upstream_client.take();
 8365        }
 8366    }
 8367
 8368    pub(crate) fn set_language_server_statuses_from_proto(
 8369        &mut self,
 8370        project: WeakEntity<Project>,
 8371        language_servers: Vec<proto::LanguageServer>,
 8372        server_capabilities: Vec<String>,
 8373        cx: &mut Context<Self>,
 8374    ) {
 8375        let lsp_logs = cx
 8376            .try_global::<GlobalLogStore>()
 8377            .map(|lsp_store| lsp_store.0.clone());
 8378
 8379        self.language_server_statuses = language_servers
 8380            .into_iter()
 8381            .zip(server_capabilities)
 8382            .map(|(server, server_capabilities)| {
 8383                let server_id = LanguageServerId(server.id as usize);
 8384                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8385                    self.lsp_server_capabilities
 8386                        .insert(server_id, server_capabilities);
 8387                }
 8388
 8389                let name = LanguageServerName::from_proto(server.name);
 8390                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8391
 8392                if let Some(lsp_logs) = &lsp_logs {
 8393                    lsp_logs.update(cx, |lsp_logs, cx| {
 8394                        lsp_logs.add_language_server(
 8395                            // Only remote clients get their language servers set from proto
 8396                            LanguageServerKind::Remote {
 8397                                project: project.clone(),
 8398                            },
 8399                            server_id,
 8400                            Some(name.clone()),
 8401                            worktree,
 8402                            None,
 8403                            cx,
 8404                        );
 8405                    });
 8406                }
 8407
 8408                (
 8409                    server_id,
 8410                    LanguageServerStatus {
 8411                        name,
 8412                        server_version: None,
 8413                        pending_work: Default::default(),
 8414                        has_pending_diagnostic_updates: false,
 8415                        progress_tokens: Default::default(),
 8416                        worktree,
 8417                        binary: None,
 8418                        configuration: None,
 8419                        workspace_folders: BTreeSet::new(),
 8420                    },
 8421                )
 8422            })
 8423            .collect();
 8424    }
 8425
 8426    #[cfg(test)]
 8427    pub fn update_diagnostic_entries(
 8428        &mut self,
 8429        server_id: LanguageServerId,
 8430        abs_path: PathBuf,
 8431        result_id: Option<SharedString>,
 8432        version: Option<i32>,
 8433        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8434        cx: &mut Context<Self>,
 8435    ) -> anyhow::Result<()> {
 8436        self.merge_diagnostic_entries(
 8437            vec![DocumentDiagnosticsUpdate {
 8438                diagnostics: DocumentDiagnostics {
 8439                    diagnostics,
 8440                    document_abs_path: abs_path,
 8441                    version,
 8442                },
 8443                result_id,
 8444                server_id,
 8445                disk_based_sources: Cow::Borrowed(&[]),
 8446                registration_id: None,
 8447            }],
 8448            |_, _, _| false,
 8449            cx,
 8450        )?;
 8451        Ok(())
 8452    }
 8453
 8454    pub fn merge_diagnostic_entries<'a>(
 8455        &mut self,
 8456        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8457        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8458        cx: &mut Context<Self>,
 8459    ) -> anyhow::Result<()> {
 8460        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8461        let mut updated_diagnostics_paths = HashMap::default();
 8462        for mut update in diagnostic_updates {
 8463            let abs_path = &update.diagnostics.document_abs_path;
 8464            let server_id = update.server_id;
 8465            let Some((worktree, relative_path)) =
 8466                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8467            else {
 8468                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8469                return Ok(());
 8470            };
 8471
 8472            let worktree_id = worktree.read(cx).id();
 8473            let project_path = ProjectPath {
 8474                worktree_id,
 8475                path: relative_path,
 8476            };
 8477
 8478            let document_uri = lsp::Uri::from_file_path(abs_path)
 8479                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8480            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8481                let snapshot = buffer_handle.read(cx).snapshot();
 8482                let buffer = buffer_handle.read(cx);
 8483                let reused_diagnostics = buffer
 8484                    .buffer_diagnostics(Some(server_id))
 8485                    .iter()
 8486                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8487                    .map(|v| {
 8488                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8489                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8490                        DiagnosticEntry {
 8491                            range: start..end,
 8492                            diagnostic: v.diagnostic.clone(),
 8493                        }
 8494                    })
 8495                    .collect::<Vec<_>>();
 8496
 8497                self.as_local_mut()
 8498                    .context("cannot merge diagnostics on a remote LspStore")?
 8499                    .update_buffer_diagnostics(
 8500                        &buffer_handle,
 8501                        server_id,
 8502                        Some(update.registration_id),
 8503                        update.result_id,
 8504                        update.diagnostics.version,
 8505                        update.diagnostics.diagnostics.clone(),
 8506                        reused_diagnostics.clone(),
 8507                        cx,
 8508                    )?;
 8509
 8510                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8511            } else if let Some(local) = self.as_local() {
 8512                let reused_diagnostics = local
 8513                    .diagnostics
 8514                    .get(&worktree_id)
 8515                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8516                    .and_then(|diagnostics_by_server_id| {
 8517                        diagnostics_by_server_id
 8518                            .binary_search_by_key(&server_id, |e| e.0)
 8519                            .ok()
 8520                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8521                    })
 8522                    .into_iter()
 8523                    .flatten()
 8524                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8525
 8526                update
 8527                    .diagnostics
 8528                    .diagnostics
 8529                    .extend(reused_diagnostics.cloned());
 8530            }
 8531
 8532            let updated = worktree.update(cx, |worktree, cx| {
 8533                self.update_worktree_diagnostics(
 8534                    worktree.id(),
 8535                    server_id,
 8536                    project_path.path.clone(),
 8537                    update.diagnostics.diagnostics,
 8538                    cx,
 8539                )
 8540            })?;
 8541            match updated {
 8542                ControlFlow::Continue(new_summary) => {
 8543                    if let Some((project_id, new_summary)) = new_summary {
 8544                        match &mut diagnostics_summary {
 8545                            Some(diagnostics_summary) => {
 8546                                diagnostics_summary
 8547                                    .more_summaries
 8548                                    .push(proto::DiagnosticSummary {
 8549                                        path: project_path.path.as_ref().to_proto(),
 8550                                        language_server_id: server_id.0 as u64,
 8551                                        error_count: new_summary.error_count,
 8552                                        warning_count: new_summary.warning_count,
 8553                                    })
 8554                            }
 8555                            None => {
 8556                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8557                                    project_id,
 8558                                    worktree_id: worktree_id.to_proto(),
 8559                                    summary: Some(proto::DiagnosticSummary {
 8560                                        path: project_path.path.as_ref().to_proto(),
 8561                                        language_server_id: server_id.0 as u64,
 8562                                        error_count: new_summary.error_count,
 8563                                        warning_count: new_summary.warning_count,
 8564                                    }),
 8565                                    more_summaries: Vec::new(),
 8566                                })
 8567                            }
 8568                        }
 8569                    }
 8570                    updated_diagnostics_paths
 8571                        .entry(server_id)
 8572                        .or_insert_with(Vec::new)
 8573                        .push(project_path);
 8574                }
 8575                ControlFlow::Break(()) => {}
 8576            }
 8577        }
 8578
 8579        if let Some((diagnostics_summary, (downstream_client, _))) =
 8580            diagnostics_summary.zip(self.downstream_client.as_ref())
 8581        {
 8582            downstream_client.send(diagnostics_summary).log_err();
 8583        }
 8584        for (server_id, paths) in updated_diagnostics_paths {
 8585            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8586        }
 8587        Ok(())
 8588    }
 8589
 8590    fn update_worktree_diagnostics(
 8591        &mut self,
 8592        worktree_id: WorktreeId,
 8593        server_id: LanguageServerId,
 8594        path_in_worktree: Arc<RelPath>,
 8595        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8596        _: &mut Context<Worktree>,
 8597    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8598        let local = match &mut self.mode {
 8599            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8600            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8601        };
 8602
 8603        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8604        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8605        let summaries_by_server_id = summaries_for_tree
 8606            .entry(path_in_worktree.clone())
 8607            .or_default();
 8608
 8609        let old_summary = summaries_by_server_id
 8610            .remove(&server_id)
 8611            .unwrap_or_default();
 8612
 8613        let new_summary = DiagnosticSummary::new(&diagnostics);
 8614        if diagnostics.is_empty() {
 8615            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8616            {
 8617                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8618                    diagnostics_by_server_id.remove(ix);
 8619                }
 8620                if diagnostics_by_server_id.is_empty() {
 8621                    diagnostics_for_tree.remove(&path_in_worktree);
 8622                }
 8623            }
 8624        } else {
 8625            summaries_by_server_id.insert(server_id, new_summary);
 8626            let diagnostics_by_server_id = diagnostics_for_tree
 8627                .entry(path_in_worktree.clone())
 8628                .or_default();
 8629            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8630                Ok(ix) => {
 8631                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8632                }
 8633                Err(ix) => {
 8634                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8635                }
 8636            }
 8637        }
 8638
 8639        if !old_summary.is_empty() || !new_summary.is_empty() {
 8640            if let Some((_, project_id)) = &self.downstream_client {
 8641                Ok(ControlFlow::Continue(Some((
 8642                    *project_id,
 8643                    proto::DiagnosticSummary {
 8644                        path: path_in_worktree.to_proto(),
 8645                        language_server_id: server_id.0 as u64,
 8646                        error_count: new_summary.error_count as u32,
 8647                        warning_count: new_summary.warning_count as u32,
 8648                    },
 8649                ))))
 8650            } else {
 8651                Ok(ControlFlow::Continue(None))
 8652            }
 8653        } else {
 8654            Ok(ControlFlow::Break(()))
 8655        }
 8656    }
 8657
 8658    pub fn open_buffer_for_symbol(
 8659        &mut self,
 8660        symbol: &Symbol,
 8661        cx: &mut Context<Self>,
 8662    ) -> Task<Result<Entity<Buffer>>> {
 8663        if let Some((client, project_id)) = self.upstream_client() {
 8664            let request = client.request(proto::OpenBufferForSymbol {
 8665                project_id,
 8666                symbol: Some(Self::serialize_symbol(symbol)),
 8667            });
 8668            cx.spawn(async move |this, cx| {
 8669                let response = request.await?;
 8670                let buffer_id = BufferId::new(response.buffer_id)?;
 8671                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8672                    .await
 8673            })
 8674        } else if let Some(local) = self.as_local() {
 8675            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8676                seed.worktree_id == symbol.source_worktree_id
 8677                    && state.id == symbol.source_language_server_id
 8678                    && symbol.language_server_name == seed.name
 8679            });
 8680            if !is_valid {
 8681                return Task::ready(Err(anyhow!(
 8682                    "language server for worktree and language not found"
 8683                )));
 8684            };
 8685
 8686            let symbol_abs_path = match &symbol.path {
 8687                SymbolLocation::InProject(project_path) => self
 8688                    .worktree_store
 8689                    .read(cx)
 8690                    .absolutize(&project_path, cx)
 8691                    .context("no such worktree"),
 8692                SymbolLocation::OutsideProject {
 8693                    abs_path,
 8694                    signature: _,
 8695                } => Ok(abs_path.to_path_buf()),
 8696            };
 8697            let symbol_abs_path = match symbol_abs_path {
 8698                Ok(abs_path) => abs_path,
 8699                Err(err) => return Task::ready(Err(err)),
 8700            };
 8701            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8702                uri
 8703            } else {
 8704                return Task::ready(Err(anyhow!("invalid symbol path")));
 8705            };
 8706
 8707            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8708        } else {
 8709            Task::ready(Err(anyhow!("no upstream client or local store")))
 8710        }
 8711    }
 8712
 8713    pub(crate) fn open_local_buffer_via_lsp(
 8714        &mut self,
 8715        abs_path: lsp::Uri,
 8716        language_server_id: LanguageServerId,
 8717        cx: &mut Context<Self>,
 8718    ) -> Task<Result<Entity<Buffer>>> {
 8719        cx.spawn(async move |lsp_store, cx| {
 8720            // Escape percent-encoded string.
 8721            let current_scheme = abs_path.scheme().to_owned();
 8722            // Uri is immutable, so we can't modify the scheme
 8723
 8724            let abs_path = abs_path
 8725                .to_file_path()
 8726                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8727            let p = abs_path.clone();
 8728            let yarn_worktree = lsp_store
 8729                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8730                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8731                        cx.spawn(async move |this, cx| {
 8732                            let t = this
 8733                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8734                                .ok()?;
 8735                            t.await
 8736                        })
 8737                    }),
 8738                    None => Task::ready(None),
 8739                })?
 8740                .await;
 8741            let (worktree_root_target, known_relative_path) =
 8742                if let Some((zip_root, relative_path)) = yarn_worktree {
 8743                    (zip_root, Some(relative_path))
 8744                } else {
 8745                    (Arc::<Path>::from(abs_path.as_path()), None)
 8746                };
 8747            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8748                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8749                    worktree_store.find_worktree(&worktree_root_target, cx)
 8750                })
 8751            })?;
 8752            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8753                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8754                (result.0, relative_path, None)
 8755            } else {
 8756                let worktree = lsp_store
 8757                    .update(cx, |lsp_store, cx| {
 8758                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8759                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8760                        })
 8761                    })?
 8762                    .await?;
 8763                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8764                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8765                    lsp_store
 8766                        .update(cx, |lsp_store, cx| {
 8767                            if let Some(local) = lsp_store.as_local_mut() {
 8768                                local.register_language_server_for_invisible_worktree(
 8769                                    &worktree,
 8770                                    language_server_id,
 8771                                    cx,
 8772                                )
 8773                            }
 8774                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8775                                Some(status) => status.worktree,
 8776                                None => None,
 8777                            }
 8778                        })
 8779                        .ok()
 8780                        .flatten()
 8781                        .zip(Some(worktree_root.clone()))
 8782                } else {
 8783                    None
 8784                };
 8785                let relative_path = if let Some(known_path) = known_relative_path {
 8786                    known_path
 8787                } else {
 8788                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8789                        .into_arc()
 8790                };
 8791                (worktree, relative_path, source_ws)
 8792            };
 8793            let project_path = ProjectPath {
 8794                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8795                path: relative_path,
 8796            };
 8797            let buffer = lsp_store
 8798                .update(cx, |lsp_store, cx| {
 8799                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8800                        buffer_store.open_buffer(project_path, cx)
 8801                    })
 8802                })?
 8803                .await?;
 8804            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8805            if let Some((source_ws, worktree_root)) = source_ws {
 8806                buffer.update(cx, |buffer, cx| {
 8807                    let settings = WorktreeSettings::get(
 8808                        Some(
 8809                            (&ProjectPath {
 8810                                worktree_id: source_ws,
 8811                                path: Arc::from(RelPath::empty()),
 8812                            })
 8813                                .into(),
 8814                        ),
 8815                        cx,
 8816                    );
 8817                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8818                    if is_read_only {
 8819                        buffer.set_capability(Capability::ReadOnly, cx);
 8820                    }
 8821                })?;
 8822            }
 8823            Ok(buffer)
 8824        })
 8825    }
 8826
 8827    fn request_multiple_lsp_locally<P, R>(
 8828        &mut self,
 8829        buffer: &Entity<Buffer>,
 8830        position: Option<P>,
 8831        request: R,
 8832        cx: &mut Context<Self>,
 8833    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8834    where
 8835        P: ToOffset,
 8836        R: LspCommand + Clone,
 8837        <R::LspRequest as lsp::request::Request>::Result: Send,
 8838        <R::LspRequest as lsp::request::Request>::Params: Send,
 8839    {
 8840        let Some(local) = self.as_local() else {
 8841            return Task::ready(Vec::new());
 8842        };
 8843
 8844        let snapshot = buffer.read(cx).snapshot();
 8845        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8846
 8847        let server_ids = buffer.update(cx, |buffer, cx| {
 8848            local
 8849                .language_servers_for_buffer(buffer, cx)
 8850                .filter(|(adapter, _)| {
 8851                    scope
 8852                        .as_ref()
 8853                        .map(|scope| scope.language_allowed(&adapter.name))
 8854                        .unwrap_or(true)
 8855                })
 8856                .map(|(_, server)| server.server_id())
 8857                .filter(|server_id| {
 8858                    self.as_local().is_none_or(|local| {
 8859                        local
 8860                            .buffers_opened_in_servers
 8861                            .get(&snapshot.remote_id())
 8862                            .is_some_and(|servers| servers.contains(server_id))
 8863                    })
 8864                })
 8865                .collect::<Vec<_>>()
 8866        });
 8867
 8868        let mut response_results = server_ids
 8869            .into_iter()
 8870            .map(|server_id| {
 8871                let task = self.request_lsp(
 8872                    buffer.clone(),
 8873                    LanguageServerToQuery::Other(server_id),
 8874                    request.clone(),
 8875                    cx,
 8876                );
 8877                async move { (server_id, task.await) }
 8878            })
 8879            .collect::<FuturesUnordered<_>>();
 8880
 8881        cx.background_spawn(async move {
 8882            let mut responses = Vec::with_capacity(response_results.len());
 8883            while let Some((server_id, response_result)) = response_results.next().await {
 8884                match response_result {
 8885                    Ok(response) => responses.push((server_id, response)),
 8886                    // rust-analyzer likes to error with this when its still loading up
 8887                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8888                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8889                }
 8890            }
 8891            responses
 8892        })
 8893    }
 8894
 8895    async fn handle_lsp_get_completions(
 8896        this: Entity<Self>,
 8897        envelope: TypedEnvelope<proto::GetCompletions>,
 8898        mut cx: AsyncApp,
 8899    ) -> Result<proto::GetCompletionsResponse> {
 8900        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8901
 8902        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8903        let buffer_handle = this.update(&mut cx, |this, cx| {
 8904            this.buffer_store.read(cx).get_existing(buffer_id)
 8905        })??;
 8906        let request = GetCompletions::from_proto(
 8907            envelope.payload,
 8908            this.clone(),
 8909            buffer_handle.clone(),
 8910            cx.clone(),
 8911        )
 8912        .await?;
 8913
 8914        let server_to_query = match request.server_id {
 8915            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8916            None => LanguageServerToQuery::FirstCapable,
 8917        };
 8918
 8919        let response = this
 8920            .update(&mut cx, |this, cx| {
 8921                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8922            })?
 8923            .await?;
 8924        this.update(&mut cx, |this, cx| {
 8925            Ok(GetCompletions::response_to_proto(
 8926                response,
 8927                this,
 8928                sender_id,
 8929                &buffer_handle.read(cx).version(),
 8930                cx,
 8931            ))
 8932        })?
 8933    }
 8934
 8935    async fn handle_lsp_command<T: LspCommand>(
 8936        this: Entity<Self>,
 8937        envelope: TypedEnvelope<T::ProtoRequest>,
 8938        mut cx: AsyncApp,
 8939    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8940    where
 8941        <T::LspRequest as lsp::request::Request>::Params: Send,
 8942        <T::LspRequest as lsp::request::Request>::Result: Send,
 8943    {
 8944        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8945        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8946        let buffer_handle = this.update(&mut cx, |this, cx| {
 8947            this.buffer_store.read(cx).get_existing(buffer_id)
 8948        })??;
 8949        let request = T::from_proto(
 8950            envelope.payload,
 8951            this.clone(),
 8952            buffer_handle.clone(),
 8953            cx.clone(),
 8954        )
 8955        .await?;
 8956        let response = this
 8957            .update(&mut cx, |this, cx| {
 8958                this.request_lsp(
 8959                    buffer_handle.clone(),
 8960                    LanguageServerToQuery::FirstCapable,
 8961                    request,
 8962                    cx,
 8963                )
 8964            })?
 8965            .await?;
 8966        this.update(&mut cx, |this, cx| {
 8967            Ok(T::response_to_proto(
 8968                response,
 8969                this,
 8970                sender_id,
 8971                &buffer_handle.read(cx).version(),
 8972                cx,
 8973            ))
 8974        })?
 8975    }
 8976
 8977    async fn handle_lsp_query(
 8978        lsp_store: Entity<Self>,
 8979        envelope: TypedEnvelope<proto::LspQuery>,
 8980        mut cx: AsyncApp,
 8981    ) -> Result<proto::Ack> {
 8982        use proto::lsp_query::Request;
 8983        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8984        let lsp_query = envelope.payload;
 8985        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8986        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8987        match lsp_query.request.context("invalid LSP query request")? {
 8988            Request::GetReferences(get_references) => {
 8989                let position = get_references.position.clone().and_then(deserialize_anchor);
 8990                Self::query_lsp_locally::<GetReferences>(
 8991                    lsp_store,
 8992                    server_id,
 8993                    sender_id,
 8994                    lsp_request_id,
 8995                    get_references,
 8996                    position,
 8997                    &mut cx,
 8998                )
 8999                .await?;
 9000            }
 9001            Request::GetDocumentColor(get_document_color) => {
 9002                Self::query_lsp_locally::<GetDocumentColor>(
 9003                    lsp_store,
 9004                    server_id,
 9005                    sender_id,
 9006                    lsp_request_id,
 9007                    get_document_color,
 9008                    None,
 9009                    &mut cx,
 9010                )
 9011                .await?;
 9012            }
 9013            Request::GetHover(get_hover) => {
 9014                let position = get_hover.position.clone().and_then(deserialize_anchor);
 9015                Self::query_lsp_locally::<GetHover>(
 9016                    lsp_store,
 9017                    server_id,
 9018                    sender_id,
 9019                    lsp_request_id,
 9020                    get_hover,
 9021                    position,
 9022                    &mut cx,
 9023                )
 9024                .await?;
 9025            }
 9026            Request::GetCodeActions(get_code_actions) => {
 9027                Self::query_lsp_locally::<GetCodeActions>(
 9028                    lsp_store,
 9029                    server_id,
 9030                    sender_id,
 9031                    lsp_request_id,
 9032                    get_code_actions,
 9033                    None,
 9034                    &mut cx,
 9035                )
 9036                .await?;
 9037            }
 9038            Request::GetSignatureHelp(get_signature_help) => {
 9039                let position = get_signature_help
 9040                    .position
 9041                    .clone()
 9042                    .and_then(deserialize_anchor);
 9043                Self::query_lsp_locally::<GetSignatureHelp>(
 9044                    lsp_store,
 9045                    server_id,
 9046                    sender_id,
 9047                    lsp_request_id,
 9048                    get_signature_help,
 9049                    position,
 9050                    &mut cx,
 9051                )
 9052                .await?;
 9053            }
 9054            Request::GetCodeLens(get_code_lens) => {
 9055                Self::query_lsp_locally::<GetCodeLens>(
 9056                    lsp_store,
 9057                    server_id,
 9058                    sender_id,
 9059                    lsp_request_id,
 9060                    get_code_lens,
 9061                    None,
 9062                    &mut cx,
 9063                )
 9064                .await?;
 9065            }
 9066            Request::GetDefinition(get_definition) => {
 9067                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9068                Self::query_lsp_locally::<GetDefinitions>(
 9069                    lsp_store,
 9070                    server_id,
 9071                    sender_id,
 9072                    lsp_request_id,
 9073                    get_definition,
 9074                    position,
 9075                    &mut cx,
 9076                )
 9077                .await?;
 9078            }
 9079            Request::GetDeclaration(get_declaration) => {
 9080                let position = get_declaration
 9081                    .position
 9082                    .clone()
 9083                    .and_then(deserialize_anchor);
 9084                Self::query_lsp_locally::<GetDeclarations>(
 9085                    lsp_store,
 9086                    server_id,
 9087                    sender_id,
 9088                    lsp_request_id,
 9089                    get_declaration,
 9090                    position,
 9091                    &mut cx,
 9092                )
 9093                .await?;
 9094            }
 9095            Request::GetTypeDefinition(get_type_definition) => {
 9096                let position = get_type_definition
 9097                    .position
 9098                    .clone()
 9099                    .and_then(deserialize_anchor);
 9100                Self::query_lsp_locally::<GetTypeDefinitions>(
 9101                    lsp_store,
 9102                    server_id,
 9103                    sender_id,
 9104                    lsp_request_id,
 9105                    get_type_definition,
 9106                    position,
 9107                    &mut cx,
 9108                )
 9109                .await?;
 9110            }
 9111            Request::GetImplementation(get_implementation) => {
 9112                let position = get_implementation
 9113                    .position
 9114                    .clone()
 9115                    .and_then(deserialize_anchor);
 9116                Self::query_lsp_locally::<GetImplementations>(
 9117                    lsp_store,
 9118                    server_id,
 9119                    sender_id,
 9120                    lsp_request_id,
 9121                    get_implementation,
 9122                    position,
 9123                    &mut cx,
 9124                )
 9125                .await?;
 9126            }
 9127            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9128                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 9129                let version = deserialize_version(get_document_diagnostics.buffer_version());
 9130                let buffer = lsp_store.update(&mut cx, |this, cx| {
 9131                    this.buffer_store.read(cx).get_existing(buffer_id)
 9132                })??;
 9133                buffer
 9134                    .update(&mut cx, |buffer, _| {
 9135                        buffer.wait_for_version(version.clone())
 9136                    })?
 9137                    .await?;
 9138                lsp_store.update(&mut cx, |lsp_store, cx| {
 9139                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9140                    let key = LspKey {
 9141                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9142                        server_queried: server_id,
 9143                    };
 9144                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9145                    ) {
 9146                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9147                            lsp_requests.clear();
 9148                        };
 9149                    }
 9150
 9151                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 9152                    existing_queries.insert(
 9153                        lsp_request_id,
 9154                        cx.spawn(async move |lsp_store, cx| {
 9155                            let diagnostics_pull = lsp_store
 9156                                .update(cx, |lsp_store, cx| {
 9157                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9158                                })
 9159                                .ok();
 9160                            if let Some(diagnostics_pull) = diagnostics_pull {
 9161                                match diagnostics_pull.await {
 9162                                    Ok(()) => {}
 9163                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9164                                };
 9165                            }
 9166                        }),
 9167                    );
 9168                })?;
 9169            }
 9170            Request::InlayHints(inlay_hints) => {
 9171                let query_start = inlay_hints
 9172                    .start
 9173                    .clone()
 9174                    .and_then(deserialize_anchor)
 9175                    .context("invalid inlay hints range start")?;
 9176                let query_end = inlay_hints
 9177                    .end
 9178                    .clone()
 9179                    .and_then(deserialize_anchor)
 9180                    .context("invalid inlay hints range end")?;
 9181                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9182                    &lsp_store,
 9183                    server_id,
 9184                    lsp_request_id,
 9185                    &inlay_hints,
 9186                    query_start..query_end,
 9187                    &mut cx,
 9188                )
 9189                .await
 9190                .context("preparing inlay hints request")?;
 9191                Self::query_lsp_locally::<InlayHints>(
 9192                    lsp_store,
 9193                    server_id,
 9194                    sender_id,
 9195                    lsp_request_id,
 9196                    inlay_hints,
 9197                    None,
 9198                    &mut cx,
 9199                )
 9200                .await
 9201                .context("querying for inlay hints")?
 9202            }
 9203        }
 9204        Ok(proto::Ack {})
 9205    }
 9206
 9207    async fn handle_lsp_query_response(
 9208        lsp_store: Entity<Self>,
 9209        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9210        cx: AsyncApp,
 9211    ) -> Result<()> {
 9212        lsp_store.read_with(&cx, |lsp_store, _| {
 9213            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9214                upstream_client.handle_lsp_response(envelope.clone());
 9215            }
 9216        })?;
 9217        Ok(())
 9218    }
 9219
 9220    async fn handle_apply_code_action(
 9221        this: Entity<Self>,
 9222        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9223        mut cx: AsyncApp,
 9224    ) -> Result<proto::ApplyCodeActionResponse> {
 9225        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9226        let action =
 9227            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9228        let apply_code_action = this.update(&mut cx, |this, cx| {
 9229            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9230            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9231            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9232        })??;
 9233
 9234        let project_transaction = apply_code_action.await?;
 9235        let project_transaction = this.update(&mut cx, |this, cx| {
 9236            this.buffer_store.update(cx, |buffer_store, cx| {
 9237                buffer_store.serialize_project_transaction_for_peer(
 9238                    project_transaction,
 9239                    sender_id,
 9240                    cx,
 9241                )
 9242            })
 9243        })?;
 9244        Ok(proto::ApplyCodeActionResponse {
 9245            transaction: Some(project_transaction),
 9246        })
 9247    }
 9248
 9249    async fn handle_register_buffer_with_language_servers(
 9250        this: Entity<Self>,
 9251        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9252        mut cx: AsyncApp,
 9253    ) -> Result<proto::Ack> {
 9254        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9255        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9256        this.update(&mut cx, |this, cx| {
 9257            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9258                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9259                    project_id: upstream_project_id,
 9260                    buffer_id: buffer_id.to_proto(),
 9261                    only_servers: envelope.payload.only_servers,
 9262                });
 9263            }
 9264
 9265            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9266                anyhow::bail!("buffer is not open");
 9267            };
 9268
 9269            let handle = this.register_buffer_with_language_servers(
 9270                &buffer,
 9271                envelope
 9272                    .payload
 9273                    .only_servers
 9274                    .into_iter()
 9275                    .filter_map(|selector| {
 9276                        Some(match selector.selector? {
 9277                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9278                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9279                            }
 9280                            proto::language_server_selector::Selector::Name(name) => {
 9281                                LanguageServerSelector::Name(LanguageServerName(
 9282                                    SharedString::from(name),
 9283                                ))
 9284                            }
 9285                        })
 9286                    })
 9287                    .collect(),
 9288                false,
 9289                cx,
 9290            );
 9291            this.buffer_store().update(cx, |buffer_store, _| {
 9292                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9293            });
 9294
 9295            Ok(())
 9296        })??;
 9297        Ok(proto::Ack {})
 9298    }
 9299
 9300    async fn handle_rename_project_entry(
 9301        this: Entity<Self>,
 9302        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9303        mut cx: AsyncApp,
 9304    ) -> Result<proto::ProjectEntryResponse> {
 9305        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9306        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9307        let new_path =
 9308            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9309
 9310        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9311            .update(&mut cx, |this, cx| {
 9312                let (worktree, entry) = this
 9313                    .worktree_store
 9314                    .read(cx)
 9315                    .worktree_and_entry_for_id(entry_id, cx)?;
 9316                let new_worktree = this
 9317                    .worktree_store
 9318                    .read(cx)
 9319                    .worktree_for_id(new_worktree_id, cx)?;
 9320                Some((
 9321                    this.worktree_store.clone(),
 9322                    worktree,
 9323                    new_worktree,
 9324                    entry.clone(),
 9325                ))
 9326            })?
 9327            .context("worktree not found")?;
 9328        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9329            (worktree.absolutize(&old_entry.path), worktree.id())
 9330        })?;
 9331        let new_abs_path =
 9332            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 9333
 9334        let _transaction = Self::will_rename_entry(
 9335            this.downgrade(),
 9336            old_worktree_id,
 9337            &old_abs_path,
 9338            &new_abs_path,
 9339            old_entry.is_dir(),
 9340            cx.clone(),
 9341        )
 9342        .await;
 9343        let response = WorktreeStore::handle_rename_project_entry(
 9344            worktree_store,
 9345            envelope.payload,
 9346            cx.clone(),
 9347        )
 9348        .await;
 9349        this.read_with(&cx, |this, _| {
 9350            this.did_rename_entry(
 9351                old_worktree_id,
 9352                &old_abs_path,
 9353                &new_abs_path,
 9354                old_entry.is_dir(),
 9355            );
 9356        })
 9357        .ok();
 9358        response
 9359    }
 9360
 9361    async fn handle_update_diagnostic_summary(
 9362        this: Entity<Self>,
 9363        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9364        mut cx: AsyncApp,
 9365    ) -> Result<()> {
 9366        this.update(&mut cx, |lsp_store, cx| {
 9367            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9368            let mut updated_diagnostics_paths = HashMap::default();
 9369            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9370            for message_summary in envelope
 9371                .payload
 9372                .summary
 9373                .into_iter()
 9374                .chain(envelope.payload.more_summaries)
 9375            {
 9376                let project_path = ProjectPath {
 9377                    worktree_id,
 9378                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9379                };
 9380                let path = project_path.path.clone();
 9381                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9382                let summary = DiagnosticSummary {
 9383                    error_count: message_summary.error_count as usize,
 9384                    warning_count: message_summary.warning_count as usize,
 9385                };
 9386
 9387                if summary.is_empty() {
 9388                    if let Some(worktree_summaries) =
 9389                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9390                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9391                    {
 9392                        summaries.remove(&server_id);
 9393                        if summaries.is_empty() {
 9394                            worktree_summaries.remove(&path);
 9395                        }
 9396                    }
 9397                } else {
 9398                    lsp_store
 9399                        .diagnostic_summaries
 9400                        .entry(worktree_id)
 9401                        .or_default()
 9402                        .entry(path)
 9403                        .or_default()
 9404                        .insert(server_id, summary);
 9405                }
 9406
 9407                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9408                    match &mut diagnostics_summary {
 9409                        Some(diagnostics_summary) => {
 9410                            diagnostics_summary
 9411                                .more_summaries
 9412                                .push(proto::DiagnosticSummary {
 9413                                    path: project_path.path.as_ref().to_proto(),
 9414                                    language_server_id: server_id.0 as u64,
 9415                                    error_count: summary.error_count as u32,
 9416                                    warning_count: summary.warning_count as u32,
 9417                                })
 9418                        }
 9419                        None => {
 9420                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9421                                project_id: *project_id,
 9422                                worktree_id: worktree_id.to_proto(),
 9423                                summary: Some(proto::DiagnosticSummary {
 9424                                    path: project_path.path.as_ref().to_proto(),
 9425                                    language_server_id: server_id.0 as u64,
 9426                                    error_count: summary.error_count as u32,
 9427                                    warning_count: summary.warning_count as u32,
 9428                                }),
 9429                                more_summaries: Vec::new(),
 9430                            })
 9431                        }
 9432                    }
 9433                }
 9434                updated_diagnostics_paths
 9435                    .entry(server_id)
 9436                    .or_insert_with(Vec::new)
 9437                    .push(project_path);
 9438            }
 9439
 9440            if let Some((diagnostics_summary, (downstream_client, _))) =
 9441                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9442            {
 9443                downstream_client.send(diagnostics_summary).log_err();
 9444            }
 9445            for (server_id, paths) in updated_diagnostics_paths {
 9446                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9447            }
 9448            Ok(())
 9449        })?
 9450    }
 9451
 9452    async fn handle_start_language_server(
 9453        lsp_store: Entity<Self>,
 9454        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9455        mut cx: AsyncApp,
 9456    ) -> Result<()> {
 9457        let server = envelope.payload.server.context("invalid server")?;
 9458        let server_capabilities =
 9459            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9460                .with_context(|| {
 9461                    format!(
 9462                        "incorrect server capabilities {}",
 9463                        envelope.payload.capabilities
 9464                    )
 9465                })?;
 9466        lsp_store.update(&mut cx, |lsp_store, cx| {
 9467            let server_id = LanguageServerId(server.id as usize);
 9468            let server_name = LanguageServerName::from_proto(server.name.clone());
 9469            lsp_store
 9470                .lsp_server_capabilities
 9471                .insert(server_id, server_capabilities);
 9472            lsp_store.language_server_statuses.insert(
 9473                server_id,
 9474                LanguageServerStatus {
 9475                    name: server_name.clone(),
 9476                    server_version: None,
 9477                    pending_work: Default::default(),
 9478                    has_pending_diagnostic_updates: false,
 9479                    progress_tokens: Default::default(),
 9480                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9481                    binary: None,
 9482                    configuration: None,
 9483                    workspace_folders: BTreeSet::new(),
 9484                },
 9485            );
 9486            cx.emit(LspStoreEvent::LanguageServerAdded(
 9487                server_id,
 9488                server_name,
 9489                server.worktree_id.map(WorktreeId::from_proto),
 9490            ));
 9491            cx.notify();
 9492        })?;
 9493        Ok(())
 9494    }
 9495
 9496    async fn handle_update_language_server(
 9497        lsp_store: Entity<Self>,
 9498        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9499        mut cx: AsyncApp,
 9500    ) -> Result<()> {
 9501        lsp_store.update(&mut cx, |lsp_store, cx| {
 9502            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9503
 9504            match envelope.payload.variant.context("invalid variant")? {
 9505                proto::update_language_server::Variant::WorkStart(payload) => {
 9506                    lsp_store.on_lsp_work_start(
 9507                        language_server_id,
 9508                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9509                            .context("invalid progress token value")?,
 9510                        LanguageServerProgress {
 9511                            title: payload.title,
 9512                            is_disk_based_diagnostics_progress: false,
 9513                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9514                            message: payload.message,
 9515                            percentage: payload.percentage.map(|p| p as usize),
 9516                            last_update_at: cx.background_executor().now(),
 9517                        },
 9518                        cx,
 9519                    );
 9520                }
 9521                proto::update_language_server::Variant::WorkProgress(payload) => {
 9522                    lsp_store.on_lsp_work_progress(
 9523                        language_server_id,
 9524                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9525                            .context("invalid progress token value")?,
 9526                        LanguageServerProgress {
 9527                            title: None,
 9528                            is_disk_based_diagnostics_progress: false,
 9529                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9530                            message: payload.message,
 9531                            percentage: payload.percentage.map(|p| p as usize),
 9532                            last_update_at: cx.background_executor().now(),
 9533                        },
 9534                        cx,
 9535                    );
 9536                }
 9537
 9538                proto::update_language_server::Variant::WorkEnd(payload) => {
 9539                    lsp_store.on_lsp_work_end(
 9540                        language_server_id,
 9541                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9542                            .context("invalid progress token value")?,
 9543                        cx,
 9544                    );
 9545                }
 9546
 9547                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9548                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9549                }
 9550
 9551                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9552                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9553                }
 9554
 9555                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9556                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9557                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9558                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9559                        language_server_id,
 9560                        name: envelope
 9561                            .payload
 9562                            .server_name
 9563                            .map(SharedString::new)
 9564                            .map(LanguageServerName),
 9565                        message: non_lsp,
 9566                    });
 9567                }
 9568            }
 9569
 9570            Ok(())
 9571        })?
 9572    }
 9573
 9574    async fn handle_language_server_log(
 9575        this: Entity<Self>,
 9576        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9577        mut cx: AsyncApp,
 9578    ) -> Result<()> {
 9579        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9580        let log_type = envelope
 9581            .payload
 9582            .log_type
 9583            .map(LanguageServerLogType::from_proto)
 9584            .context("invalid language server log type")?;
 9585
 9586        let message = envelope.payload.message;
 9587
 9588        this.update(&mut cx, |_, cx| {
 9589            cx.emit(LspStoreEvent::LanguageServerLog(
 9590                language_server_id,
 9591                log_type,
 9592                message,
 9593            ));
 9594        })
 9595    }
 9596
 9597    async fn handle_lsp_ext_cancel_flycheck(
 9598        lsp_store: Entity<Self>,
 9599        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9600        cx: AsyncApp,
 9601    ) -> Result<proto::Ack> {
 9602        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9603        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9604            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9605                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9606            } else {
 9607                None
 9608            }
 9609        })?;
 9610        if let Some(task) = task {
 9611            task.context("handling lsp ext cancel flycheck")?;
 9612        }
 9613
 9614        Ok(proto::Ack {})
 9615    }
 9616
 9617    async fn handle_lsp_ext_run_flycheck(
 9618        lsp_store: Entity<Self>,
 9619        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9620        mut cx: AsyncApp,
 9621    ) -> Result<proto::Ack> {
 9622        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9623        lsp_store.update(&mut cx, |lsp_store, cx| {
 9624            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9625                let text_document = if envelope.payload.current_file_only {
 9626                    let buffer_id = envelope
 9627                        .payload
 9628                        .buffer_id
 9629                        .map(|id| BufferId::new(id))
 9630                        .transpose()?;
 9631                    buffer_id
 9632                        .and_then(|buffer_id| {
 9633                            lsp_store
 9634                                .buffer_store()
 9635                                .read(cx)
 9636                                .get(buffer_id)
 9637                                .and_then(|buffer| {
 9638                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9639                                })
 9640                                .map(|path| make_text_document_identifier(&path))
 9641                        })
 9642                        .transpose()?
 9643                } else {
 9644                    None
 9645                };
 9646                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9647                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9648                )?;
 9649            }
 9650            anyhow::Ok(())
 9651        })??;
 9652
 9653        Ok(proto::Ack {})
 9654    }
 9655
 9656    async fn handle_lsp_ext_clear_flycheck(
 9657        lsp_store: Entity<Self>,
 9658        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9659        cx: AsyncApp,
 9660    ) -> Result<proto::Ack> {
 9661        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9662        lsp_store
 9663            .read_with(&cx, |lsp_store, _| {
 9664                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9665                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9666                } else {
 9667                    None
 9668                }
 9669            })
 9670            .context("handling lsp ext clear flycheck")?;
 9671
 9672        Ok(proto::Ack {})
 9673    }
 9674
 9675    pub fn disk_based_diagnostics_started(
 9676        &mut self,
 9677        language_server_id: LanguageServerId,
 9678        cx: &mut Context<Self>,
 9679    ) {
 9680        if let Some(language_server_status) =
 9681            self.language_server_statuses.get_mut(&language_server_id)
 9682        {
 9683            language_server_status.has_pending_diagnostic_updates = true;
 9684        }
 9685
 9686        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9687        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9688            language_server_id,
 9689            name: self
 9690                .language_server_adapter_for_id(language_server_id)
 9691                .map(|adapter| adapter.name()),
 9692            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9693                Default::default(),
 9694            ),
 9695        })
 9696    }
 9697
 9698    pub fn disk_based_diagnostics_finished(
 9699        &mut self,
 9700        language_server_id: LanguageServerId,
 9701        cx: &mut Context<Self>,
 9702    ) {
 9703        if let Some(language_server_status) =
 9704            self.language_server_statuses.get_mut(&language_server_id)
 9705        {
 9706            language_server_status.has_pending_diagnostic_updates = false;
 9707        }
 9708
 9709        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9710        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9711            language_server_id,
 9712            name: self
 9713                .language_server_adapter_for_id(language_server_id)
 9714                .map(|adapter| adapter.name()),
 9715            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9716                Default::default(),
 9717            ),
 9718        })
 9719    }
 9720
 9721    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9722    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9723    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9724    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9725    // the language server might take some time to publish diagnostics.
 9726    fn simulate_disk_based_diagnostics_events_if_needed(
 9727        &mut self,
 9728        language_server_id: LanguageServerId,
 9729        cx: &mut Context<Self>,
 9730    ) {
 9731        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9732
 9733        let Some(LanguageServerState::Running {
 9734            simulate_disk_based_diagnostics_completion,
 9735            adapter,
 9736            ..
 9737        }) = self
 9738            .as_local_mut()
 9739            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9740        else {
 9741            return;
 9742        };
 9743
 9744        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9745            return;
 9746        }
 9747
 9748        let prev_task =
 9749            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9750                cx.background_executor()
 9751                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9752                    .await;
 9753
 9754                this.update(cx, |this, cx| {
 9755                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9756
 9757                    if let Some(LanguageServerState::Running {
 9758                        simulate_disk_based_diagnostics_completion,
 9759                        ..
 9760                    }) = this.as_local_mut().and_then(|local_store| {
 9761                        local_store.language_servers.get_mut(&language_server_id)
 9762                    }) {
 9763                        *simulate_disk_based_diagnostics_completion = None;
 9764                    }
 9765                })
 9766                .ok();
 9767            }));
 9768
 9769        if prev_task.is_none() {
 9770            self.disk_based_diagnostics_started(language_server_id, cx);
 9771        }
 9772    }
 9773
 9774    pub fn language_server_statuses(
 9775        &self,
 9776    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9777        self.language_server_statuses
 9778            .iter()
 9779            .map(|(key, value)| (*key, value))
 9780    }
 9781
 9782    pub(super) fn did_rename_entry(
 9783        &self,
 9784        worktree_id: WorktreeId,
 9785        old_path: &Path,
 9786        new_path: &Path,
 9787        is_dir: bool,
 9788    ) {
 9789        maybe!({
 9790            let local_store = self.as_local()?;
 9791
 9792            let old_uri = lsp::Uri::from_file_path(old_path)
 9793                .ok()
 9794                .map(|uri| uri.to_string())?;
 9795            let new_uri = lsp::Uri::from_file_path(new_path)
 9796                .ok()
 9797                .map(|uri| uri.to_string())?;
 9798
 9799            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9800                let Some(filter) = local_store
 9801                    .language_server_paths_watched_for_rename
 9802                    .get(&language_server.server_id())
 9803                else {
 9804                    continue;
 9805                };
 9806
 9807                if filter.should_send_did_rename(&old_uri, is_dir) {
 9808                    language_server
 9809                        .notify::<DidRenameFiles>(RenameFilesParams {
 9810                            files: vec![FileRename {
 9811                                old_uri: old_uri.clone(),
 9812                                new_uri: new_uri.clone(),
 9813                            }],
 9814                        })
 9815                        .ok();
 9816                }
 9817            }
 9818            Some(())
 9819        });
 9820    }
 9821
 9822    pub(super) fn will_rename_entry(
 9823        this: WeakEntity<Self>,
 9824        worktree_id: WorktreeId,
 9825        old_path: &Path,
 9826        new_path: &Path,
 9827        is_dir: bool,
 9828        cx: AsyncApp,
 9829    ) -> Task<ProjectTransaction> {
 9830        let old_uri = lsp::Uri::from_file_path(old_path)
 9831            .ok()
 9832            .map(|uri| uri.to_string());
 9833        let new_uri = lsp::Uri::from_file_path(new_path)
 9834            .ok()
 9835            .map(|uri| uri.to_string());
 9836        cx.spawn(async move |cx| {
 9837            let mut tasks = vec![];
 9838            this.update(cx, |this, cx| {
 9839                let local_store = this.as_local()?;
 9840                let old_uri = old_uri?;
 9841                let new_uri = new_uri?;
 9842                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9843                    let Some(filter) = local_store
 9844                        .language_server_paths_watched_for_rename
 9845                        .get(&language_server.server_id())
 9846                    else {
 9847                        continue;
 9848                    };
 9849
 9850                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9851                        let apply_edit = cx.spawn({
 9852                            let old_uri = old_uri.clone();
 9853                            let new_uri = new_uri.clone();
 9854                            let language_server = language_server.clone();
 9855                            async move |this, cx| {
 9856                                let edit = language_server
 9857                                    .request::<WillRenameFiles>(RenameFilesParams {
 9858                                        files: vec![FileRename { old_uri, new_uri }],
 9859                                    })
 9860                                    .await
 9861                                    .into_response()
 9862                                    .context("will rename files")
 9863                                    .log_err()
 9864                                    .flatten()?;
 9865
 9866                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9867                                    this.upgrade()?,
 9868                                    edit,
 9869                                    false,
 9870                                    language_server.clone(),
 9871                                    cx,
 9872                                )
 9873                                .await
 9874                                .ok()?;
 9875                                Some(transaction)
 9876                            }
 9877                        });
 9878                        tasks.push(apply_edit);
 9879                    }
 9880                }
 9881                Some(())
 9882            })
 9883            .ok()
 9884            .flatten();
 9885            let mut merged_transaction = ProjectTransaction::default();
 9886            for task in tasks {
 9887                // Await on tasks sequentially so that the order of application of edits is deterministic
 9888                // (at least with regards to the order of registration of language servers)
 9889                if let Some(transaction) = task.await {
 9890                    for (buffer, buffer_transaction) in transaction.0 {
 9891                        merged_transaction.0.insert(buffer, buffer_transaction);
 9892                    }
 9893                }
 9894            }
 9895            merged_transaction
 9896        })
 9897    }
 9898
 9899    fn lsp_notify_abs_paths_changed(
 9900        &mut self,
 9901        server_id: LanguageServerId,
 9902        changes: Vec<PathEvent>,
 9903    ) {
 9904        maybe!({
 9905            let server = self.language_server_for_id(server_id)?;
 9906            let changes = changes
 9907                .into_iter()
 9908                .filter_map(|event| {
 9909                    let typ = match event.kind? {
 9910                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9911                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9912                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9913                    };
 9914                    Some(lsp::FileEvent {
 9915                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9916                        typ,
 9917                    })
 9918                })
 9919                .collect::<Vec<_>>();
 9920            if !changes.is_empty() {
 9921                server
 9922                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9923                        lsp::DidChangeWatchedFilesParams { changes },
 9924                    )
 9925                    .ok();
 9926            }
 9927            Some(())
 9928        });
 9929    }
 9930
 9931    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9932        self.as_local()?.language_server_for_id(id)
 9933    }
 9934
 9935    fn on_lsp_progress(
 9936        &mut self,
 9937        progress_params: lsp::ProgressParams,
 9938        language_server_id: LanguageServerId,
 9939        disk_based_diagnostics_progress_token: Option<String>,
 9940        cx: &mut Context<Self>,
 9941    ) {
 9942        match progress_params.value {
 9943            lsp::ProgressParamsValue::WorkDone(progress) => {
 9944                self.handle_work_done_progress(
 9945                    progress,
 9946                    language_server_id,
 9947                    disk_based_diagnostics_progress_token,
 9948                    ProgressToken::from_lsp(progress_params.token),
 9949                    cx,
 9950                );
 9951            }
 9952            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9953                let registration_id = match progress_params.token {
 9954                    lsp::NumberOrString::Number(_) => None,
 9955                    lsp::NumberOrString::String(token) => token
 9956                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9957                        .map(|(_, id)| id.to_owned()),
 9958                };
 9959                if let Some(LanguageServerState::Running {
 9960                    workspace_diagnostics_refresh_tasks,
 9961                    ..
 9962                }) = self
 9963                    .as_local_mut()
 9964                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9965                    && let Some(workspace_diagnostics) =
 9966                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9967                {
 9968                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9969                    self.apply_workspace_diagnostic_report(
 9970                        language_server_id,
 9971                        report,
 9972                        registration_id.map(SharedString::from),
 9973                        cx,
 9974                    )
 9975                }
 9976            }
 9977        }
 9978    }
 9979
 9980    fn handle_work_done_progress(
 9981        &mut self,
 9982        progress: lsp::WorkDoneProgress,
 9983        language_server_id: LanguageServerId,
 9984        disk_based_diagnostics_progress_token: Option<String>,
 9985        token: ProgressToken,
 9986        cx: &mut Context<Self>,
 9987    ) {
 9988        let language_server_status =
 9989            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9990                status
 9991            } else {
 9992                return;
 9993            };
 9994
 9995        if !language_server_status.progress_tokens.contains(&token) {
 9996            return;
 9997        }
 9998
 9999        let is_disk_based_diagnostics_progress =
10000            if let (Some(disk_based_token), ProgressToken::String(token)) =
10001                (&disk_based_diagnostics_progress_token, &token)
10002            {
10003                token.starts_with(disk_based_token)
10004            } else {
10005                false
10006            };
10007
10008        match progress {
10009            lsp::WorkDoneProgress::Begin(report) => {
10010                if is_disk_based_diagnostics_progress {
10011                    self.disk_based_diagnostics_started(language_server_id, cx);
10012                }
10013                self.on_lsp_work_start(
10014                    language_server_id,
10015                    token.clone(),
10016                    LanguageServerProgress {
10017                        title: Some(report.title),
10018                        is_disk_based_diagnostics_progress,
10019                        is_cancellable: report.cancellable.unwrap_or(false),
10020                        message: report.message.clone(),
10021                        percentage: report.percentage.map(|p| p as usize),
10022                        last_update_at: cx.background_executor().now(),
10023                    },
10024                    cx,
10025                );
10026            }
10027            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10028                language_server_id,
10029                token,
10030                LanguageServerProgress {
10031                    title: None,
10032                    is_disk_based_diagnostics_progress,
10033                    is_cancellable: report.cancellable.unwrap_or(false),
10034                    message: report.message,
10035                    percentage: report.percentage.map(|p| p as usize),
10036                    last_update_at: cx.background_executor().now(),
10037                },
10038                cx,
10039            ),
10040            lsp::WorkDoneProgress::End(_) => {
10041                language_server_status.progress_tokens.remove(&token);
10042                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10043                if is_disk_based_diagnostics_progress {
10044                    self.disk_based_diagnostics_finished(language_server_id, cx);
10045                }
10046            }
10047        }
10048    }
10049
10050    fn on_lsp_work_start(
10051        &mut self,
10052        language_server_id: LanguageServerId,
10053        token: ProgressToken,
10054        progress: LanguageServerProgress,
10055        cx: &mut Context<Self>,
10056    ) {
10057        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10058            status.pending_work.insert(token.clone(), progress.clone());
10059            cx.notify();
10060        }
10061        cx.emit(LspStoreEvent::LanguageServerUpdate {
10062            language_server_id,
10063            name: self
10064                .language_server_adapter_for_id(language_server_id)
10065                .map(|adapter| adapter.name()),
10066            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10067                token: Some(token.to_proto()),
10068                title: progress.title,
10069                message: progress.message,
10070                percentage: progress.percentage.map(|p| p as u32),
10071                is_cancellable: Some(progress.is_cancellable),
10072            }),
10073        })
10074    }
10075
10076    fn on_lsp_work_progress(
10077        &mut self,
10078        language_server_id: LanguageServerId,
10079        token: ProgressToken,
10080        progress: LanguageServerProgress,
10081        cx: &mut Context<Self>,
10082    ) {
10083        let mut did_update = false;
10084        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10085            match status.pending_work.entry(token.clone()) {
10086                btree_map::Entry::Vacant(entry) => {
10087                    entry.insert(progress.clone());
10088                    did_update = true;
10089                }
10090                btree_map::Entry::Occupied(mut entry) => {
10091                    let entry = entry.get_mut();
10092                    if (progress.last_update_at - entry.last_update_at)
10093                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10094                    {
10095                        entry.last_update_at = progress.last_update_at;
10096                        if progress.message.is_some() {
10097                            entry.message = progress.message.clone();
10098                        }
10099                        if progress.percentage.is_some() {
10100                            entry.percentage = progress.percentage;
10101                        }
10102                        if progress.is_cancellable != entry.is_cancellable {
10103                            entry.is_cancellable = progress.is_cancellable;
10104                        }
10105                        did_update = true;
10106                    }
10107                }
10108            }
10109        }
10110
10111        if did_update {
10112            cx.emit(LspStoreEvent::LanguageServerUpdate {
10113                language_server_id,
10114                name: self
10115                    .language_server_adapter_for_id(language_server_id)
10116                    .map(|adapter| adapter.name()),
10117                message: proto::update_language_server::Variant::WorkProgress(
10118                    proto::LspWorkProgress {
10119                        token: Some(token.to_proto()),
10120                        message: progress.message,
10121                        percentage: progress.percentage.map(|p| p as u32),
10122                        is_cancellable: Some(progress.is_cancellable),
10123                    },
10124                ),
10125            })
10126        }
10127    }
10128
10129    fn on_lsp_work_end(
10130        &mut self,
10131        language_server_id: LanguageServerId,
10132        token: ProgressToken,
10133        cx: &mut Context<Self>,
10134    ) {
10135        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10136            if let Some(work) = status.pending_work.remove(&token)
10137                && !work.is_disk_based_diagnostics_progress
10138            {
10139                cx.emit(LspStoreEvent::RefreshInlayHints {
10140                    server_id: language_server_id,
10141                    request_id: None,
10142                });
10143            }
10144            cx.notify();
10145        }
10146
10147        cx.emit(LspStoreEvent::LanguageServerUpdate {
10148            language_server_id,
10149            name: self
10150                .language_server_adapter_for_id(language_server_id)
10151                .map(|adapter| adapter.name()),
10152            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10153                token: Some(token.to_proto()),
10154            }),
10155        })
10156    }
10157
10158    pub async fn handle_resolve_completion_documentation(
10159        this: Entity<Self>,
10160        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10161        mut cx: AsyncApp,
10162    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10163        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10164
10165        let completion = this
10166            .read_with(&cx, |this, cx| {
10167                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10168                let server = this
10169                    .language_server_for_id(id)
10170                    .with_context(|| format!("No language server {id}"))?;
10171
10172                anyhow::Ok(cx.background_spawn(async move {
10173                    let can_resolve = server
10174                        .capabilities()
10175                        .completion_provider
10176                        .as_ref()
10177                        .and_then(|options| options.resolve_provider)
10178                        .unwrap_or(false);
10179                    if can_resolve {
10180                        server
10181                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
10182                            .await
10183                            .into_response()
10184                            .context("resolve completion item")
10185                    } else {
10186                        anyhow::Ok(lsp_completion)
10187                    }
10188                }))
10189            })??
10190            .await?;
10191
10192        let mut documentation_is_markdown = false;
10193        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10194        let documentation = match completion.documentation {
10195            Some(lsp::Documentation::String(text)) => text,
10196
10197            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10198                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10199                value
10200            }
10201
10202            _ => String::new(),
10203        };
10204
10205        // If we have a new buffer_id, that means we're talking to a new client
10206        // and want to check for new text_edits in the completion too.
10207        let mut old_replace_start = None;
10208        let mut old_replace_end = None;
10209        let mut old_insert_start = None;
10210        let mut old_insert_end = None;
10211        let mut new_text = String::default();
10212        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10213            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10214                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10215                anyhow::Ok(buffer.read(cx).snapshot())
10216            })??;
10217
10218            if let Some(text_edit) = completion.text_edit.as_ref() {
10219                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10220
10221                if let Some(mut edit) = edit {
10222                    LineEnding::normalize(&mut edit.new_text);
10223
10224                    new_text = edit.new_text;
10225                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10226                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10227                    if let Some(insert_range) = edit.insert_range {
10228                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10229                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10230                    }
10231                }
10232            }
10233        }
10234
10235        Ok(proto::ResolveCompletionDocumentationResponse {
10236            documentation,
10237            documentation_is_markdown,
10238            old_replace_start,
10239            old_replace_end,
10240            new_text,
10241            lsp_completion,
10242            old_insert_start,
10243            old_insert_end,
10244        })
10245    }
10246
10247    async fn handle_on_type_formatting(
10248        this: Entity<Self>,
10249        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10250        mut cx: AsyncApp,
10251    ) -> Result<proto::OnTypeFormattingResponse> {
10252        let on_type_formatting = this.update(&mut cx, |this, cx| {
10253            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10254            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10255            let position = envelope
10256                .payload
10257                .position
10258                .and_then(deserialize_anchor)
10259                .context("invalid position")?;
10260            anyhow::Ok(this.apply_on_type_formatting(
10261                buffer,
10262                position,
10263                envelope.payload.trigger.clone(),
10264                cx,
10265            ))
10266        })??;
10267
10268        let transaction = on_type_formatting
10269            .await?
10270            .as_ref()
10271            .map(language::proto::serialize_transaction);
10272        Ok(proto::OnTypeFormattingResponse { transaction })
10273    }
10274
10275    async fn handle_refresh_inlay_hints(
10276        lsp_store: Entity<Self>,
10277        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10278        mut cx: AsyncApp,
10279    ) -> Result<proto::Ack> {
10280        lsp_store.update(&mut cx, |_, cx| {
10281            cx.emit(LspStoreEvent::RefreshInlayHints {
10282                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10283                request_id: envelope.payload.request_id.map(|id| id as usize),
10284            });
10285        })?;
10286        Ok(proto::Ack {})
10287    }
10288
10289    async fn handle_pull_workspace_diagnostics(
10290        lsp_store: Entity<Self>,
10291        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10292        mut cx: AsyncApp,
10293    ) -> Result<proto::Ack> {
10294        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10295        lsp_store.update(&mut cx, |lsp_store, _| {
10296            lsp_store.pull_workspace_diagnostics(server_id);
10297        })?;
10298        Ok(proto::Ack {})
10299    }
10300
10301    async fn handle_get_color_presentation(
10302        lsp_store: Entity<Self>,
10303        envelope: TypedEnvelope<proto::GetColorPresentation>,
10304        mut cx: AsyncApp,
10305    ) -> Result<proto::GetColorPresentationResponse> {
10306        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10307        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10308            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10309        })??;
10310
10311        let color = envelope
10312            .payload
10313            .color
10314            .context("invalid color resolve request")?;
10315        let start = color
10316            .lsp_range_start
10317            .context("invalid color resolve request")?;
10318        let end = color
10319            .lsp_range_end
10320            .context("invalid color resolve request")?;
10321
10322        let color = DocumentColor {
10323            lsp_range: lsp::Range {
10324                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10325                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10326            },
10327            color: lsp::Color {
10328                red: color.red,
10329                green: color.green,
10330                blue: color.blue,
10331                alpha: color.alpha,
10332            },
10333            resolved: false,
10334            color_presentations: Vec::new(),
10335        };
10336        let resolved_color = lsp_store
10337            .update(&mut cx, |lsp_store, cx| {
10338                lsp_store.resolve_color_presentation(
10339                    color,
10340                    buffer.clone(),
10341                    LanguageServerId(envelope.payload.server_id as usize),
10342                    cx,
10343                )
10344            })?
10345            .await
10346            .context("resolving color presentation")?;
10347
10348        Ok(proto::GetColorPresentationResponse {
10349            presentations: resolved_color
10350                .color_presentations
10351                .into_iter()
10352                .map(|presentation| proto::ColorPresentation {
10353                    label: presentation.label.to_string(),
10354                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10355                    additional_text_edits: presentation
10356                        .additional_text_edits
10357                        .into_iter()
10358                        .map(serialize_lsp_edit)
10359                        .collect(),
10360                })
10361                .collect(),
10362        })
10363    }
10364
10365    async fn handle_resolve_inlay_hint(
10366        lsp_store: Entity<Self>,
10367        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10368        mut cx: AsyncApp,
10369    ) -> Result<proto::ResolveInlayHintResponse> {
10370        let proto_hint = envelope
10371            .payload
10372            .hint
10373            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10374        let hint = InlayHints::proto_to_project_hint(proto_hint)
10375            .context("resolved proto inlay hint conversion")?;
10376        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10377            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10378            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10379        })??;
10380        let response_hint = lsp_store
10381            .update(&mut cx, |lsp_store, cx| {
10382                lsp_store.resolve_inlay_hint(
10383                    hint,
10384                    buffer,
10385                    LanguageServerId(envelope.payload.language_server_id as usize),
10386                    cx,
10387                )
10388            })?
10389            .await
10390            .context("inlay hints fetch")?;
10391        Ok(proto::ResolveInlayHintResponse {
10392            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10393        })
10394    }
10395
10396    async fn handle_refresh_code_lens(
10397        this: Entity<Self>,
10398        _: TypedEnvelope<proto::RefreshCodeLens>,
10399        mut cx: AsyncApp,
10400    ) -> Result<proto::Ack> {
10401        this.update(&mut cx, |_, cx| {
10402            cx.emit(LspStoreEvent::RefreshCodeLens);
10403        })?;
10404        Ok(proto::Ack {})
10405    }
10406
10407    async fn handle_open_buffer_for_symbol(
10408        this: Entity<Self>,
10409        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10410        mut cx: AsyncApp,
10411    ) -> Result<proto::OpenBufferForSymbolResponse> {
10412        let peer_id = envelope.original_sender_id().unwrap_or_default();
10413        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10414        let symbol = Self::deserialize_symbol(symbol)?;
10415        this.read_with(&cx, |this, _| {
10416            if let SymbolLocation::OutsideProject {
10417                abs_path,
10418                signature,
10419            } = &symbol.path
10420            {
10421                let new_signature = this.symbol_signature(&abs_path);
10422                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10423            }
10424            Ok(())
10425        })??;
10426        let buffer = this
10427            .update(&mut cx, |this, cx| {
10428                this.open_buffer_for_symbol(
10429                    &Symbol {
10430                        language_server_name: symbol.language_server_name,
10431                        source_worktree_id: symbol.source_worktree_id,
10432                        source_language_server_id: symbol.source_language_server_id,
10433                        path: symbol.path,
10434                        name: symbol.name,
10435                        kind: symbol.kind,
10436                        range: symbol.range,
10437                        label: CodeLabel::default(),
10438                    },
10439                    cx,
10440                )
10441            })?
10442            .await?;
10443
10444        this.update(&mut cx, |this, cx| {
10445            let is_private = buffer
10446                .read(cx)
10447                .file()
10448                .map(|f| f.is_private())
10449                .unwrap_or_default();
10450            if is_private {
10451                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10452            } else {
10453                this.buffer_store
10454                    .update(cx, |buffer_store, cx| {
10455                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10456                    })
10457                    .detach_and_log_err(cx);
10458                let buffer_id = buffer.read(cx).remote_id().to_proto();
10459                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10460            }
10461        })?
10462    }
10463
10464    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10465        let mut hasher = Sha256::new();
10466        hasher.update(abs_path.to_string_lossy().as_bytes());
10467        hasher.update(self.nonce.to_be_bytes());
10468        hasher.finalize().as_slice().try_into().unwrap()
10469    }
10470
10471    pub async fn handle_get_project_symbols(
10472        this: Entity<Self>,
10473        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10474        mut cx: AsyncApp,
10475    ) -> Result<proto::GetProjectSymbolsResponse> {
10476        let symbols = this
10477            .update(&mut cx, |this, cx| {
10478                this.symbols(&envelope.payload.query, cx)
10479            })?
10480            .await?;
10481
10482        Ok(proto::GetProjectSymbolsResponse {
10483            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10484        })
10485    }
10486
10487    pub async fn handle_restart_language_servers(
10488        this: Entity<Self>,
10489        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10490        mut cx: AsyncApp,
10491    ) -> Result<proto::Ack> {
10492        this.update(&mut cx, |lsp_store, cx| {
10493            let buffers =
10494                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10495            lsp_store.restart_language_servers_for_buffers(
10496                buffers,
10497                envelope
10498                    .payload
10499                    .only_servers
10500                    .into_iter()
10501                    .filter_map(|selector| {
10502                        Some(match selector.selector? {
10503                            proto::language_server_selector::Selector::ServerId(server_id) => {
10504                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10505                            }
10506                            proto::language_server_selector::Selector::Name(name) => {
10507                                LanguageServerSelector::Name(LanguageServerName(
10508                                    SharedString::from(name),
10509                                ))
10510                            }
10511                        })
10512                    })
10513                    .collect(),
10514                cx,
10515            );
10516        })?;
10517
10518        Ok(proto::Ack {})
10519    }
10520
10521    pub async fn handle_stop_language_servers(
10522        lsp_store: Entity<Self>,
10523        envelope: TypedEnvelope<proto::StopLanguageServers>,
10524        mut cx: AsyncApp,
10525    ) -> Result<proto::Ack> {
10526        lsp_store.update(&mut cx, |lsp_store, cx| {
10527            if envelope.payload.all
10528                && envelope.payload.also_servers.is_empty()
10529                && envelope.payload.buffer_ids.is_empty()
10530            {
10531                lsp_store.stop_all_language_servers(cx);
10532            } else {
10533                let buffers =
10534                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10535                lsp_store
10536                    .stop_language_servers_for_buffers(
10537                        buffers,
10538                        envelope
10539                            .payload
10540                            .also_servers
10541                            .into_iter()
10542                            .filter_map(|selector| {
10543                                Some(match selector.selector? {
10544                                    proto::language_server_selector::Selector::ServerId(
10545                                        server_id,
10546                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10547                                        server_id,
10548                                    )),
10549                                    proto::language_server_selector::Selector::Name(name) => {
10550                                        LanguageServerSelector::Name(LanguageServerName(
10551                                            SharedString::from(name),
10552                                        ))
10553                                    }
10554                                })
10555                            })
10556                            .collect(),
10557                        cx,
10558                    )
10559                    .detach_and_log_err(cx);
10560            }
10561        })?;
10562
10563        Ok(proto::Ack {})
10564    }
10565
10566    pub async fn handle_cancel_language_server_work(
10567        lsp_store: Entity<Self>,
10568        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10569        mut cx: AsyncApp,
10570    ) -> Result<proto::Ack> {
10571        lsp_store.update(&mut cx, |lsp_store, cx| {
10572            if let Some(work) = envelope.payload.work {
10573                match work {
10574                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10575                        let buffers =
10576                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10577                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10578                    }
10579                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10580                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10581                        let token = work
10582                            .token
10583                            .map(|token| {
10584                                ProgressToken::from_proto(token)
10585                                    .context("invalid work progress token")
10586                            })
10587                            .transpose()?;
10588                        lsp_store.cancel_language_server_work(server_id, token, cx);
10589                    }
10590                }
10591            }
10592            anyhow::Ok(())
10593        })??;
10594
10595        Ok(proto::Ack {})
10596    }
10597
10598    fn buffer_ids_to_buffers(
10599        &mut self,
10600        buffer_ids: impl Iterator<Item = u64>,
10601        cx: &mut Context<Self>,
10602    ) -> Vec<Entity<Buffer>> {
10603        buffer_ids
10604            .into_iter()
10605            .flat_map(|buffer_id| {
10606                self.buffer_store
10607                    .read(cx)
10608                    .get(BufferId::new(buffer_id).log_err()?)
10609            })
10610            .collect::<Vec<_>>()
10611    }
10612
10613    async fn handle_apply_additional_edits_for_completion(
10614        this: Entity<Self>,
10615        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10616        mut cx: AsyncApp,
10617    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10618        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10619            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10620            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10621            let completion = Self::deserialize_completion(
10622                envelope.payload.completion.context("invalid completion")?,
10623            )?;
10624            anyhow::Ok((buffer, completion))
10625        })??;
10626
10627        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10628            this.apply_additional_edits_for_completion(
10629                buffer,
10630                Rc::new(RefCell::new(Box::new([Completion {
10631                    replace_range: completion.replace_range,
10632                    new_text: completion.new_text,
10633                    source: completion.source,
10634                    documentation: None,
10635                    label: CodeLabel::default(),
10636                    match_start: None,
10637                    snippet_deduplication_key: None,
10638                    insert_text_mode: None,
10639                    icon_path: None,
10640                    confirm: None,
10641                }]))),
10642                0,
10643                false,
10644                cx,
10645            )
10646        })?;
10647
10648        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10649            transaction: apply_additional_edits
10650                .await?
10651                .as_ref()
10652                .map(language::proto::serialize_transaction),
10653        })
10654    }
10655
10656    pub fn last_formatting_failure(&self) -> Option<&str> {
10657        self.last_formatting_failure.as_deref()
10658    }
10659
10660    pub fn reset_last_formatting_failure(&mut self) {
10661        self.last_formatting_failure = None;
10662    }
10663
10664    pub fn environment_for_buffer(
10665        &self,
10666        buffer: &Entity<Buffer>,
10667        cx: &mut Context<Self>,
10668    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10669        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10670            environment.update(cx, |env, cx| {
10671                env.buffer_environment(buffer, &self.worktree_store, cx)
10672            })
10673        } else {
10674            Task::ready(None).shared()
10675        }
10676    }
10677
10678    pub fn format(
10679        &mut self,
10680        buffers: HashSet<Entity<Buffer>>,
10681        target: LspFormatTarget,
10682        push_to_history: bool,
10683        trigger: FormatTrigger,
10684        cx: &mut Context<Self>,
10685    ) -> Task<anyhow::Result<ProjectTransaction>> {
10686        let logger = zlog::scoped!("format");
10687        if self.as_local().is_some() {
10688            zlog::trace!(logger => "Formatting locally");
10689            let logger = zlog::scoped!(logger => "local");
10690            let buffers = buffers
10691                .into_iter()
10692                .map(|buffer_handle| {
10693                    let buffer = buffer_handle.read(cx);
10694                    let buffer_abs_path = File::from_dyn(buffer.file())
10695                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10696
10697                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10698                })
10699                .collect::<Vec<_>>();
10700
10701            cx.spawn(async move |lsp_store, cx| {
10702                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10703
10704                for (handle, abs_path, id) in buffers {
10705                    let env = lsp_store
10706                        .update(cx, |lsp_store, cx| {
10707                            lsp_store.environment_for_buffer(&handle, cx)
10708                        })?
10709                        .await;
10710
10711                    let ranges = match &target {
10712                        LspFormatTarget::Buffers => None,
10713                        LspFormatTarget::Ranges(ranges) => {
10714                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10715                        }
10716                    };
10717
10718                    formattable_buffers.push(FormattableBuffer {
10719                        handle,
10720                        abs_path,
10721                        env,
10722                        ranges,
10723                    });
10724                }
10725                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10726
10727                let format_timer = zlog::time!(logger => "Formatting buffers");
10728                let result = LocalLspStore::format_locally(
10729                    lsp_store.clone(),
10730                    formattable_buffers,
10731                    push_to_history,
10732                    trigger,
10733                    logger,
10734                    cx,
10735                )
10736                .await;
10737                format_timer.end();
10738
10739                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10740
10741                lsp_store.update(cx, |lsp_store, _| {
10742                    lsp_store.update_last_formatting_failure(&result);
10743                })?;
10744
10745                result
10746            })
10747        } else if let Some((client, project_id)) = self.upstream_client() {
10748            zlog::trace!(logger => "Formatting remotely");
10749            let logger = zlog::scoped!(logger => "remote");
10750            // Don't support formatting ranges via remote
10751            match target {
10752                LspFormatTarget::Buffers => {}
10753                LspFormatTarget::Ranges(_) => {
10754                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10755                    return Task::ready(Ok(ProjectTransaction::default()));
10756                }
10757            }
10758
10759            let buffer_store = self.buffer_store();
10760            cx.spawn(async move |lsp_store, cx| {
10761                zlog::trace!(logger => "Sending remote format request");
10762                let request_timer = zlog::time!(logger => "remote format request");
10763                let result = client
10764                    .request(proto::FormatBuffers {
10765                        project_id,
10766                        trigger: trigger as i32,
10767                        buffer_ids: buffers
10768                            .iter()
10769                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10770                            .collect::<Result<_>>()?,
10771                    })
10772                    .await
10773                    .and_then(|result| result.transaction.context("missing transaction"));
10774                request_timer.end();
10775
10776                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10777
10778                lsp_store.update(cx, |lsp_store, _| {
10779                    lsp_store.update_last_formatting_failure(&result);
10780                })?;
10781
10782                let transaction_response = result?;
10783                let _timer = zlog::time!(logger => "deserializing project transaction");
10784                buffer_store
10785                    .update(cx, |buffer_store, cx| {
10786                        buffer_store.deserialize_project_transaction(
10787                            transaction_response,
10788                            push_to_history,
10789                            cx,
10790                        )
10791                    })?
10792                    .await
10793            })
10794        } else {
10795            zlog::trace!(logger => "Not formatting");
10796            Task::ready(Ok(ProjectTransaction::default()))
10797        }
10798    }
10799
10800    async fn handle_format_buffers(
10801        this: Entity<Self>,
10802        envelope: TypedEnvelope<proto::FormatBuffers>,
10803        mut cx: AsyncApp,
10804    ) -> Result<proto::FormatBuffersResponse> {
10805        let sender_id = envelope.original_sender_id().unwrap_or_default();
10806        let format = this.update(&mut cx, |this, cx| {
10807            let mut buffers = HashSet::default();
10808            for buffer_id in &envelope.payload.buffer_ids {
10809                let buffer_id = BufferId::new(*buffer_id)?;
10810                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10811            }
10812            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10813            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10814        })??;
10815
10816        let project_transaction = format.await?;
10817        let project_transaction = this.update(&mut cx, |this, cx| {
10818            this.buffer_store.update(cx, |buffer_store, cx| {
10819                buffer_store.serialize_project_transaction_for_peer(
10820                    project_transaction,
10821                    sender_id,
10822                    cx,
10823                )
10824            })
10825        })?;
10826        Ok(proto::FormatBuffersResponse {
10827            transaction: Some(project_transaction),
10828        })
10829    }
10830
10831    async fn handle_apply_code_action_kind(
10832        this: Entity<Self>,
10833        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10834        mut cx: AsyncApp,
10835    ) -> Result<proto::ApplyCodeActionKindResponse> {
10836        let sender_id = envelope.original_sender_id().unwrap_or_default();
10837        let format = this.update(&mut cx, |this, cx| {
10838            let mut buffers = HashSet::default();
10839            for buffer_id in &envelope.payload.buffer_ids {
10840                let buffer_id = BufferId::new(*buffer_id)?;
10841                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10842            }
10843            let kind = match envelope.payload.kind.as_str() {
10844                "" => CodeActionKind::EMPTY,
10845                "quickfix" => CodeActionKind::QUICKFIX,
10846                "refactor" => CodeActionKind::REFACTOR,
10847                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10848                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10849                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10850                "source" => CodeActionKind::SOURCE,
10851                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10852                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10853                _ => anyhow::bail!(
10854                    "Invalid code action kind {}",
10855                    envelope.payload.kind.as_str()
10856                ),
10857            };
10858            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10859        })??;
10860
10861        let project_transaction = format.await?;
10862        let project_transaction = this.update(&mut cx, |this, cx| {
10863            this.buffer_store.update(cx, |buffer_store, cx| {
10864                buffer_store.serialize_project_transaction_for_peer(
10865                    project_transaction,
10866                    sender_id,
10867                    cx,
10868                )
10869            })
10870        })?;
10871        Ok(proto::ApplyCodeActionKindResponse {
10872            transaction: Some(project_transaction),
10873        })
10874    }
10875
10876    async fn shutdown_language_server(
10877        server_state: Option<LanguageServerState>,
10878        name: LanguageServerName,
10879        cx: &mut AsyncApp,
10880    ) {
10881        let server = match server_state {
10882            Some(LanguageServerState::Starting { startup, .. }) => {
10883                let mut timer = cx
10884                    .background_executor()
10885                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10886                    .fuse();
10887
10888                select! {
10889                    server = startup.fuse() => server,
10890                    () = timer => {
10891                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10892                        None
10893                    },
10894                }
10895            }
10896
10897            Some(LanguageServerState::Running { server, .. }) => Some(server),
10898
10899            None => None,
10900        };
10901
10902        if let Some(server) = server
10903            && let Some(shutdown) = server.shutdown()
10904        {
10905            shutdown.await;
10906        }
10907    }
10908
10909    // Returns a list of all of the worktrees which no longer have a language server and the root path
10910    // for the stopped server
10911    fn stop_local_language_server(
10912        &mut self,
10913        server_id: LanguageServerId,
10914        cx: &mut Context<Self>,
10915    ) -> Task<()> {
10916        let local = match &mut self.mode {
10917            LspStoreMode::Local(local) => local,
10918            _ => {
10919                return Task::ready(());
10920            }
10921        };
10922
10923        // Remove this server ID from all entries in the given worktree.
10924        local
10925            .language_server_ids
10926            .retain(|_, state| state.id != server_id);
10927        self.buffer_store.update(cx, |buffer_store, cx| {
10928            for buffer in buffer_store.buffers() {
10929                buffer.update(cx, |buffer, cx| {
10930                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10931                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10932                });
10933            }
10934        });
10935
10936        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10937            summaries.retain(|path, summaries_by_server_id| {
10938                if summaries_by_server_id.remove(&server_id).is_some() {
10939                    if let Some((client, project_id)) = self.downstream_client.clone() {
10940                        client
10941                            .send(proto::UpdateDiagnosticSummary {
10942                                project_id,
10943                                worktree_id: worktree_id.to_proto(),
10944                                summary: Some(proto::DiagnosticSummary {
10945                                    path: path.as_ref().to_proto(),
10946                                    language_server_id: server_id.0 as u64,
10947                                    error_count: 0,
10948                                    warning_count: 0,
10949                                }),
10950                                more_summaries: Vec::new(),
10951                            })
10952                            .log_err();
10953                    }
10954                    !summaries_by_server_id.is_empty()
10955                } else {
10956                    true
10957                }
10958            });
10959        }
10960
10961        let local = self.as_local_mut().unwrap();
10962        for diagnostics in local.diagnostics.values_mut() {
10963            diagnostics.retain(|_, diagnostics_by_server_id| {
10964                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10965                    diagnostics_by_server_id.remove(ix);
10966                    !diagnostics_by_server_id.is_empty()
10967                } else {
10968                    true
10969                }
10970            });
10971        }
10972        local.language_server_watched_paths.remove(&server_id);
10973
10974        let server_state = local.language_servers.remove(&server_id);
10975        self.cleanup_lsp_data(server_id);
10976        let name = self
10977            .language_server_statuses
10978            .remove(&server_id)
10979            .map(|status| status.name)
10980            .or_else(|| {
10981                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10982                    Some(adapter.name())
10983                } else {
10984                    None
10985                }
10986            });
10987
10988        if let Some(name) = name {
10989            log::info!("stopping language server {name}");
10990            self.languages
10991                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10992            cx.notify();
10993
10994            return cx.spawn(async move |lsp_store, cx| {
10995                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10996                lsp_store
10997                    .update(cx, |lsp_store, cx| {
10998                        lsp_store
10999                            .languages
11000                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
11001                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11002                        cx.notify();
11003                    })
11004                    .ok();
11005            });
11006        }
11007
11008        if server_state.is_some() {
11009            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11010        }
11011        Task::ready(())
11012    }
11013
11014    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
11015        if let Some((client, project_id)) = self.upstream_client() {
11016            let request = client.request(proto::StopLanguageServers {
11017                project_id,
11018                buffer_ids: Vec::new(),
11019                also_servers: Vec::new(),
11020                all: true,
11021            });
11022            cx.background_spawn(request).detach_and_log_err(cx);
11023        } else {
11024            let Some(local) = self.as_local_mut() else {
11025                return;
11026            };
11027            let language_servers_to_stop = local
11028                .language_server_ids
11029                .values()
11030                .map(|state| state.id)
11031                .collect();
11032            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11033            let tasks = language_servers_to_stop
11034                .into_iter()
11035                .map(|server| self.stop_local_language_server(server, cx))
11036                .collect::<Vec<_>>();
11037            cx.background_spawn(async move {
11038                futures::future::join_all(tasks).await;
11039            })
11040            .detach();
11041        }
11042    }
11043
11044    pub fn restart_language_servers_for_buffers(
11045        &mut self,
11046        buffers: Vec<Entity<Buffer>>,
11047        only_restart_servers: HashSet<LanguageServerSelector>,
11048        cx: &mut Context<Self>,
11049    ) {
11050        if let Some((client, project_id)) = self.upstream_client() {
11051            let request = client.request(proto::RestartLanguageServers {
11052                project_id,
11053                buffer_ids: buffers
11054                    .into_iter()
11055                    .map(|b| b.read(cx).remote_id().to_proto())
11056                    .collect(),
11057                only_servers: only_restart_servers
11058                    .into_iter()
11059                    .map(|selector| {
11060                        let selector = match selector {
11061                            LanguageServerSelector::Id(language_server_id) => {
11062                                proto::language_server_selector::Selector::ServerId(
11063                                    language_server_id.to_proto(),
11064                                )
11065                            }
11066                            LanguageServerSelector::Name(language_server_name) => {
11067                                proto::language_server_selector::Selector::Name(
11068                                    language_server_name.to_string(),
11069                                )
11070                            }
11071                        };
11072                        proto::LanguageServerSelector {
11073                            selector: Some(selector),
11074                        }
11075                    })
11076                    .collect(),
11077                all: false,
11078            });
11079            cx.background_spawn(request).detach_and_log_err(cx);
11080        } else {
11081            let stop_task = if only_restart_servers.is_empty() {
11082                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11083            } else {
11084                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11085            };
11086            cx.spawn(async move |lsp_store, cx| {
11087                stop_task.await;
11088                lsp_store
11089                    .update(cx, |lsp_store, cx| {
11090                        for buffer in buffers {
11091                            lsp_store.register_buffer_with_language_servers(
11092                                &buffer,
11093                                only_restart_servers.clone(),
11094                                true,
11095                                cx,
11096                            );
11097                        }
11098                    })
11099                    .ok()
11100            })
11101            .detach();
11102        }
11103    }
11104
11105    pub fn stop_language_servers_for_buffers(
11106        &mut self,
11107        buffers: Vec<Entity<Buffer>>,
11108        also_stop_servers: HashSet<LanguageServerSelector>,
11109        cx: &mut Context<Self>,
11110    ) -> Task<Result<()>> {
11111        if let Some((client, project_id)) = self.upstream_client() {
11112            let request = client.request(proto::StopLanguageServers {
11113                project_id,
11114                buffer_ids: buffers
11115                    .into_iter()
11116                    .map(|b| b.read(cx).remote_id().to_proto())
11117                    .collect(),
11118                also_servers: also_stop_servers
11119                    .into_iter()
11120                    .map(|selector| {
11121                        let selector = match selector {
11122                            LanguageServerSelector::Id(language_server_id) => {
11123                                proto::language_server_selector::Selector::ServerId(
11124                                    language_server_id.to_proto(),
11125                                )
11126                            }
11127                            LanguageServerSelector::Name(language_server_name) => {
11128                                proto::language_server_selector::Selector::Name(
11129                                    language_server_name.to_string(),
11130                                )
11131                            }
11132                        };
11133                        proto::LanguageServerSelector {
11134                            selector: Some(selector),
11135                        }
11136                    })
11137                    .collect(),
11138                all: false,
11139            });
11140            cx.background_spawn(async move {
11141                let _ = request.await?;
11142                Ok(())
11143            })
11144        } else {
11145            let task =
11146                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11147            cx.background_spawn(async move {
11148                task.await;
11149                Ok(())
11150            })
11151        }
11152    }
11153
11154    fn stop_local_language_servers_for_buffers(
11155        &mut self,
11156        buffers: &[Entity<Buffer>],
11157        also_stop_servers: HashSet<LanguageServerSelector>,
11158        cx: &mut Context<Self>,
11159    ) -> Task<()> {
11160        let Some(local) = self.as_local_mut() else {
11161            return Task::ready(());
11162        };
11163        let mut language_server_names_to_stop = BTreeSet::default();
11164        let mut language_servers_to_stop = also_stop_servers
11165            .into_iter()
11166            .flat_map(|selector| match selector {
11167                LanguageServerSelector::Id(id) => Some(id),
11168                LanguageServerSelector::Name(name) => {
11169                    language_server_names_to_stop.insert(name);
11170                    None
11171                }
11172            })
11173            .collect::<BTreeSet<_>>();
11174
11175        let mut covered_worktrees = HashSet::default();
11176        for buffer in buffers {
11177            buffer.update(cx, |buffer, cx| {
11178                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11179                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11180                    && covered_worktrees.insert(worktree_id)
11181                {
11182                    language_server_names_to_stop.retain(|name| {
11183                        let old_ids_count = language_servers_to_stop.len();
11184                        let all_language_servers_with_this_name = local
11185                            .language_server_ids
11186                            .iter()
11187                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11188                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11189                        old_ids_count == language_servers_to_stop.len()
11190                    });
11191                }
11192            });
11193        }
11194        for name in language_server_names_to_stop {
11195            language_servers_to_stop.extend(
11196                local
11197                    .language_server_ids
11198                    .iter()
11199                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11200            );
11201        }
11202
11203        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11204        let tasks = language_servers_to_stop
11205            .into_iter()
11206            .map(|server| self.stop_local_language_server(server, cx))
11207            .collect::<Vec<_>>();
11208
11209        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11210    }
11211
11212    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11213        let (worktree, relative_path) =
11214            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11215
11216        let project_path = ProjectPath {
11217            worktree_id: worktree.read(cx).id(),
11218            path: relative_path,
11219        };
11220
11221        Some(
11222            self.buffer_store()
11223                .read(cx)
11224                .get_by_path(&project_path)?
11225                .read(cx),
11226        )
11227    }
11228
11229    #[cfg(any(test, feature = "test-support"))]
11230    pub fn update_diagnostics(
11231        &mut self,
11232        server_id: LanguageServerId,
11233        diagnostics: lsp::PublishDiagnosticsParams,
11234        result_id: Option<SharedString>,
11235        source_kind: DiagnosticSourceKind,
11236        disk_based_sources: &[String],
11237        cx: &mut Context<Self>,
11238    ) -> Result<()> {
11239        self.merge_lsp_diagnostics(
11240            source_kind,
11241            vec![DocumentDiagnosticsUpdate {
11242                diagnostics,
11243                result_id,
11244                server_id,
11245                disk_based_sources: Cow::Borrowed(disk_based_sources),
11246                registration_id: None,
11247            }],
11248            |_, _, _| false,
11249            cx,
11250        )
11251    }
11252
11253    pub fn merge_lsp_diagnostics(
11254        &mut self,
11255        source_kind: DiagnosticSourceKind,
11256        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11257        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11258        cx: &mut Context<Self>,
11259    ) -> Result<()> {
11260        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11261        let updates = lsp_diagnostics
11262            .into_iter()
11263            .filter_map(|update| {
11264                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11265                Some(DocumentDiagnosticsUpdate {
11266                    diagnostics: self.lsp_to_document_diagnostics(
11267                        abs_path,
11268                        source_kind,
11269                        update.server_id,
11270                        update.diagnostics,
11271                        &update.disk_based_sources,
11272                        update.registration_id.clone(),
11273                    ),
11274                    result_id: update.result_id,
11275                    server_id: update.server_id,
11276                    disk_based_sources: update.disk_based_sources,
11277                    registration_id: update.registration_id,
11278                })
11279            })
11280            .collect();
11281        self.merge_diagnostic_entries(updates, merge, cx)?;
11282        Ok(())
11283    }
11284
11285    fn lsp_to_document_diagnostics(
11286        &mut self,
11287        document_abs_path: PathBuf,
11288        source_kind: DiagnosticSourceKind,
11289        server_id: LanguageServerId,
11290        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11291        disk_based_sources: &[String],
11292        registration_id: Option<SharedString>,
11293    ) -> DocumentDiagnostics {
11294        let mut diagnostics = Vec::default();
11295        let mut primary_diagnostic_group_ids = HashMap::default();
11296        let mut sources_by_group_id = HashMap::default();
11297        let mut supporting_diagnostics = HashMap::default();
11298
11299        let adapter = self.language_server_adapter_for_id(server_id);
11300
11301        // Ensure that primary diagnostics are always the most severe
11302        lsp_diagnostics
11303            .diagnostics
11304            .sort_by_key(|item| item.severity);
11305
11306        for diagnostic in &lsp_diagnostics.diagnostics {
11307            let source = diagnostic.source.as_ref();
11308            let range = range_from_lsp(diagnostic.range);
11309            let is_supporting = diagnostic
11310                .related_information
11311                .as_ref()
11312                .is_some_and(|infos| {
11313                    infos.iter().any(|info| {
11314                        primary_diagnostic_group_ids.contains_key(&(
11315                            source,
11316                            diagnostic.code.clone(),
11317                            range_from_lsp(info.location.range),
11318                        ))
11319                    })
11320                });
11321
11322            let is_unnecessary = diagnostic
11323                .tags
11324                .as_ref()
11325                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11326
11327            let underline = self
11328                .language_server_adapter_for_id(server_id)
11329                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11330
11331            if is_supporting {
11332                supporting_diagnostics.insert(
11333                    (source, diagnostic.code.clone(), range),
11334                    (diagnostic.severity, is_unnecessary),
11335                );
11336            } else {
11337                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11338                let is_disk_based =
11339                    source.is_some_and(|source| disk_based_sources.contains(source));
11340
11341                sources_by_group_id.insert(group_id, source);
11342                primary_diagnostic_group_ids
11343                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11344
11345                diagnostics.push(DiagnosticEntry {
11346                    range,
11347                    diagnostic: Diagnostic {
11348                        source: diagnostic.source.clone(),
11349                        source_kind,
11350                        code: diagnostic.code.clone(),
11351                        code_description: diagnostic
11352                            .code_description
11353                            .as_ref()
11354                            .and_then(|d| d.href.clone()),
11355                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11356                        markdown: adapter.as_ref().and_then(|adapter| {
11357                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11358                        }),
11359                        message: diagnostic.message.trim().to_string(),
11360                        group_id,
11361                        is_primary: true,
11362                        is_disk_based,
11363                        is_unnecessary,
11364                        underline,
11365                        data: diagnostic.data.clone(),
11366                        registration_id: registration_id.clone(),
11367                    },
11368                });
11369                if let Some(infos) = &diagnostic.related_information {
11370                    for info in infos {
11371                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11372                            let range = range_from_lsp(info.location.range);
11373                            diagnostics.push(DiagnosticEntry {
11374                                range,
11375                                diagnostic: Diagnostic {
11376                                    source: diagnostic.source.clone(),
11377                                    source_kind,
11378                                    code: diagnostic.code.clone(),
11379                                    code_description: diagnostic
11380                                        .code_description
11381                                        .as_ref()
11382                                        .and_then(|d| d.href.clone()),
11383                                    severity: DiagnosticSeverity::INFORMATION,
11384                                    markdown: adapter.as_ref().and_then(|adapter| {
11385                                        adapter.diagnostic_message_to_markdown(&info.message)
11386                                    }),
11387                                    message: info.message.trim().to_string(),
11388                                    group_id,
11389                                    is_primary: false,
11390                                    is_disk_based,
11391                                    is_unnecessary: false,
11392                                    underline,
11393                                    data: diagnostic.data.clone(),
11394                                    registration_id: registration_id.clone(),
11395                                },
11396                            });
11397                        }
11398                    }
11399                }
11400            }
11401        }
11402
11403        for entry in &mut diagnostics {
11404            let diagnostic = &mut entry.diagnostic;
11405            if !diagnostic.is_primary {
11406                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11407                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11408                    source,
11409                    diagnostic.code.clone(),
11410                    entry.range.clone(),
11411                )) {
11412                    if let Some(severity) = severity {
11413                        diagnostic.severity = severity;
11414                    }
11415                    diagnostic.is_unnecessary = is_unnecessary;
11416                }
11417            }
11418        }
11419
11420        DocumentDiagnostics {
11421            diagnostics,
11422            document_abs_path,
11423            version: lsp_diagnostics.version,
11424        }
11425    }
11426
11427    fn insert_newly_running_language_server(
11428        &mut self,
11429        adapter: Arc<CachedLspAdapter>,
11430        language_server: Arc<LanguageServer>,
11431        server_id: LanguageServerId,
11432        key: LanguageServerSeed,
11433        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11434        cx: &mut Context<Self>,
11435    ) {
11436        let Some(local) = self.as_local_mut() else {
11437            return;
11438        };
11439        // If the language server for this key doesn't match the server id, don't store the
11440        // server. Which will cause it to be dropped, killing the process
11441        if local
11442            .language_server_ids
11443            .get(&key)
11444            .map(|state| state.id != server_id)
11445            .unwrap_or(false)
11446        {
11447            return;
11448        }
11449
11450        // Update language_servers collection with Running variant of LanguageServerState
11451        // indicating that the server is up and running and ready
11452        let workspace_folders = workspace_folders.lock().clone();
11453        language_server.set_workspace_folders(workspace_folders);
11454
11455        let workspace_diagnostics_refresh_tasks = language_server
11456            .capabilities()
11457            .diagnostic_provider
11458            .and_then(|provider| {
11459                local
11460                    .language_server_dynamic_registrations
11461                    .entry(server_id)
11462                    .or_default()
11463                    .diagnostics
11464                    .entry(None)
11465                    .or_insert(provider.clone());
11466                let workspace_refresher =
11467                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11468
11469                Some((None, workspace_refresher))
11470            })
11471            .into_iter()
11472            .collect();
11473        local.language_servers.insert(
11474            server_id,
11475            LanguageServerState::Running {
11476                workspace_diagnostics_refresh_tasks,
11477                adapter: adapter.clone(),
11478                server: language_server.clone(),
11479                simulate_disk_based_diagnostics_completion: None,
11480            },
11481        );
11482        local
11483            .languages
11484            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11485        if let Some(file_ops_caps) = language_server
11486            .capabilities()
11487            .workspace
11488            .as_ref()
11489            .and_then(|ws| ws.file_operations.as_ref())
11490        {
11491            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11492            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11493            if did_rename_caps.or(will_rename_caps).is_some() {
11494                let watcher = RenamePathsWatchedForServer::default()
11495                    .with_did_rename_patterns(did_rename_caps)
11496                    .with_will_rename_patterns(will_rename_caps);
11497                local
11498                    .language_server_paths_watched_for_rename
11499                    .insert(server_id, watcher);
11500            }
11501        }
11502
11503        self.language_server_statuses.insert(
11504            server_id,
11505            LanguageServerStatus {
11506                name: language_server.name(),
11507                server_version: language_server.version(),
11508                pending_work: Default::default(),
11509                has_pending_diagnostic_updates: false,
11510                progress_tokens: Default::default(),
11511                worktree: Some(key.worktree_id),
11512                binary: Some(language_server.binary().clone()),
11513                configuration: Some(language_server.configuration().clone()),
11514                workspace_folders: language_server.workspace_folders(),
11515            },
11516        );
11517
11518        cx.emit(LspStoreEvent::LanguageServerAdded(
11519            server_id,
11520            language_server.name(),
11521            Some(key.worktree_id),
11522        ));
11523
11524        let server_capabilities = language_server.capabilities();
11525        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11526            downstream_client
11527                .send(proto::StartLanguageServer {
11528                    project_id: *project_id,
11529                    server: Some(proto::LanguageServer {
11530                        id: server_id.to_proto(),
11531                        name: language_server.name().to_string(),
11532                        worktree_id: Some(key.worktree_id.to_proto()),
11533                    }),
11534                    capabilities: serde_json::to_string(&server_capabilities)
11535                        .expect("serializing server LSP capabilities"),
11536                })
11537                .log_err();
11538        }
11539        self.lsp_server_capabilities
11540            .insert(server_id, server_capabilities);
11541
11542        // Tell the language server about every open buffer in the worktree that matches the language.
11543        // Also check for buffers in worktrees that reused this server
11544        let mut worktrees_using_server = vec![key.worktree_id];
11545        if let Some(local) = self.as_local() {
11546            // Find all worktrees that have this server in their language server tree
11547            for (worktree_id, servers) in &local.lsp_tree.instances {
11548                if *worktree_id != key.worktree_id {
11549                    for server_map in servers.roots.values() {
11550                        if server_map
11551                            .values()
11552                            .any(|(node, _)| node.id() == Some(server_id))
11553                        {
11554                            worktrees_using_server.push(*worktree_id);
11555                        }
11556                    }
11557                }
11558            }
11559        }
11560
11561        let mut buffer_paths_registered = Vec::new();
11562        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11563            let mut lsp_adapters = HashMap::default();
11564            for buffer_handle in buffer_store.buffers() {
11565                let buffer = buffer_handle.read(cx);
11566                let file = match File::from_dyn(buffer.file()) {
11567                    Some(file) => file,
11568                    None => continue,
11569                };
11570                let language = match buffer.language() {
11571                    Some(language) => language,
11572                    None => continue,
11573                };
11574
11575                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11576                    || !lsp_adapters
11577                        .entry(language.name())
11578                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11579                        .iter()
11580                        .any(|a| a.name == key.name)
11581                {
11582                    continue;
11583                }
11584                // didOpen
11585                let file = match file.as_local() {
11586                    Some(file) => file,
11587                    None => continue,
11588                };
11589
11590                let local = self.as_local_mut().unwrap();
11591
11592                let buffer_id = buffer.remote_id();
11593                if local.registered_buffers.contains_key(&buffer_id) {
11594                    let versions = local
11595                        .buffer_snapshots
11596                        .entry(buffer_id)
11597                        .or_default()
11598                        .entry(server_id)
11599                        .and_modify(|_| {
11600                            assert!(
11601                            false,
11602                            "There should not be an existing snapshot for a newly inserted buffer"
11603                        )
11604                        })
11605                        .or_insert_with(|| {
11606                            vec![LspBufferSnapshot {
11607                                version: 0,
11608                                snapshot: buffer.text_snapshot(),
11609                            }]
11610                        });
11611
11612                    let snapshot = versions.last().unwrap();
11613                    let version = snapshot.version;
11614                    let initial_snapshot = &snapshot.snapshot;
11615                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11616                    language_server.register_buffer(
11617                        uri,
11618                        adapter.language_id(&language.name()),
11619                        version,
11620                        initial_snapshot.text(),
11621                    );
11622                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11623                    local
11624                        .buffers_opened_in_servers
11625                        .entry(buffer_id)
11626                        .or_default()
11627                        .insert(server_id);
11628                }
11629                buffer_handle.update(cx, |buffer, cx| {
11630                    buffer.set_completion_triggers(
11631                        server_id,
11632                        language_server
11633                            .capabilities()
11634                            .completion_provider
11635                            .as_ref()
11636                            .and_then(|provider| {
11637                                provider
11638                                    .trigger_characters
11639                                    .as_ref()
11640                                    .map(|characters| characters.iter().cloned().collect())
11641                            })
11642                            .unwrap_or_default(),
11643                        cx,
11644                    )
11645                });
11646            }
11647        });
11648
11649        for (buffer_id, abs_path) in buffer_paths_registered {
11650            cx.emit(LspStoreEvent::LanguageServerUpdate {
11651                language_server_id: server_id,
11652                name: Some(adapter.name()),
11653                message: proto::update_language_server::Variant::RegisteredForBuffer(
11654                    proto::RegisteredForBuffer {
11655                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11656                        buffer_id: buffer_id.to_proto(),
11657                    },
11658                ),
11659            });
11660        }
11661
11662        cx.notify();
11663    }
11664
11665    pub fn language_servers_running_disk_based_diagnostics(
11666        &self,
11667    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11668        self.language_server_statuses
11669            .iter()
11670            .filter_map(|(id, status)| {
11671                if status.has_pending_diagnostic_updates {
11672                    Some(*id)
11673                } else {
11674                    None
11675                }
11676            })
11677    }
11678
11679    pub(crate) fn cancel_language_server_work_for_buffers(
11680        &mut self,
11681        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11682        cx: &mut Context<Self>,
11683    ) {
11684        if let Some((client, project_id)) = self.upstream_client() {
11685            let request = client.request(proto::CancelLanguageServerWork {
11686                project_id,
11687                work: Some(proto::cancel_language_server_work::Work::Buffers(
11688                    proto::cancel_language_server_work::Buffers {
11689                        buffer_ids: buffers
11690                            .into_iter()
11691                            .map(|b| b.read(cx).remote_id().to_proto())
11692                            .collect(),
11693                    },
11694                )),
11695            });
11696            cx.background_spawn(request).detach_and_log_err(cx);
11697        } else if let Some(local) = self.as_local() {
11698            let servers = buffers
11699                .into_iter()
11700                .flat_map(|buffer| {
11701                    buffer.update(cx, |buffer, cx| {
11702                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11703                    })
11704                })
11705                .collect::<HashSet<_>>();
11706            for server_id in servers {
11707                self.cancel_language_server_work(server_id, None, cx);
11708            }
11709        }
11710    }
11711
11712    pub(crate) fn cancel_language_server_work(
11713        &mut self,
11714        server_id: LanguageServerId,
11715        token_to_cancel: Option<ProgressToken>,
11716        cx: &mut Context<Self>,
11717    ) {
11718        if let Some(local) = self.as_local() {
11719            let status = self.language_server_statuses.get(&server_id);
11720            let server = local.language_servers.get(&server_id);
11721            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11722            {
11723                for (token, progress) in &status.pending_work {
11724                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11725                        && token != token_to_cancel
11726                    {
11727                        continue;
11728                    }
11729                    if progress.is_cancellable {
11730                        server
11731                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11732                                WorkDoneProgressCancelParams {
11733                                    token: token.to_lsp(),
11734                                },
11735                            )
11736                            .ok();
11737                    }
11738                }
11739            }
11740        } else if let Some((client, project_id)) = self.upstream_client() {
11741            let request = client.request(proto::CancelLanguageServerWork {
11742                project_id,
11743                work: Some(
11744                    proto::cancel_language_server_work::Work::LanguageServerWork(
11745                        proto::cancel_language_server_work::LanguageServerWork {
11746                            language_server_id: server_id.to_proto(),
11747                            token: token_to_cancel.map(|token| token.to_proto()),
11748                        },
11749                    ),
11750                ),
11751            });
11752            cx.background_spawn(request).detach_and_log_err(cx);
11753        }
11754    }
11755
11756    fn register_supplementary_language_server(
11757        &mut self,
11758        id: LanguageServerId,
11759        name: LanguageServerName,
11760        server: Arc<LanguageServer>,
11761        cx: &mut Context<Self>,
11762    ) {
11763        if let Some(local) = self.as_local_mut() {
11764            local
11765                .supplementary_language_servers
11766                .insert(id, (name.clone(), server));
11767            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11768        }
11769    }
11770
11771    fn unregister_supplementary_language_server(
11772        &mut self,
11773        id: LanguageServerId,
11774        cx: &mut Context<Self>,
11775    ) {
11776        if let Some(local) = self.as_local_mut() {
11777            local.supplementary_language_servers.remove(&id);
11778            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11779        }
11780    }
11781
11782    pub(crate) fn supplementary_language_servers(
11783        &self,
11784    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11785        self.as_local().into_iter().flat_map(|local| {
11786            local
11787                .supplementary_language_servers
11788                .iter()
11789                .map(|(id, (name, _))| (*id, name.clone()))
11790        })
11791    }
11792
11793    pub fn language_server_adapter_for_id(
11794        &self,
11795        id: LanguageServerId,
11796    ) -> Option<Arc<CachedLspAdapter>> {
11797        self.as_local()
11798            .and_then(|local| local.language_servers.get(&id))
11799            .and_then(|language_server_state| match language_server_state {
11800                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11801                _ => None,
11802            })
11803    }
11804
11805    pub(super) fn update_local_worktree_language_servers(
11806        &mut self,
11807        worktree_handle: &Entity<Worktree>,
11808        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11809        cx: &mut Context<Self>,
11810    ) {
11811        if changes.is_empty() {
11812            return;
11813        }
11814
11815        let Some(local) = self.as_local() else { return };
11816
11817        local.prettier_store.update(cx, |prettier_store, cx| {
11818            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11819        });
11820
11821        let worktree_id = worktree_handle.read(cx).id();
11822        let mut language_server_ids = local
11823            .language_server_ids
11824            .iter()
11825            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11826            .collect::<Vec<_>>();
11827        language_server_ids.sort();
11828        language_server_ids.dedup();
11829
11830        // let abs_path = worktree_handle.read(cx).abs_path();
11831        for server_id in &language_server_ids {
11832            if let Some(LanguageServerState::Running { server, .. }) =
11833                local.language_servers.get(server_id)
11834                && let Some(watched_paths) = local
11835                    .language_server_watched_paths
11836                    .get(server_id)
11837                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11838            {
11839                let params = lsp::DidChangeWatchedFilesParams {
11840                    changes: changes
11841                        .iter()
11842                        .filter_map(|(path, _, change)| {
11843                            if !watched_paths.is_match(path.as_std_path()) {
11844                                return None;
11845                            }
11846                            let typ = match change {
11847                                PathChange::Loaded => return None,
11848                                PathChange::Added => lsp::FileChangeType::CREATED,
11849                                PathChange::Removed => lsp::FileChangeType::DELETED,
11850                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11851                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11852                            };
11853                            let uri = lsp::Uri::from_file_path(
11854                                worktree_handle.read(cx).absolutize(&path),
11855                            )
11856                            .ok()?;
11857                            Some(lsp::FileEvent { uri, typ })
11858                        })
11859                        .collect(),
11860                };
11861                if !params.changes.is_empty() {
11862                    server
11863                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11864                        .ok();
11865                }
11866            }
11867        }
11868        for (path, _, _) in changes {
11869            if let Some(file_name) = path.file_name()
11870                && local.watched_manifest_filenames.contains(file_name)
11871            {
11872                self.request_workspace_config_refresh();
11873                break;
11874            }
11875        }
11876    }
11877
11878    pub fn wait_for_remote_buffer(
11879        &mut self,
11880        id: BufferId,
11881        cx: &mut Context<Self>,
11882    ) -> Task<Result<Entity<Buffer>>> {
11883        self.buffer_store.update(cx, |buffer_store, cx| {
11884            buffer_store.wait_for_remote_buffer(id, cx)
11885        })
11886    }
11887
11888    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11889        let mut result = proto::Symbol {
11890            language_server_name: symbol.language_server_name.0.to_string(),
11891            source_worktree_id: symbol.source_worktree_id.to_proto(),
11892            language_server_id: symbol.source_language_server_id.to_proto(),
11893            name: symbol.name.clone(),
11894            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11895            start: Some(proto::PointUtf16 {
11896                row: symbol.range.start.0.row,
11897                column: symbol.range.start.0.column,
11898            }),
11899            end: Some(proto::PointUtf16 {
11900                row: symbol.range.end.0.row,
11901                column: symbol.range.end.0.column,
11902            }),
11903            worktree_id: Default::default(),
11904            path: Default::default(),
11905            signature: Default::default(),
11906        };
11907        match &symbol.path {
11908            SymbolLocation::InProject(path) => {
11909                result.worktree_id = path.worktree_id.to_proto();
11910                result.path = path.path.to_proto();
11911            }
11912            SymbolLocation::OutsideProject {
11913                abs_path,
11914                signature,
11915            } => {
11916                result.path = abs_path.to_string_lossy().into_owned();
11917                result.signature = signature.to_vec();
11918            }
11919        }
11920        result
11921    }
11922
11923    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11924        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11925        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11926        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11927
11928        let path = if serialized_symbol.signature.is_empty() {
11929            SymbolLocation::InProject(ProjectPath {
11930                worktree_id,
11931                path: RelPath::from_proto(&serialized_symbol.path)
11932                    .context("invalid symbol path")?,
11933            })
11934        } else {
11935            SymbolLocation::OutsideProject {
11936                abs_path: Path::new(&serialized_symbol.path).into(),
11937                signature: serialized_symbol
11938                    .signature
11939                    .try_into()
11940                    .map_err(|_| anyhow!("invalid signature"))?,
11941            }
11942        };
11943
11944        let start = serialized_symbol.start.context("invalid start")?;
11945        let end = serialized_symbol.end.context("invalid end")?;
11946        Ok(CoreSymbol {
11947            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11948            source_worktree_id,
11949            source_language_server_id: LanguageServerId::from_proto(
11950                serialized_symbol.language_server_id,
11951            ),
11952            path,
11953            name: serialized_symbol.name,
11954            range: Unclipped(PointUtf16::new(start.row, start.column))
11955                ..Unclipped(PointUtf16::new(end.row, end.column)),
11956            kind,
11957        })
11958    }
11959
11960    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11961        let mut serialized_completion = proto::Completion {
11962            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11963            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11964            new_text: completion.new_text.clone(),
11965            ..proto::Completion::default()
11966        };
11967        match &completion.source {
11968            CompletionSource::Lsp {
11969                insert_range,
11970                server_id,
11971                lsp_completion,
11972                lsp_defaults,
11973                resolved,
11974            } => {
11975                let (old_insert_start, old_insert_end) = insert_range
11976                    .as_ref()
11977                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11978                    .unzip();
11979
11980                serialized_completion.old_insert_start = old_insert_start;
11981                serialized_completion.old_insert_end = old_insert_end;
11982                serialized_completion.source = proto::completion::Source::Lsp as i32;
11983                serialized_completion.server_id = server_id.0 as u64;
11984                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11985                serialized_completion.lsp_defaults = lsp_defaults
11986                    .as_deref()
11987                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11988                serialized_completion.resolved = *resolved;
11989            }
11990            CompletionSource::BufferWord {
11991                word_range,
11992                resolved,
11993            } => {
11994                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11995                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11996                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11997                serialized_completion.resolved = *resolved;
11998            }
11999            CompletionSource::Custom => {
12000                serialized_completion.source = proto::completion::Source::Custom as i32;
12001                serialized_completion.resolved = true;
12002            }
12003            CompletionSource::Dap { sort_text } => {
12004                serialized_completion.source = proto::completion::Source::Dap as i32;
12005                serialized_completion.sort_text = Some(sort_text.clone());
12006            }
12007        }
12008
12009        serialized_completion
12010    }
12011
12012    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
12013        let old_replace_start = completion
12014            .old_replace_start
12015            .and_then(deserialize_anchor)
12016            .context("invalid old start")?;
12017        let old_replace_end = completion
12018            .old_replace_end
12019            .and_then(deserialize_anchor)
12020            .context("invalid old end")?;
12021        let insert_range = {
12022            match completion.old_insert_start.zip(completion.old_insert_end) {
12023                Some((start, end)) => {
12024                    let start = deserialize_anchor(start).context("invalid insert old start")?;
12025                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12026                    Some(start..end)
12027                }
12028                None => None,
12029            }
12030        };
12031        Ok(CoreCompletion {
12032            replace_range: old_replace_start..old_replace_end,
12033            new_text: completion.new_text,
12034            source: match proto::completion::Source::from_i32(completion.source) {
12035                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12036                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12037                    insert_range,
12038                    server_id: LanguageServerId::from_proto(completion.server_id),
12039                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12040                    lsp_defaults: completion
12041                        .lsp_defaults
12042                        .as_deref()
12043                        .map(serde_json::from_slice)
12044                        .transpose()?,
12045                    resolved: completion.resolved,
12046                },
12047                Some(proto::completion::Source::BufferWord) => {
12048                    let word_range = completion
12049                        .buffer_word_start
12050                        .and_then(deserialize_anchor)
12051                        .context("invalid buffer word start")?
12052                        ..completion
12053                            .buffer_word_end
12054                            .and_then(deserialize_anchor)
12055                            .context("invalid buffer word end")?;
12056                    CompletionSource::BufferWord {
12057                        word_range,
12058                        resolved: completion.resolved,
12059                    }
12060                }
12061                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12062                    sort_text: completion
12063                        .sort_text
12064                        .context("expected sort text to exist")?,
12065                },
12066                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12067            },
12068        })
12069    }
12070
12071    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12072        let (kind, lsp_action) = match &action.lsp_action {
12073            LspAction::Action(code_action) => (
12074                proto::code_action::Kind::Action as i32,
12075                serde_json::to_vec(code_action).unwrap(),
12076            ),
12077            LspAction::Command(command) => (
12078                proto::code_action::Kind::Command as i32,
12079                serde_json::to_vec(command).unwrap(),
12080            ),
12081            LspAction::CodeLens(code_lens) => (
12082                proto::code_action::Kind::CodeLens as i32,
12083                serde_json::to_vec(code_lens).unwrap(),
12084            ),
12085        };
12086
12087        proto::CodeAction {
12088            server_id: action.server_id.0 as u64,
12089            start: Some(serialize_anchor(&action.range.start)),
12090            end: Some(serialize_anchor(&action.range.end)),
12091            lsp_action,
12092            kind,
12093            resolved: action.resolved,
12094        }
12095    }
12096
12097    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12098        let start = action
12099            .start
12100            .and_then(deserialize_anchor)
12101            .context("invalid start")?;
12102        let end = action
12103            .end
12104            .and_then(deserialize_anchor)
12105            .context("invalid end")?;
12106        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12107            Some(proto::code_action::Kind::Action) => {
12108                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12109            }
12110            Some(proto::code_action::Kind::Command) => {
12111                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12112            }
12113            Some(proto::code_action::Kind::CodeLens) => {
12114                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12115            }
12116            None => anyhow::bail!("Unknown action kind {}", action.kind),
12117        };
12118        Ok(CodeAction {
12119            server_id: LanguageServerId(action.server_id as usize),
12120            range: start..end,
12121            resolved: action.resolved,
12122            lsp_action,
12123        })
12124    }
12125
12126    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12127        match &formatting_result {
12128            Ok(_) => self.last_formatting_failure = None,
12129            Err(error) => {
12130                let error_string = format!("{error:#}");
12131                log::error!("Formatting failed: {error_string}");
12132                self.last_formatting_failure
12133                    .replace(error_string.lines().join(" "));
12134            }
12135        }
12136    }
12137
12138    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12139        self.lsp_server_capabilities.remove(&for_server);
12140        for lsp_data in self.lsp_data.values_mut() {
12141            lsp_data.remove_server_data(for_server);
12142        }
12143        if let Some(local) = self.as_local_mut() {
12144            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12145            local
12146                .workspace_pull_diagnostics_result_ids
12147                .remove(&for_server);
12148            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12149                buffer_servers.remove(&for_server);
12150            }
12151        }
12152    }
12153
12154    pub fn result_id_for_buffer_pull(
12155        &self,
12156        server_id: LanguageServerId,
12157        buffer_id: BufferId,
12158        registration_id: &Option<SharedString>,
12159        cx: &App,
12160    ) -> Option<SharedString> {
12161        let abs_path = self
12162            .buffer_store
12163            .read(cx)
12164            .get(buffer_id)
12165            .and_then(|b| File::from_dyn(b.read(cx).file()))
12166            .map(|f| f.abs_path(cx))?;
12167        self.as_local()?
12168            .buffer_pull_diagnostics_result_ids
12169            .get(&server_id)?
12170            .get(registration_id)?
12171            .get(&abs_path)?
12172            .clone()
12173    }
12174
12175    /// Gets all result_ids for a workspace diagnostics pull request.
12176    /// 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.
12177    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12178    pub fn result_ids_for_workspace_refresh(
12179        &self,
12180        server_id: LanguageServerId,
12181        registration_id: &Option<SharedString>,
12182    ) -> HashMap<PathBuf, SharedString> {
12183        let Some(local) = self.as_local() else {
12184            return HashMap::default();
12185        };
12186        local
12187            .workspace_pull_diagnostics_result_ids
12188            .get(&server_id)
12189            .into_iter()
12190            .filter_map(|diagnostics| diagnostics.get(registration_id))
12191            .flatten()
12192            .filter_map(|(abs_path, result_id)| {
12193                let result_id = local
12194                    .buffer_pull_diagnostics_result_ids
12195                    .get(&server_id)
12196                    .and_then(|buffer_ids_result_ids| {
12197                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12198                    })
12199                    .cloned()
12200                    .flatten()
12201                    .or_else(|| result_id.clone())?;
12202                Some((abs_path.clone(), result_id))
12203            })
12204            .collect()
12205    }
12206
12207    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12208        if let Some(LanguageServerState::Running {
12209            workspace_diagnostics_refresh_tasks,
12210            ..
12211        }) = self
12212            .as_local_mut()
12213            .and_then(|local| local.language_servers.get_mut(&server_id))
12214        {
12215            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12216                diagnostics.refresh_tx.try_send(()).ok();
12217            }
12218        }
12219    }
12220
12221    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12222    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12223    /// which requires refreshing both workspace and document diagnostics.
12224    pub fn pull_document_diagnostics_for_server(
12225        &mut self,
12226        server_id: LanguageServerId,
12227        cx: &mut Context<Self>,
12228    ) {
12229        let buffers_to_pull: Vec<_> = self
12230            .as_local()
12231            .into_iter()
12232            .flat_map(|local| {
12233                self.buffer_store.read(cx).buffers().filter(|buffer| {
12234                    let buffer_id = buffer.read(cx).remote_id();
12235                    local
12236                        .buffers_opened_in_servers
12237                        .get(&buffer_id)
12238                        .is_some_and(|servers| servers.contains(&server_id))
12239                })
12240            })
12241            .collect();
12242
12243        for buffer in buffers_to_pull {
12244            self.pull_diagnostics_for_buffer(buffer, cx)
12245                .detach_and_log_err(cx);
12246        }
12247    }
12248
12249    fn apply_workspace_diagnostic_report(
12250        &mut self,
12251        server_id: LanguageServerId,
12252        report: lsp::WorkspaceDiagnosticReportResult,
12253        registration_id: Option<SharedString>,
12254        cx: &mut Context<Self>,
12255    ) {
12256        let mut workspace_diagnostics =
12257            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12258                report,
12259                server_id,
12260                registration_id,
12261            );
12262        workspace_diagnostics.retain(|d| match &d.diagnostics {
12263            LspPullDiagnostics::Response {
12264                server_id,
12265                registration_id,
12266                ..
12267            } => self.diagnostic_registration_exists(*server_id, registration_id),
12268            LspPullDiagnostics::Default => false,
12269        });
12270        let mut unchanged_buffers = HashMap::default();
12271        let workspace_diagnostics_updates = workspace_diagnostics
12272            .into_iter()
12273            .filter_map(
12274                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12275                    LspPullDiagnostics::Response {
12276                        server_id,
12277                        uri,
12278                        diagnostics,
12279                        registration_id,
12280                    } => Some((
12281                        server_id,
12282                        uri,
12283                        diagnostics,
12284                        workspace_diagnostics.version,
12285                        registration_id,
12286                    )),
12287                    LspPullDiagnostics::Default => None,
12288                },
12289            )
12290            .fold(
12291                HashMap::default(),
12292                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12293                    let (result_id, diagnostics) = match diagnostics {
12294                        PulledDiagnostics::Unchanged { result_id } => {
12295                            unchanged_buffers
12296                                .entry(new_registration_id.clone())
12297                                .or_insert_with(HashSet::default)
12298                                .insert(uri.clone());
12299                            (Some(result_id), Vec::new())
12300                        }
12301                        PulledDiagnostics::Changed {
12302                            result_id,
12303                            diagnostics,
12304                        } => (result_id, diagnostics),
12305                    };
12306                    let disk_based_sources = Cow::Owned(
12307                        self.language_server_adapter_for_id(server_id)
12308                            .as_ref()
12309                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12310                            .unwrap_or(&[])
12311                            .to_vec(),
12312                    );
12313
12314                    let Some(abs_path) = uri.to_file_path().ok() else {
12315                        return acc;
12316                    };
12317                    let Some((worktree, relative_path)) =
12318                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12319                    else {
12320                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12321                        return acc;
12322                    };
12323                    let worktree_id = worktree.read(cx).id();
12324                    let project_path = ProjectPath {
12325                        worktree_id,
12326                        path: relative_path,
12327                    };
12328                    if let Some(local_lsp_store) = self.as_local_mut() {
12329                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12330                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12331                    }
12332                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12333                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12334                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12335                        acc.entry(server_id)
12336                            .or_insert_with(HashMap::default)
12337                            .entry(new_registration_id.clone())
12338                            .or_insert_with(Vec::new)
12339                            .push(DocumentDiagnosticsUpdate {
12340                                server_id,
12341                                diagnostics: lsp::PublishDiagnosticsParams {
12342                                    uri,
12343                                    diagnostics,
12344                                    version,
12345                                },
12346                                result_id,
12347                                disk_based_sources,
12348                                registration_id: new_registration_id,
12349                            });
12350                    }
12351                    acc
12352                },
12353            );
12354
12355        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12356            for (registration_id, diagnostic_updates) in diagnostic_updates {
12357                self.merge_lsp_diagnostics(
12358                    DiagnosticSourceKind::Pulled,
12359                    diagnostic_updates,
12360                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12361                        DiagnosticSourceKind::Pulled => {
12362                            old_diagnostic.registration_id != registration_id
12363                                || unchanged_buffers
12364                                    .get(&old_diagnostic.registration_id)
12365                                    .is_some_and(|unchanged_buffers| {
12366                                        unchanged_buffers.contains(&document_uri)
12367                                    })
12368                        }
12369                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12370                    },
12371                    cx,
12372                )
12373                .log_err();
12374            }
12375        }
12376    }
12377
12378    fn register_server_capabilities(
12379        &mut self,
12380        server_id: LanguageServerId,
12381        params: lsp::RegistrationParams,
12382        cx: &mut Context<Self>,
12383    ) -> anyhow::Result<()> {
12384        let server = self
12385            .language_server_for_id(server_id)
12386            .with_context(|| format!("no server {server_id} found"))?;
12387        for reg in params.registrations {
12388            match reg.method.as_str() {
12389                "workspace/didChangeWatchedFiles" => {
12390                    if let Some(options) = reg.register_options {
12391                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12392                            let caps = serde_json::from_value(options)?;
12393                            local_lsp_store
12394                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12395                            true
12396                        } else {
12397                            false
12398                        };
12399                        if notify {
12400                            notify_server_capabilities_updated(&server, cx);
12401                        }
12402                    }
12403                }
12404                "workspace/didChangeConfiguration" => {
12405                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12406                }
12407                "workspace/didChangeWorkspaceFolders" => {
12408                    // In this case register options is an empty object, we can ignore it
12409                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12410                        supported: Some(true),
12411                        change_notifications: Some(OneOf::Right(reg.id)),
12412                    };
12413                    server.update_capabilities(|capabilities| {
12414                        capabilities
12415                            .workspace
12416                            .get_or_insert_default()
12417                            .workspace_folders = Some(caps);
12418                    });
12419                    notify_server_capabilities_updated(&server, cx);
12420                }
12421                "workspace/symbol" => {
12422                    let options = parse_register_capabilities(reg)?;
12423                    server.update_capabilities(|capabilities| {
12424                        capabilities.workspace_symbol_provider = Some(options);
12425                    });
12426                    notify_server_capabilities_updated(&server, cx);
12427                }
12428                "workspace/fileOperations" => {
12429                    if let Some(options) = reg.register_options {
12430                        let caps = serde_json::from_value(options)?;
12431                        server.update_capabilities(|capabilities| {
12432                            capabilities
12433                                .workspace
12434                                .get_or_insert_default()
12435                                .file_operations = Some(caps);
12436                        });
12437                        notify_server_capabilities_updated(&server, cx);
12438                    }
12439                }
12440                "workspace/executeCommand" => {
12441                    if let Some(options) = reg.register_options {
12442                        let options = serde_json::from_value(options)?;
12443                        server.update_capabilities(|capabilities| {
12444                            capabilities.execute_command_provider = Some(options);
12445                        });
12446                        notify_server_capabilities_updated(&server, cx);
12447                    }
12448                }
12449                "textDocument/rangeFormatting" => {
12450                    let options = parse_register_capabilities(reg)?;
12451                    server.update_capabilities(|capabilities| {
12452                        capabilities.document_range_formatting_provider = Some(options);
12453                    });
12454                    notify_server_capabilities_updated(&server, cx);
12455                }
12456                "textDocument/onTypeFormatting" => {
12457                    if let Some(options) = reg
12458                        .register_options
12459                        .map(serde_json::from_value)
12460                        .transpose()?
12461                    {
12462                        server.update_capabilities(|capabilities| {
12463                            capabilities.document_on_type_formatting_provider = Some(options);
12464                        });
12465                        notify_server_capabilities_updated(&server, cx);
12466                    }
12467                }
12468                "textDocument/formatting" => {
12469                    let options = parse_register_capabilities(reg)?;
12470                    server.update_capabilities(|capabilities| {
12471                        capabilities.document_formatting_provider = Some(options);
12472                    });
12473                    notify_server_capabilities_updated(&server, cx);
12474                }
12475                "textDocument/rename" => {
12476                    let options = parse_register_capabilities(reg)?;
12477                    server.update_capabilities(|capabilities| {
12478                        capabilities.rename_provider = Some(options);
12479                    });
12480                    notify_server_capabilities_updated(&server, cx);
12481                }
12482                "textDocument/inlayHint" => {
12483                    let options = parse_register_capabilities(reg)?;
12484                    server.update_capabilities(|capabilities| {
12485                        capabilities.inlay_hint_provider = Some(options);
12486                    });
12487                    notify_server_capabilities_updated(&server, cx);
12488                }
12489                "textDocument/documentSymbol" => {
12490                    let options = parse_register_capabilities(reg)?;
12491                    server.update_capabilities(|capabilities| {
12492                        capabilities.document_symbol_provider = Some(options);
12493                    });
12494                    notify_server_capabilities_updated(&server, cx);
12495                }
12496                "textDocument/codeAction" => {
12497                    let options = parse_register_capabilities(reg)?;
12498                    let provider = match options {
12499                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12500                        OneOf::Right(caps) => caps,
12501                    };
12502                    server.update_capabilities(|capabilities| {
12503                        capabilities.code_action_provider = Some(provider);
12504                    });
12505                    notify_server_capabilities_updated(&server, cx);
12506                }
12507                "textDocument/definition" => {
12508                    let options = parse_register_capabilities(reg)?;
12509                    server.update_capabilities(|capabilities| {
12510                        capabilities.definition_provider = Some(options);
12511                    });
12512                    notify_server_capabilities_updated(&server, cx);
12513                }
12514                "textDocument/completion" => {
12515                    if let Some(caps) = reg
12516                        .register_options
12517                        .map(serde_json::from_value::<CompletionOptions>)
12518                        .transpose()?
12519                    {
12520                        server.update_capabilities(|capabilities| {
12521                            capabilities.completion_provider = Some(caps.clone());
12522                        });
12523
12524                        if let Some(local) = self.as_local() {
12525                            let mut buffers_with_language_server = Vec::new();
12526                            for handle in self.buffer_store.read(cx).buffers() {
12527                                let buffer_id = handle.read(cx).remote_id();
12528                                if local
12529                                    .buffers_opened_in_servers
12530                                    .get(&buffer_id)
12531                                    .filter(|s| s.contains(&server_id))
12532                                    .is_some()
12533                                {
12534                                    buffers_with_language_server.push(handle);
12535                                }
12536                            }
12537                            let triggers = caps
12538                                .trigger_characters
12539                                .unwrap_or_default()
12540                                .into_iter()
12541                                .collect::<BTreeSet<_>>();
12542                            for handle in buffers_with_language_server {
12543                                let triggers = triggers.clone();
12544                                let _ = handle.update(cx, move |buffer, cx| {
12545                                    buffer.set_completion_triggers(server_id, triggers, cx);
12546                                });
12547                            }
12548                        }
12549                        notify_server_capabilities_updated(&server, cx);
12550                    }
12551                }
12552                "textDocument/hover" => {
12553                    let options = parse_register_capabilities(reg)?;
12554                    let provider = match options {
12555                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12556                        OneOf::Right(caps) => caps,
12557                    };
12558                    server.update_capabilities(|capabilities| {
12559                        capabilities.hover_provider = Some(provider);
12560                    });
12561                    notify_server_capabilities_updated(&server, cx);
12562                }
12563                "textDocument/signatureHelp" => {
12564                    if let Some(caps) = reg
12565                        .register_options
12566                        .map(serde_json::from_value)
12567                        .transpose()?
12568                    {
12569                        server.update_capabilities(|capabilities| {
12570                            capabilities.signature_help_provider = Some(caps);
12571                        });
12572                        notify_server_capabilities_updated(&server, cx);
12573                    }
12574                }
12575                "textDocument/didChange" => {
12576                    if let Some(sync_kind) = reg
12577                        .register_options
12578                        .and_then(|opts| opts.get("syncKind").cloned())
12579                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12580                        .transpose()?
12581                    {
12582                        server.update_capabilities(|capabilities| {
12583                            let mut sync_options =
12584                                Self::take_text_document_sync_options(capabilities);
12585                            sync_options.change = Some(sync_kind);
12586                            capabilities.text_document_sync =
12587                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12588                        });
12589                        notify_server_capabilities_updated(&server, cx);
12590                    }
12591                }
12592                "textDocument/didSave" => {
12593                    if let Some(include_text) = reg
12594                        .register_options
12595                        .map(|opts| {
12596                            let transpose = opts
12597                                .get("includeText")
12598                                .cloned()
12599                                .map(serde_json::from_value::<Option<bool>>)
12600                                .transpose();
12601                            match transpose {
12602                                Ok(value) => Ok(value.flatten()),
12603                                Err(e) => Err(e),
12604                            }
12605                        })
12606                        .transpose()?
12607                    {
12608                        server.update_capabilities(|capabilities| {
12609                            let mut sync_options =
12610                                Self::take_text_document_sync_options(capabilities);
12611                            sync_options.save =
12612                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12613                                    include_text,
12614                                }));
12615                            capabilities.text_document_sync =
12616                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12617                        });
12618                        notify_server_capabilities_updated(&server, cx);
12619                    }
12620                }
12621                "textDocument/codeLens" => {
12622                    if let Some(caps) = reg
12623                        .register_options
12624                        .map(serde_json::from_value)
12625                        .transpose()?
12626                    {
12627                        server.update_capabilities(|capabilities| {
12628                            capabilities.code_lens_provider = Some(caps);
12629                        });
12630                        notify_server_capabilities_updated(&server, cx);
12631                    }
12632                }
12633                "textDocument/diagnostic" => {
12634                    if let Some(caps) = reg
12635                        .register_options
12636                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12637                        .transpose()?
12638                    {
12639                        let local = self
12640                            .as_local_mut()
12641                            .context("Expected LSP Store to be local")?;
12642                        let state = local
12643                            .language_servers
12644                            .get_mut(&server_id)
12645                            .context("Could not obtain Language Servers state")?;
12646                        local
12647                            .language_server_dynamic_registrations
12648                            .entry(server_id)
12649                            .or_default()
12650                            .diagnostics
12651                            .insert(Some(reg.id.clone()), caps.clone());
12652
12653                        let supports_workspace_diagnostics =
12654                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12655                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12656                                    diagnostic_options.workspace_diagnostics
12657                                }
12658                                DiagnosticServerCapabilities::RegistrationOptions(
12659                                    diagnostic_registration_options,
12660                                ) => {
12661                                    diagnostic_registration_options
12662                                        .diagnostic_options
12663                                        .workspace_diagnostics
12664                                }
12665                            };
12666
12667                        if supports_workspace_diagnostics(&caps) {
12668                            if let LanguageServerState::Running {
12669                                workspace_diagnostics_refresh_tasks,
12670                                ..
12671                            } = state
12672                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12673                                    Some(reg.id.clone()),
12674                                    caps.clone(),
12675                                    server.clone(),
12676                                    cx,
12677                                )
12678                            {
12679                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12680                            }
12681                        }
12682
12683                        server.update_capabilities(|capabilities| {
12684                            capabilities.diagnostic_provider = Some(caps);
12685                        });
12686
12687                        notify_server_capabilities_updated(&server, cx);
12688
12689                        self.pull_document_diagnostics_for_server(server_id, cx);
12690                    }
12691                }
12692                "textDocument/documentColor" => {
12693                    let options = parse_register_capabilities(reg)?;
12694                    let provider = match options {
12695                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12696                        OneOf::Right(caps) => caps,
12697                    };
12698                    server.update_capabilities(|capabilities| {
12699                        capabilities.color_provider = Some(provider);
12700                    });
12701                    notify_server_capabilities_updated(&server, cx);
12702                }
12703                _ => log::warn!("unhandled capability registration: {reg:?}"),
12704            }
12705        }
12706
12707        Ok(())
12708    }
12709
12710    fn unregister_server_capabilities(
12711        &mut self,
12712        server_id: LanguageServerId,
12713        params: lsp::UnregistrationParams,
12714        cx: &mut Context<Self>,
12715    ) -> anyhow::Result<()> {
12716        let server = self
12717            .language_server_for_id(server_id)
12718            .with_context(|| format!("no server {server_id} found"))?;
12719        for unreg in params.unregisterations.iter() {
12720            match unreg.method.as_str() {
12721                "workspace/didChangeWatchedFiles" => {
12722                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12723                        local_lsp_store
12724                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12725                        true
12726                    } else {
12727                        false
12728                    };
12729                    if notify {
12730                        notify_server_capabilities_updated(&server, cx);
12731                    }
12732                }
12733                "workspace/didChangeConfiguration" => {
12734                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12735                }
12736                "workspace/didChangeWorkspaceFolders" => {
12737                    server.update_capabilities(|capabilities| {
12738                        capabilities
12739                            .workspace
12740                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12741                                workspace_folders: None,
12742                                file_operations: None,
12743                            })
12744                            .workspace_folders = None;
12745                    });
12746                    notify_server_capabilities_updated(&server, cx);
12747                }
12748                "workspace/symbol" => {
12749                    server.update_capabilities(|capabilities| {
12750                        capabilities.workspace_symbol_provider = None
12751                    });
12752                    notify_server_capabilities_updated(&server, cx);
12753                }
12754                "workspace/fileOperations" => {
12755                    server.update_capabilities(|capabilities| {
12756                        capabilities
12757                            .workspace
12758                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12759                                workspace_folders: None,
12760                                file_operations: None,
12761                            })
12762                            .file_operations = None;
12763                    });
12764                    notify_server_capabilities_updated(&server, cx);
12765                }
12766                "workspace/executeCommand" => {
12767                    server.update_capabilities(|capabilities| {
12768                        capabilities.execute_command_provider = None;
12769                    });
12770                    notify_server_capabilities_updated(&server, cx);
12771                }
12772                "textDocument/rangeFormatting" => {
12773                    server.update_capabilities(|capabilities| {
12774                        capabilities.document_range_formatting_provider = None
12775                    });
12776                    notify_server_capabilities_updated(&server, cx);
12777                }
12778                "textDocument/onTypeFormatting" => {
12779                    server.update_capabilities(|capabilities| {
12780                        capabilities.document_on_type_formatting_provider = None;
12781                    });
12782                    notify_server_capabilities_updated(&server, cx);
12783                }
12784                "textDocument/formatting" => {
12785                    server.update_capabilities(|capabilities| {
12786                        capabilities.document_formatting_provider = None;
12787                    });
12788                    notify_server_capabilities_updated(&server, cx);
12789                }
12790                "textDocument/rename" => {
12791                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12792                    notify_server_capabilities_updated(&server, cx);
12793                }
12794                "textDocument/codeAction" => {
12795                    server.update_capabilities(|capabilities| {
12796                        capabilities.code_action_provider = None;
12797                    });
12798                    notify_server_capabilities_updated(&server, cx);
12799                }
12800                "textDocument/definition" => {
12801                    server.update_capabilities(|capabilities| {
12802                        capabilities.definition_provider = None;
12803                    });
12804                    notify_server_capabilities_updated(&server, cx);
12805                }
12806                "textDocument/completion" => {
12807                    server.update_capabilities(|capabilities| {
12808                        capabilities.completion_provider = None;
12809                    });
12810                    notify_server_capabilities_updated(&server, cx);
12811                }
12812                "textDocument/hover" => {
12813                    server.update_capabilities(|capabilities| {
12814                        capabilities.hover_provider = None;
12815                    });
12816                    notify_server_capabilities_updated(&server, cx);
12817                }
12818                "textDocument/signatureHelp" => {
12819                    server.update_capabilities(|capabilities| {
12820                        capabilities.signature_help_provider = None;
12821                    });
12822                    notify_server_capabilities_updated(&server, cx);
12823                }
12824                "textDocument/didChange" => {
12825                    server.update_capabilities(|capabilities| {
12826                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12827                        sync_options.change = None;
12828                        capabilities.text_document_sync =
12829                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12830                    });
12831                    notify_server_capabilities_updated(&server, cx);
12832                }
12833                "textDocument/didSave" => {
12834                    server.update_capabilities(|capabilities| {
12835                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12836                        sync_options.save = None;
12837                        capabilities.text_document_sync =
12838                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12839                    });
12840                    notify_server_capabilities_updated(&server, cx);
12841                }
12842                "textDocument/codeLens" => {
12843                    server.update_capabilities(|capabilities| {
12844                        capabilities.code_lens_provider = None;
12845                    });
12846                    notify_server_capabilities_updated(&server, cx);
12847                }
12848                "textDocument/diagnostic" => {
12849                    let local = self
12850                        .as_local_mut()
12851                        .context("Expected LSP Store to be local")?;
12852
12853                    let state = local
12854                        .language_servers
12855                        .get_mut(&server_id)
12856                        .context("Could not obtain Language Servers state")?;
12857                    let registrations = local
12858                        .language_server_dynamic_registrations
12859                        .get_mut(&server_id)
12860                        .with_context(|| {
12861                            format!("Expected dynamic registration to exist for server {server_id}")
12862                        })?;
12863                    registrations.diagnostics
12864                        .remove(&Some(unreg.id.clone()))
12865                        .with_context(|| format!(
12866                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12867                            unreg.id)
12868                        )?;
12869                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12870
12871                    if let LanguageServerState::Running {
12872                        workspace_diagnostics_refresh_tasks,
12873                        ..
12874                    } = state
12875                    {
12876                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12877                    }
12878
12879                    self.clear_unregistered_diagnostics(
12880                        server_id,
12881                        SharedString::from(unreg.id.clone()),
12882                        cx,
12883                    )?;
12884
12885                    if removed_last_diagnostic_provider {
12886                        server.update_capabilities(|capabilities| {
12887                            debug_assert!(capabilities.diagnostic_provider.is_some());
12888                            capabilities.diagnostic_provider = None;
12889                        });
12890                    }
12891
12892                    notify_server_capabilities_updated(&server, cx);
12893                }
12894                "textDocument/documentColor" => {
12895                    server.update_capabilities(|capabilities| {
12896                        capabilities.color_provider = None;
12897                    });
12898                    notify_server_capabilities_updated(&server, cx);
12899                }
12900                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12901            }
12902        }
12903
12904        Ok(())
12905    }
12906
12907    fn clear_unregistered_diagnostics(
12908        &mut self,
12909        server_id: LanguageServerId,
12910        cleared_registration_id: SharedString,
12911        cx: &mut Context<Self>,
12912    ) -> anyhow::Result<()> {
12913        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12914
12915        self.buffer_store.update(cx, |buffer_store, cx| {
12916            for buffer_handle in buffer_store.buffers() {
12917                let buffer = buffer_handle.read(cx);
12918                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12919                let Some(abs_path) = abs_path else {
12920                    continue;
12921                };
12922                affected_abs_paths.insert(abs_path);
12923            }
12924        });
12925
12926        let local = self.as_local().context("Expected LSP Store to be local")?;
12927        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12928            let Some(worktree) = self
12929                .worktree_store
12930                .read(cx)
12931                .worktree_for_id(*worktree_id, cx)
12932            else {
12933                continue;
12934            };
12935
12936            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
12937                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
12938                    let has_matching_registration =
12939                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
12940                            entry.diagnostic.registration_id.as_ref()
12941                                == Some(&cleared_registration_id)
12942                        });
12943                    if has_matching_registration {
12944                        let abs_path = worktree.read(cx).absolutize(rel_path);
12945                        affected_abs_paths.insert(abs_path);
12946                    }
12947                }
12948            }
12949        }
12950
12951        if affected_abs_paths.is_empty() {
12952            return Ok(());
12953        }
12954
12955        // Send a fake diagnostic update which clears the state for the registration ID
12956        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
12957            affected_abs_paths
12958                .into_iter()
12959                .map(|abs_path| DocumentDiagnosticsUpdate {
12960                    diagnostics: DocumentDiagnostics {
12961                        diagnostics: Vec::new(),
12962                        document_abs_path: abs_path,
12963                        version: None,
12964                    },
12965                    result_id: None,
12966                    registration_id: Some(cleared_registration_id.clone()),
12967                    server_id,
12968                    disk_based_sources: Cow::Borrowed(&[]),
12969                })
12970                .collect();
12971
12972        let merge_registration_id = cleared_registration_id.clone();
12973        self.merge_diagnostic_entries(
12974            clears,
12975            move |_, diagnostic, _| {
12976                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
12977                    diagnostic.registration_id != Some(merge_registration_id.clone())
12978                } else {
12979                    true
12980                }
12981            },
12982            cx,
12983        )?;
12984
12985        Ok(())
12986    }
12987
12988    async fn deduplicate_range_based_lsp_requests<T>(
12989        lsp_store: &Entity<Self>,
12990        server_id: Option<LanguageServerId>,
12991        lsp_request_id: LspRequestId,
12992        proto_request: &T::ProtoRequest,
12993        range: Range<Anchor>,
12994        cx: &mut AsyncApp,
12995    ) -> Result<()>
12996    where
12997        T: LspCommand,
12998        T::ProtoRequest: proto::LspRequestMessage,
12999    {
13000        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13001        let version = deserialize_version(proto_request.buffer_version());
13002        let buffer = lsp_store.update(cx, |this, cx| {
13003            this.buffer_store.read(cx).get_existing(buffer_id)
13004        })??;
13005        buffer
13006            .update(cx, |buffer, _| buffer.wait_for_version(version))?
13007            .await?;
13008        lsp_store.update(cx, |lsp_store, cx| {
13009            let buffer_snapshot = buffer.read(cx).snapshot();
13010            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13011            let chunks_queried_for = lsp_data
13012                .inlay_hints
13013                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
13014                .collect::<Vec<_>>();
13015            match chunks_queried_for.as_slice() {
13016                &[chunk] => {
13017                    let key = LspKey {
13018                        request_type: TypeId::of::<T>(),
13019                        server_queried: server_id,
13020                    };
13021                    let previous_request = lsp_data
13022                        .chunk_lsp_requests
13023                        .entry(key)
13024                        .or_default()
13025                        .insert(chunk, lsp_request_id);
13026                    if let Some((previous_request, running_requests)) =
13027                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13028                    {
13029                        running_requests.remove(&previous_request);
13030                    }
13031                }
13032                _ambiguous_chunks => {
13033                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13034                    // there, a buffer version-based check will be performed and outdated requests discarded.
13035                }
13036            }
13037            anyhow::Ok(())
13038        })??;
13039
13040        Ok(())
13041    }
13042
13043    async fn query_lsp_locally<T>(
13044        lsp_store: Entity<Self>,
13045        for_server_id: Option<LanguageServerId>,
13046        sender_id: proto::PeerId,
13047        lsp_request_id: LspRequestId,
13048        proto_request: T::ProtoRequest,
13049        position: Option<Anchor>,
13050        cx: &mut AsyncApp,
13051    ) -> Result<()>
13052    where
13053        T: LspCommand + Clone,
13054        T::ProtoRequest: proto::LspRequestMessage,
13055        <T::ProtoRequest as proto::RequestMessage>::Response:
13056            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13057    {
13058        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13059        let version = deserialize_version(proto_request.buffer_version());
13060        let buffer = lsp_store.update(cx, |this, cx| {
13061            this.buffer_store.read(cx).get_existing(buffer_id)
13062        })??;
13063        buffer
13064            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
13065            .await?;
13066        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
13067        let request =
13068            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13069        let key = LspKey {
13070            request_type: TypeId::of::<T>(),
13071            server_queried: for_server_id,
13072        };
13073        lsp_store.update(cx, |lsp_store, cx| {
13074            let request_task = match for_server_id {
13075                Some(server_id) => {
13076                    let server_task = lsp_store.request_lsp(
13077                        buffer.clone(),
13078                        LanguageServerToQuery::Other(server_id),
13079                        request.clone(),
13080                        cx,
13081                    );
13082                    cx.background_spawn(async move {
13083                        let mut responses = Vec::new();
13084                        match server_task.await {
13085                            Ok(response) => responses.push((server_id, response)),
13086                            // rust-analyzer likes to error with this when its still loading up
13087                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13088                            Err(e) => log::error!(
13089                                "Error handling response for request {request:?}: {e:#}"
13090                            ),
13091                        }
13092                        responses
13093                    })
13094                }
13095                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13096            };
13097            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13098            if T::ProtoRequest::stop_previous_requests() {
13099                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13100                    lsp_requests.clear();
13101                }
13102            }
13103            lsp_data.lsp_requests.entry(key).or_default().insert(
13104                lsp_request_id,
13105                cx.spawn(async move |lsp_store, cx| {
13106                    let response = request_task.await;
13107                    lsp_store
13108                        .update(cx, |lsp_store, cx| {
13109                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13110                            {
13111                                let response = response
13112                                    .into_iter()
13113                                    .map(|(server_id, response)| {
13114                                        (
13115                                            server_id.to_proto(),
13116                                            T::response_to_proto(
13117                                                response,
13118                                                lsp_store,
13119                                                sender_id,
13120                                                &buffer_version,
13121                                                cx,
13122                                            )
13123                                            .into(),
13124                                        )
13125                                    })
13126                                    .collect::<HashMap<_, _>>();
13127                                match client.send_lsp_response::<T::ProtoRequest>(
13128                                    project_id,
13129                                    lsp_request_id,
13130                                    response,
13131                                ) {
13132                                    Ok(()) => {}
13133                                    Err(e) => {
13134                                        log::error!("Failed to send LSP response: {e:#}",)
13135                                    }
13136                                }
13137                            }
13138                        })
13139                        .ok();
13140                }),
13141            );
13142        })?;
13143        Ok(())
13144    }
13145
13146    fn take_text_document_sync_options(
13147        capabilities: &mut lsp::ServerCapabilities,
13148    ) -> lsp::TextDocumentSyncOptions {
13149        match capabilities.text_document_sync.take() {
13150            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13151            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13152                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13153                sync_options.change = Some(sync_kind);
13154                sync_options
13155            }
13156            None => lsp::TextDocumentSyncOptions::default(),
13157        }
13158    }
13159
13160    #[cfg(any(test, feature = "test-support"))]
13161    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
13162        Some(
13163            self.lsp_data
13164                .get_mut(&buffer_id)?
13165                .code_lens
13166                .take()?
13167                .update
13168                .take()?
13169                .1,
13170        )
13171    }
13172
13173    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13174        self.downstream_client.clone()
13175    }
13176
13177    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13178        self.worktree_store.clone()
13179    }
13180
13181    /// Gets what's stored in the LSP data for the given buffer.
13182    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13183        self.lsp_data.get_mut(&buffer_id)
13184    }
13185
13186    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13187    /// new [`BufferLspData`] will be created to replace the previous state.
13188    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13189        let (buffer_id, buffer_version) =
13190            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13191        let lsp_data = self
13192            .lsp_data
13193            .entry(buffer_id)
13194            .or_insert_with(|| BufferLspData::new(buffer, cx));
13195        if buffer_version.changed_since(&lsp_data.buffer_version) {
13196            *lsp_data = BufferLspData::new(buffer, cx);
13197        }
13198        lsp_data
13199    }
13200}
13201
13202// Registration with registerOptions as null, should fallback to true.
13203// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13204fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13205    reg: lsp::Registration,
13206) -> Result<OneOf<bool, T>> {
13207    Ok(match reg.register_options {
13208        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13209        None => OneOf::Left(true),
13210    })
13211}
13212
13213fn subscribe_to_binary_statuses(
13214    languages: &Arc<LanguageRegistry>,
13215    cx: &mut Context<'_, LspStore>,
13216) -> Task<()> {
13217    let mut server_statuses = languages.language_server_binary_statuses();
13218    cx.spawn(async move |lsp_store, cx| {
13219        while let Some((server_name, binary_status)) = server_statuses.next().await {
13220            if lsp_store
13221                .update(cx, |_, cx| {
13222                    let mut message = None;
13223                    let binary_status = match binary_status {
13224                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13225                        BinaryStatus::CheckingForUpdate => {
13226                            proto::ServerBinaryStatus::CheckingForUpdate
13227                        }
13228                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13229                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13230                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13231                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13232                        BinaryStatus::Failed { error } => {
13233                            message = Some(error);
13234                            proto::ServerBinaryStatus::Failed
13235                        }
13236                    };
13237                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13238                        // Binary updates are about the binary that might not have any language server id at that point.
13239                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13240                        language_server_id: LanguageServerId(0),
13241                        name: Some(server_name),
13242                        message: proto::update_language_server::Variant::StatusUpdate(
13243                            proto::StatusUpdate {
13244                                message,
13245                                status: Some(proto::status_update::Status::Binary(
13246                                    binary_status as i32,
13247                                )),
13248                            },
13249                        ),
13250                    });
13251                })
13252                .is_err()
13253            {
13254                break;
13255            }
13256        }
13257    })
13258}
13259
13260fn lsp_workspace_diagnostics_refresh(
13261    registration_id: Option<String>,
13262    options: DiagnosticServerCapabilities,
13263    server: Arc<LanguageServer>,
13264    cx: &mut Context<'_, LspStore>,
13265) -> Option<WorkspaceRefreshTask> {
13266    let identifier = workspace_diagnostic_identifier(&options)?;
13267    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13268
13269    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13270    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13271    refresh_tx.try_send(()).ok();
13272
13273    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13274        let mut attempts = 0;
13275        let max_attempts = 50;
13276        let mut requests = 0;
13277
13278        loop {
13279            let Some(()) = refresh_rx.recv().await else {
13280                return;
13281            };
13282
13283            'request: loop {
13284                requests += 1;
13285                if attempts > max_attempts {
13286                    log::error!(
13287                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13288                    );
13289                    return;
13290                }
13291                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13292                cx.background_executor()
13293                    .timer(Duration::from_millis(backoff_millis))
13294                    .await;
13295                attempts += 1;
13296
13297                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13298                    lsp_store
13299                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13300                        .into_iter()
13301                        .filter_map(|(abs_path, result_id)| {
13302                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13303                            Some(lsp::PreviousResultId {
13304                                uri,
13305                                value: result_id.to_string(),
13306                            })
13307                        })
13308                        .collect()
13309                }) else {
13310                    return;
13311                };
13312
13313                let token = if let Some(registration_id) = &registration_id {
13314                    format!(
13315                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13316                        server.server_id(),
13317                    )
13318                } else {
13319                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13320                };
13321
13322                progress_rx.try_recv().ok();
13323                let timer =
13324                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13325                let progress = pin!(progress_rx.recv().fuse());
13326                let response_result = server
13327                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13328                        lsp::WorkspaceDiagnosticParams {
13329                            previous_result_ids,
13330                            identifier: identifier.clone(),
13331                            work_done_progress_params: Default::default(),
13332                            partial_result_params: lsp::PartialResultParams {
13333                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13334                            },
13335                        },
13336                        select(timer, progress).then(|either| match either {
13337                            Either::Left((message, ..)) => ready(message).left_future(),
13338                            Either::Right(..) => pending::<String>().right_future(),
13339                        }),
13340                    )
13341                    .await;
13342
13343                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13344                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13345                match response_result {
13346                    ConnectionResult::Timeout => {
13347                        log::error!("Timeout during workspace diagnostics pull");
13348                        continue 'request;
13349                    }
13350                    ConnectionResult::ConnectionReset => {
13351                        log::error!("Server closed a workspace diagnostics pull request");
13352                        continue 'request;
13353                    }
13354                    ConnectionResult::Result(Err(e)) => {
13355                        log::error!("Error during workspace diagnostics pull: {e:#}");
13356                        break 'request;
13357                    }
13358                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13359                        attempts = 0;
13360                        if lsp_store
13361                            .update(cx, |lsp_store, cx| {
13362                                lsp_store.apply_workspace_diagnostic_report(
13363                                    server.server_id(),
13364                                    pulled_diagnostics,
13365                                    registration_id_shared.clone(),
13366                                    cx,
13367                                )
13368                            })
13369                            .is_err()
13370                        {
13371                            return;
13372                        }
13373                        break 'request;
13374                    }
13375                }
13376            }
13377        }
13378    });
13379
13380    Some(WorkspaceRefreshTask {
13381        refresh_tx,
13382        progress_tx,
13383        task: workspace_query_language_server,
13384    })
13385}
13386
13387fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13388    match &options {
13389        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13390            diagnostic_options.identifier.clone()
13391        }
13392        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13393            let diagnostic_options = &registration_options.diagnostic_options;
13394            diagnostic_options.identifier.clone()
13395        }
13396    }
13397}
13398
13399fn workspace_diagnostic_identifier(
13400    options: &DiagnosticServerCapabilities,
13401) -> Option<Option<String>> {
13402    match &options {
13403        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13404            if !diagnostic_options.workspace_diagnostics {
13405                return None;
13406            }
13407            Some(diagnostic_options.identifier.clone())
13408        }
13409        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13410            let diagnostic_options = &registration_options.diagnostic_options;
13411            if !diagnostic_options.workspace_diagnostics {
13412                return None;
13413            }
13414            Some(diagnostic_options.identifier.clone())
13415        }
13416    }
13417}
13418
13419fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13420    let CompletionSource::BufferWord {
13421        word_range,
13422        resolved,
13423    } = &mut completion.source
13424    else {
13425        return;
13426    };
13427    if *resolved {
13428        return;
13429    }
13430
13431    if completion.new_text
13432        != snapshot
13433            .text_for_range(word_range.clone())
13434            .collect::<String>()
13435    {
13436        return;
13437    }
13438
13439    let mut offset = 0;
13440    for chunk in snapshot.chunks(word_range.clone(), true) {
13441        let end_offset = offset + chunk.text.len();
13442        if let Some(highlight_id) = chunk.syntax_highlight_id {
13443            completion
13444                .label
13445                .runs
13446                .push((offset..end_offset, highlight_id));
13447        }
13448        offset = end_offset;
13449    }
13450    *resolved = true;
13451}
13452
13453impl EventEmitter<LspStoreEvent> for LspStore {}
13454
13455fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13456    hover
13457        .contents
13458        .retain(|hover_block| !hover_block.text.trim().is_empty());
13459    if hover.contents.is_empty() {
13460        None
13461    } else {
13462        Some(hover)
13463    }
13464}
13465
13466async fn populate_labels_for_completions(
13467    new_completions: Vec<CoreCompletion>,
13468    language: Option<Arc<Language>>,
13469    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13470) -> Vec<Completion> {
13471    let lsp_completions = new_completions
13472        .iter()
13473        .filter_map(|new_completion| {
13474            new_completion
13475                .source
13476                .lsp_completion(true)
13477                .map(|lsp_completion| lsp_completion.into_owned())
13478        })
13479        .collect::<Vec<_>>();
13480
13481    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13482        lsp_adapter
13483            .labels_for_completions(&lsp_completions, language)
13484            .await
13485            .log_err()
13486            .unwrap_or_default()
13487    } else {
13488        Vec::new()
13489    }
13490    .into_iter()
13491    .fuse();
13492
13493    let mut completions = Vec::new();
13494    for completion in new_completions {
13495        match completion.source.lsp_completion(true) {
13496            Some(lsp_completion) => {
13497                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13498
13499                let mut label = labels.next().flatten().unwrap_or_else(|| {
13500                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13501                });
13502                ensure_uniform_list_compatible_label(&mut label);
13503                completions.push(Completion {
13504                    label,
13505                    documentation,
13506                    replace_range: completion.replace_range,
13507                    new_text: completion.new_text,
13508                    insert_text_mode: lsp_completion.insert_text_mode,
13509                    source: completion.source,
13510                    icon_path: None,
13511                    confirm: None,
13512                    match_start: None,
13513                    snippet_deduplication_key: None,
13514                });
13515            }
13516            None => {
13517                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13518                ensure_uniform_list_compatible_label(&mut label);
13519                completions.push(Completion {
13520                    label,
13521                    documentation: None,
13522                    replace_range: completion.replace_range,
13523                    new_text: completion.new_text,
13524                    source: completion.source,
13525                    insert_text_mode: None,
13526                    icon_path: None,
13527                    confirm: None,
13528                    match_start: None,
13529                    snippet_deduplication_key: None,
13530                });
13531            }
13532        }
13533    }
13534    completions
13535}
13536
13537#[derive(Debug)]
13538pub enum LanguageServerToQuery {
13539    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13540    FirstCapable,
13541    /// Query a specific language server.
13542    Other(LanguageServerId),
13543}
13544
13545#[derive(Default)]
13546struct RenamePathsWatchedForServer {
13547    did_rename: Vec<RenameActionPredicate>,
13548    will_rename: Vec<RenameActionPredicate>,
13549}
13550
13551impl RenamePathsWatchedForServer {
13552    fn with_did_rename_patterns(
13553        mut self,
13554        did_rename: Option<&FileOperationRegistrationOptions>,
13555    ) -> Self {
13556        if let Some(did_rename) = did_rename {
13557            self.did_rename = did_rename
13558                .filters
13559                .iter()
13560                .filter_map(|filter| filter.try_into().log_err())
13561                .collect();
13562        }
13563        self
13564    }
13565    fn with_will_rename_patterns(
13566        mut self,
13567        will_rename: Option<&FileOperationRegistrationOptions>,
13568    ) -> Self {
13569        if let Some(will_rename) = will_rename {
13570            self.will_rename = will_rename
13571                .filters
13572                .iter()
13573                .filter_map(|filter| filter.try_into().log_err())
13574                .collect();
13575        }
13576        self
13577    }
13578
13579    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13580        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13581    }
13582    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13583        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13584    }
13585}
13586
13587impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13588    type Error = globset::Error;
13589    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13590        Ok(Self {
13591            kind: ops.pattern.matches.clone(),
13592            glob: GlobBuilder::new(&ops.pattern.glob)
13593                .case_insensitive(
13594                    ops.pattern
13595                        .options
13596                        .as_ref()
13597                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13598                )
13599                .build()?
13600                .compile_matcher(),
13601        })
13602    }
13603}
13604struct RenameActionPredicate {
13605    glob: GlobMatcher,
13606    kind: Option<FileOperationPatternKind>,
13607}
13608
13609impl RenameActionPredicate {
13610    // Returns true if language server should be notified
13611    fn eval(&self, path: &str, is_dir: bool) -> bool {
13612        self.kind.as_ref().is_none_or(|kind| {
13613            let expected_kind = if is_dir {
13614                FileOperationPatternKind::Folder
13615            } else {
13616                FileOperationPatternKind::File
13617            };
13618            kind == &expected_kind
13619        }) && self.glob.is_match(path)
13620    }
13621}
13622
13623#[derive(Default)]
13624struct LanguageServerWatchedPaths {
13625    worktree_paths: HashMap<WorktreeId, GlobSet>,
13626    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13627}
13628
13629#[derive(Default)]
13630struct LanguageServerWatchedPathsBuilder {
13631    worktree_paths: HashMap<WorktreeId, GlobSet>,
13632    abs_paths: HashMap<Arc<Path>, GlobSet>,
13633}
13634
13635impl LanguageServerWatchedPathsBuilder {
13636    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13637        self.worktree_paths.insert(worktree_id, glob_set);
13638    }
13639    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13640        self.abs_paths.insert(path, glob_set);
13641    }
13642    fn build(
13643        self,
13644        fs: Arc<dyn Fs>,
13645        language_server_id: LanguageServerId,
13646        cx: &mut Context<LspStore>,
13647    ) -> LanguageServerWatchedPaths {
13648        let lsp_store = cx.weak_entity();
13649
13650        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13651        let abs_paths = self
13652            .abs_paths
13653            .into_iter()
13654            .map(|(abs_path, globset)| {
13655                let task = cx.spawn({
13656                    let abs_path = abs_path.clone();
13657                    let fs = fs.clone();
13658
13659                    let lsp_store = lsp_store.clone();
13660                    async move |_, cx| {
13661                        maybe!(async move {
13662                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13663                            while let Some(update) = push_updates.0.next().await {
13664                                let action = lsp_store
13665                                    .update(cx, |this, _| {
13666                                        let Some(local) = this.as_local() else {
13667                                            return ControlFlow::Break(());
13668                                        };
13669                                        let Some(watcher) = local
13670                                            .language_server_watched_paths
13671                                            .get(&language_server_id)
13672                                        else {
13673                                            return ControlFlow::Break(());
13674                                        };
13675                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13676                                            "Watched abs path is not registered with a watcher",
13677                                        );
13678                                        let matching_entries = update
13679                                            .into_iter()
13680                                            .filter(|event| globs.is_match(&event.path))
13681                                            .collect::<Vec<_>>();
13682                                        this.lsp_notify_abs_paths_changed(
13683                                            language_server_id,
13684                                            matching_entries,
13685                                        );
13686                                        ControlFlow::Continue(())
13687                                    })
13688                                    .ok()?;
13689
13690                                if action.is_break() {
13691                                    break;
13692                                }
13693                            }
13694                            Some(())
13695                        })
13696                        .await;
13697                    }
13698                });
13699                (abs_path, (globset, task))
13700            })
13701            .collect();
13702        LanguageServerWatchedPaths {
13703            worktree_paths: self.worktree_paths,
13704            abs_paths,
13705        }
13706    }
13707}
13708
13709struct LspBufferSnapshot {
13710    version: i32,
13711    snapshot: TextBufferSnapshot,
13712}
13713
13714/// A prompt requested by LSP server.
13715#[derive(Clone, Debug)]
13716pub struct LanguageServerPromptRequest {
13717    pub level: PromptLevel,
13718    pub message: String,
13719    pub actions: Vec<MessageActionItem>,
13720    pub lsp_name: String,
13721    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13722}
13723
13724impl LanguageServerPromptRequest {
13725    pub async fn respond(self, index: usize) -> Option<()> {
13726        if let Some(response) = self.actions.into_iter().nth(index) {
13727            self.response_channel.send(response).await.ok()
13728        } else {
13729            None
13730        }
13731    }
13732}
13733impl PartialEq for LanguageServerPromptRequest {
13734    fn eq(&self, other: &Self) -> bool {
13735        self.message == other.message && self.actions == other.actions
13736    }
13737}
13738
13739#[derive(Clone, Debug, PartialEq)]
13740pub enum LanguageServerLogType {
13741    Log(MessageType),
13742    Trace { verbose_info: Option<String> },
13743    Rpc { received: bool },
13744}
13745
13746impl LanguageServerLogType {
13747    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13748        match self {
13749            Self::Log(log_type) => {
13750                use proto::log_message::LogLevel;
13751                let level = match *log_type {
13752                    MessageType::ERROR => LogLevel::Error,
13753                    MessageType::WARNING => LogLevel::Warning,
13754                    MessageType::INFO => LogLevel::Info,
13755                    MessageType::LOG => LogLevel::Log,
13756                    other => {
13757                        log::warn!("Unknown lsp log message type: {other:?}");
13758                        LogLevel::Log
13759                    }
13760                };
13761                proto::language_server_log::LogType::Log(proto::LogMessage {
13762                    level: level as i32,
13763                })
13764            }
13765            Self::Trace { verbose_info } => {
13766                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13767                    verbose_info: verbose_info.to_owned(),
13768                })
13769            }
13770            Self::Rpc { received } => {
13771                let kind = if *received {
13772                    proto::rpc_message::Kind::Received
13773                } else {
13774                    proto::rpc_message::Kind::Sent
13775                };
13776                let kind = kind as i32;
13777                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13778            }
13779        }
13780    }
13781
13782    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13783        use proto::log_message::LogLevel;
13784        use proto::rpc_message;
13785        match log_type {
13786            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13787                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13788                    LogLevel::Error => MessageType::ERROR,
13789                    LogLevel::Warning => MessageType::WARNING,
13790                    LogLevel::Info => MessageType::INFO,
13791                    LogLevel::Log => MessageType::LOG,
13792                },
13793            ),
13794            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13795                verbose_info: trace_message.verbose_info,
13796            },
13797            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13798                received: match rpc_message::Kind::from_i32(message.kind)
13799                    .unwrap_or(rpc_message::Kind::Received)
13800                {
13801                    rpc_message::Kind::Received => true,
13802                    rpc_message::Kind::Sent => false,
13803                },
13804            },
13805        }
13806    }
13807}
13808
13809pub struct WorkspaceRefreshTask {
13810    refresh_tx: mpsc::Sender<()>,
13811    progress_tx: mpsc::Sender<()>,
13812    #[allow(dead_code)]
13813    task: Task<()>,
13814}
13815
13816pub enum LanguageServerState {
13817    Starting {
13818        startup: Task<Option<Arc<LanguageServer>>>,
13819        /// List of language servers that will be added to the workspace once it's initialization completes.
13820        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13821    },
13822
13823    Running {
13824        adapter: Arc<CachedLspAdapter>,
13825        server: Arc<LanguageServer>,
13826        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13827        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13828    },
13829}
13830
13831impl LanguageServerState {
13832    fn add_workspace_folder(&self, uri: Uri) {
13833        match self {
13834            LanguageServerState::Starting {
13835                pending_workspace_folders,
13836                ..
13837            } => {
13838                pending_workspace_folders.lock().insert(uri);
13839            }
13840            LanguageServerState::Running { server, .. } => {
13841                server.add_workspace_folder(uri);
13842            }
13843        }
13844    }
13845    fn _remove_workspace_folder(&self, uri: Uri) {
13846        match self {
13847            LanguageServerState::Starting {
13848                pending_workspace_folders,
13849                ..
13850            } => {
13851                pending_workspace_folders.lock().remove(&uri);
13852            }
13853            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13854        }
13855    }
13856}
13857
13858impl std::fmt::Debug for LanguageServerState {
13859    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13860        match self {
13861            LanguageServerState::Starting { .. } => {
13862                f.debug_struct("LanguageServerState::Starting").finish()
13863            }
13864            LanguageServerState::Running { .. } => {
13865                f.debug_struct("LanguageServerState::Running").finish()
13866            }
13867        }
13868    }
13869}
13870
13871#[derive(Clone, Debug, Serialize)]
13872pub struct LanguageServerProgress {
13873    pub is_disk_based_diagnostics_progress: bool,
13874    pub is_cancellable: bool,
13875    pub title: Option<String>,
13876    pub message: Option<String>,
13877    pub percentage: Option<usize>,
13878    #[serde(skip_serializing)]
13879    pub last_update_at: Instant,
13880}
13881
13882#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13883pub struct DiagnosticSummary {
13884    pub error_count: usize,
13885    pub warning_count: usize,
13886}
13887
13888impl DiagnosticSummary {
13889    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13890        let mut this = Self {
13891            error_count: 0,
13892            warning_count: 0,
13893        };
13894
13895        for entry in diagnostics {
13896            if entry.diagnostic.is_primary {
13897                match entry.diagnostic.severity {
13898                    DiagnosticSeverity::ERROR => this.error_count += 1,
13899                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13900                    _ => {}
13901                }
13902            }
13903        }
13904
13905        this
13906    }
13907
13908    pub fn is_empty(&self) -> bool {
13909        self.error_count == 0 && self.warning_count == 0
13910    }
13911
13912    pub fn to_proto(
13913        self,
13914        language_server_id: LanguageServerId,
13915        path: &RelPath,
13916    ) -> proto::DiagnosticSummary {
13917        proto::DiagnosticSummary {
13918            path: path.to_proto(),
13919            language_server_id: language_server_id.0 as u64,
13920            error_count: self.error_count as u32,
13921            warning_count: self.warning_count as u32,
13922        }
13923    }
13924}
13925
13926#[derive(Clone, Debug)]
13927pub enum CompletionDocumentation {
13928    /// There is no documentation for this completion.
13929    Undocumented,
13930    /// A single line of documentation.
13931    SingleLine(SharedString),
13932    /// Multiple lines of plain text documentation.
13933    MultiLinePlainText(SharedString),
13934    /// Markdown documentation.
13935    MultiLineMarkdown(SharedString),
13936    /// Both single line and multiple lines of plain text documentation.
13937    SingleLineAndMultiLinePlainText {
13938        single_line: SharedString,
13939        plain_text: Option<SharedString>,
13940    },
13941}
13942
13943impl CompletionDocumentation {
13944    #[cfg(any(test, feature = "test-support"))]
13945    pub fn text(&self) -> SharedString {
13946        match self {
13947            CompletionDocumentation::Undocumented => "".into(),
13948            CompletionDocumentation::SingleLine(s) => s.clone(),
13949            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13950            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13951            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13952                single_line.clone()
13953            }
13954        }
13955    }
13956}
13957
13958impl From<lsp::Documentation> for CompletionDocumentation {
13959    fn from(docs: lsp::Documentation) -> Self {
13960        match docs {
13961            lsp::Documentation::String(text) => {
13962                if text.lines().count() <= 1 {
13963                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
13964                } else {
13965                    CompletionDocumentation::MultiLinePlainText(text.into())
13966                }
13967            }
13968
13969            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13970                lsp::MarkupKind::PlainText => {
13971                    if value.lines().count() <= 1 {
13972                        CompletionDocumentation::SingleLine(value.into())
13973                    } else {
13974                        CompletionDocumentation::MultiLinePlainText(value.into())
13975                    }
13976                }
13977
13978                lsp::MarkupKind::Markdown => {
13979                    CompletionDocumentation::MultiLineMarkdown(value.into())
13980                }
13981            },
13982        }
13983    }
13984}
13985
13986pub enum ResolvedHint {
13987    Resolved(InlayHint),
13988    Resolving(Shared<Task<()>>),
13989}
13990
13991fn glob_literal_prefix(glob: &Path) -> PathBuf {
13992    glob.components()
13993        .take_while(|component| match component {
13994            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13995            _ => true,
13996        })
13997        .collect()
13998}
13999
14000pub struct SshLspAdapter {
14001    name: LanguageServerName,
14002    binary: LanguageServerBinary,
14003    initialization_options: Option<String>,
14004    code_action_kinds: Option<Vec<CodeActionKind>>,
14005}
14006
14007impl SshLspAdapter {
14008    pub fn new(
14009        name: LanguageServerName,
14010        binary: LanguageServerBinary,
14011        initialization_options: Option<String>,
14012        code_action_kinds: Option<String>,
14013    ) -> Self {
14014        Self {
14015            name,
14016            binary,
14017            initialization_options,
14018            code_action_kinds: code_action_kinds
14019                .as_ref()
14020                .and_then(|c| serde_json::from_str(c).ok()),
14021        }
14022    }
14023}
14024
14025impl LspInstaller for SshLspAdapter {
14026    type BinaryVersion = ();
14027    async fn check_if_user_installed(
14028        &self,
14029        _: &dyn LspAdapterDelegate,
14030        _: Option<Toolchain>,
14031        _: &AsyncApp,
14032    ) -> Option<LanguageServerBinary> {
14033        Some(self.binary.clone())
14034    }
14035
14036    async fn cached_server_binary(
14037        &self,
14038        _: PathBuf,
14039        _: &dyn LspAdapterDelegate,
14040    ) -> Option<LanguageServerBinary> {
14041        None
14042    }
14043
14044    async fn fetch_latest_server_version(
14045        &self,
14046        _: &dyn LspAdapterDelegate,
14047        _: bool,
14048        _: &mut AsyncApp,
14049    ) -> Result<()> {
14050        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14051    }
14052
14053    async fn fetch_server_binary(
14054        &self,
14055        _: (),
14056        _: PathBuf,
14057        _: &dyn LspAdapterDelegate,
14058    ) -> Result<LanguageServerBinary> {
14059        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14060    }
14061}
14062
14063#[async_trait(?Send)]
14064impl LspAdapter for SshLspAdapter {
14065    fn name(&self) -> LanguageServerName {
14066        self.name.clone()
14067    }
14068
14069    async fn initialization_options(
14070        self: Arc<Self>,
14071        _: &Arc<dyn LspAdapterDelegate>,
14072    ) -> Result<Option<serde_json::Value>> {
14073        let Some(options) = &self.initialization_options else {
14074            return Ok(None);
14075        };
14076        let result = serde_json::from_str(options)?;
14077        Ok(result)
14078    }
14079
14080    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14081        self.code_action_kinds.clone()
14082    }
14083}
14084
14085pub fn language_server_settings<'a>(
14086    delegate: &'a dyn LspAdapterDelegate,
14087    language: &LanguageServerName,
14088    cx: &'a App,
14089) -> Option<&'a LspSettings> {
14090    language_server_settings_for(
14091        SettingsLocation {
14092            worktree_id: delegate.worktree_id(),
14093            path: RelPath::empty(),
14094        },
14095        language,
14096        cx,
14097    )
14098}
14099
14100pub fn language_server_settings_for<'a>(
14101    location: SettingsLocation<'a>,
14102    language: &LanguageServerName,
14103    cx: &'a App,
14104) -> Option<&'a LspSettings> {
14105    ProjectSettings::get(Some(location), cx).lsp.get(language)
14106}
14107
14108pub struct LocalLspAdapterDelegate {
14109    lsp_store: WeakEntity<LspStore>,
14110    worktree: worktree::Snapshot,
14111    fs: Arc<dyn Fs>,
14112    http_client: Arc<dyn HttpClient>,
14113    language_registry: Arc<LanguageRegistry>,
14114    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14115}
14116
14117impl LocalLspAdapterDelegate {
14118    pub fn new(
14119        language_registry: Arc<LanguageRegistry>,
14120        environment: &Entity<ProjectEnvironment>,
14121        lsp_store: WeakEntity<LspStore>,
14122        worktree: &Entity<Worktree>,
14123        http_client: Arc<dyn HttpClient>,
14124        fs: Arc<dyn Fs>,
14125        cx: &mut App,
14126    ) -> Arc<Self> {
14127        let load_shell_env_task =
14128            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14129
14130        Arc::new(Self {
14131            lsp_store,
14132            worktree: worktree.read(cx).snapshot(),
14133            fs,
14134            http_client,
14135            language_registry,
14136            load_shell_env_task,
14137        })
14138    }
14139
14140    pub fn from_local_lsp(
14141        local: &LocalLspStore,
14142        worktree: &Entity<Worktree>,
14143        cx: &mut App,
14144    ) -> Arc<Self> {
14145        Self::new(
14146            local.languages.clone(),
14147            &local.environment,
14148            local.weak.clone(),
14149            worktree,
14150            local.http_client.clone(),
14151            local.fs.clone(),
14152            cx,
14153        )
14154    }
14155}
14156
14157#[async_trait]
14158impl LspAdapterDelegate for LocalLspAdapterDelegate {
14159    fn show_notification(&self, message: &str, cx: &mut App) {
14160        self.lsp_store
14161            .update(cx, |_, cx| {
14162                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14163            })
14164            .ok();
14165    }
14166
14167    fn http_client(&self) -> Arc<dyn HttpClient> {
14168        self.http_client.clone()
14169    }
14170
14171    fn worktree_id(&self) -> WorktreeId {
14172        self.worktree.id()
14173    }
14174
14175    fn worktree_root_path(&self) -> &Path {
14176        self.worktree.abs_path().as_ref()
14177    }
14178
14179    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
14180        self.worktree.resolve_executable_path(path)
14181    }
14182
14183    async fn shell_env(&self) -> HashMap<String, String> {
14184        let task = self.load_shell_env_task.clone();
14185        task.await.unwrap_or_default()
14186    }
14187
14188    async fn npm_package_installed_version(
14189        &self,
14190        package_name: &str,
14191    ) -> Result<Option<(PathBuf, Version)>> {
14192        let local_package_directory = self.worktree_root_path();
14193        let node_modules_directory = local_package_directory.join("node_modules");
14194
14195        if let Some(version) =
14196            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14197        {
14198            return Ok(Some((node_modules_directory, version)));
14199        }
14200        let Some(npm) = self.which("npm".as_ref()).await else {
14201            log::warn!(
14202                "Failed to find npm executable for {:?}",
14203                local_package_directory
14204            );
14205            return Ok(None);
14206        };
14207
14208        let env = self.shell_env().await;
14209        let output = util::command::new_smol_command(&npm)
14210            .args(["root", "-g"])
14211            .envs(env)
14212            .current_dir(local_package_directory)
14213            .output()
14214            .await?;
14215        let global_node_modules =
14216            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14217
14218        if let Some(version) =
14219            read_package_installed_version(global_node_modules.clone(), package_name).await?
14220        {
14221            return Ok(Some((global_node_modules, version)));
14222        }
14223        return Ok(None);
14224    }
14225
14226    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14227        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14228        if self.fs.is_file(&worktree_abs_path).await {
14229            worktree_abs_path.pop();
14230        }
14231
14232        let env = self.shell_env().await;
14233
14234        let shell_path = env.get("PATH").cloned();
14235
14236        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14237    }
14238
14239    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14240        let mut working_dir = self.worktree_root_path().to_path_buf();
14241        if self.fs.is_file(&working_dir).await {
14242            working_dir.pop();
14243        }
14244        let output = util::command::new_smol_command(&command.path)
14245            .args(command.arguments)
14246            .envs(command.env.clone().unwrap_or_default())
14247            .current_dir(working_dir)
14248            .output()
14249            .await?;
14250
14251        anyhow::ensure!(
14252            output.status.success(),
14253            "{}, stdout: {:?}, stderr: {:?}",
14254            output.status,
14255            String::from_utf8_lossy(&output.stdout),
14256            String::from_utf8_lossy(&output.stderr)
14257        );
14258        Ok(())
14259    }
14260
14261    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14262        self.language_registry
14263            .update_lsp_binary_status(server_name, status);
14264    }
14265
14266    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14267        self.language_registry
14268            .all_lsp_adapters()
14269            .into_iter()
14270            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14271            .collect()
14272    }
14273
14274    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14275        let dir = self.language_registry.language_server_download_dir(name)?;
14276
14277        if !dir.exists() {
14278            smol::fs::create_dir_all(&dir)
14279                .await
14280                .context("failed to create container directory")
14281                .log_err()?;
14282        }
14283
14284        Some(dir)
14285    }
14286
14287    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14288        let entry = self
14289            .worktree
14290            .entry_for_path(path)
14291            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14292        let abs_path = self.worktree.absolutize(&entry.path);
14293        self.fs.load(&abs_path).await
14294    }
14295}
14296
14297async fn populate_labels_for_symbols(
14298    symbols: Vec<CoreSymbol>,
14299    language_registry: &Arc<LanguageRegistry>,
14300    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14301    output: &mut Vec<Symbol>,
14302) {
14303    #[allow(clippy::mutable_key_type)]
14304    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14305
14306    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14307    for symbol in symbols {
14308        let Some(file_name) = symbol.path.file_name() else {
14309            continue;
14310        };
14311        let language = language_registry
14312            .load_language_for_file_path(Path::new(file_name))
14313            .await
14314            .ok()
14315            .or_else(|| {
14316                unknown_paths.insert(file_name.into());
14317                None
14318            });
14319        symbols_by_language
14320            .entry(language)
14321            .or_default()
14322            .push(symbol);
14323    }
14324
14325    for unknown_path in unknown_paths {
14326        log::info!("no language found for symbol in file {unknown_path:?}");
14327    }
14328
14329    let mut label_params = Vec::new();
14330    for (language, mut symbols) in symbols_by_language {
14331        label_params.clear();
14332        label_params.extend(
14333            symbols
14334                .iter_mut()
14335                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14336        );
14337
14338        let mut labels = Vec::new();
14339        if let Some(language) = language {
14340            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14341                language_registry
14342                    .lsp_adapters(&language.name())
14343                    .first()
14344                    .cloned()
14345            });
14346            if let Some(lsp_adapter) = lsp_adapter {
14347                labels = lsp_adapter
14348                    .labels_for_symbols(&label_params, &language)
14349                    .await
14350                    .log_err()
14351                    .unwrap_or_default();
14352            }
14353        }
14354
14355        for ((symbol, (name, _)), label) in symbols
14356            .into_iter()
14357            .zip(label_params.drain(..))
14358            .zip(labels.into_iter().chain(iter::repeat(None)))
14359        {
14360            output.push(Symbol {
14361                language_server_name: symbol.language_server_name,
14362                source_worktree_id: symbol.source_worktree_id,
14363                source_language_server_id: symbol.source_language_server_id,
14364                path: symbol.path,
14365                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14366                name,
14367                kind: symbol.kind,
14368                range: symbol.range,
14369            });
14370        }
14371    }
14372}
14373
14374fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14375    match server.capabilities().text_document_sync.as_ref()? {
14376        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14377            // Server wants didSave but didn't specify includeText.
14378            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14379            // Server doesn't want didSave at all.
14380            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14381            // Server provided SaveOptions.
14382            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14383                Some(save_options.include_text.unwrap_or(false))
14384            }
14385        },
14386        // We do not have any save info. Kind affects didChange only.
14387        lsp::TextDocumentSyncCapability::Kind(_) => None,
14388    }
14389}
14390
14391/// Completion items are displayed in a `UniformList`.
14392/// Usually, those items are single-line strings, but in LSP responses,
14393/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14394/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14395/// 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,
14396/// breaking the completions menu presentation.
14397///
14398/// 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.
14399fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14400    let mut new_text = String::with_capacity(label.text.len());
14401    let mut offset_map = vec![0; label.text.len() + 1];
14402    let mut last_char_was_space = false;
14403    let mut new_idx = 0;
14404    let chars = label.text.char_indices().fuse();
14405    let mut newlines_removed = false;
14406
14407    for (idx, c) in chars {
14408        offset_map[idx] = new_idx;
14409
14410        match c {
14411            '\n' if last_char_was_space => {
14412                newlines_removed = true;
14413            }
14414            '\t' | ' ' if last_char_was_space => {}
14415            '\n' if !last_char_was_space => {
14416                new_text.push(' ');
14417                new_idx += 1;
14418                last_char_was_space = true;
14419                newlines_removed = true;
14420            }
14421            ' ' | '\t' => {
14422                new_text.push(' ');
14423                new_idx += 1;
14424                last_char_was_space = true;
14425            }
14426            _ => {
14427                new_text.push(c);
14428                new_idx += c.len_utf8();
14429                last_char_was_space = false;
14430            }
14431        }
14432    }
14433    offset_map[label.text.len()] = new_idx;
14434
14435    // Only modify the label if newlines were removed.
14436    if !newlines_removed {
14437        return;
14438    }
14439
14440    let last_index = new_idx;
14441    let mut run_ranges_errors = Vec::new();
14442    label.runs.retain_mut(|(range, _)| {
14443        match offset_map.get(range.start) {
14444            Some(&start) => range.start = start,
14445            None => {
14446                run_ranges_errors.push(range.clone());
14447                return false;
14448            }
14449        }
14450
14451        match offset_map.get(range.end) {
14452            Some(&end) => range.end = end,
14453            None => {
14454                run_ranges_errors.push(range.clone());
14455                range.end = last_index;
14456            }
14457        }
14458        true
14459    });
14460    if !run_ranges_errors.is_empty() {
14461        log::error!(
14462            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14463            label.text
14464        );
14465    }
14466
14467    let mut wrong_filter_range = None;
14468    if label.filter_range == (0..label.text.len()) {
14469        label.filter_range = 0..new_text.len();
14470    } else {
14471        let mut original_filter_range = Some(label.filter_range.clone());
14472        match offset_map.get(label.filter_range.start) {
14473            Some(&start) => label.filter_range.start = start,
14474            None => {
14475                wrong_filter_range = original_filter_range.take();
14476                label.filter_range.start = last_index;
14477            }
14478        }
14479
14480        match offset_map.get(label.filter_range.end) {
14481            Some(&end) => label.filter_range.end = end,
14482            None => {
14483                wrong_filter_range = original_filter_range.take();
14484                label.filter_range.end = last_index;
14485            }
14486        }
14487    }
14488    if let Some(wrong_filter_range) = wrong_filter_range {
14489        log::error!(
14490            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14491            label.text
14492        );
14493    }
14494
14495    label.text = new_text;
14496}
14497
14498#[cfg(test)]
14499mod tests {
14500    use language::HighlightId;
14501
14502    use super::*;
14503
14504    #[test]
14505    fn test_glob_literal_prefix() {
14506        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14507        assert_eq!(
14508            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14509            Path::new("node_modules")
14510        );
14511        assert_eq!(
14512            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14513            Path::new("foo")
14514        );
14515        assert_eq!(
14516            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14517            Path::new("foo/bar/baz.js")
14518        );
14519
14520        #[cfg(target_os = "windows")]
14521        {
14522            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14523            assert_eq!(
14524                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14525                Path::new("node_modules")
14526            );
14527            assert_eq!(
14528                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14529                Path::new("foo")
14530            );
14531            assert_eq!(
14532                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14533                Path::new("foo/bar/baz.js")
14534            );
14535        }
14536    }
14537
14538    #[test]
14539    fn test_multi_len_chars_normalization() {
14540        let mut label = CodeLabel::new(
14541            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14542            0..6,
14543            vec![(0..6, HighlightId(1))],
14544        );
14545        ensure_uniform_list_compatible_label(&mut label);
14546        assert_eq!(
14547            label,
14548            CodeLabel::new(
14549                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14550                0..6,
14551                vec![(0..6, HighlightId(1))],
14552            )
14553        );
14554    }
14555
14556    #[test]
14557    fn test_trailing_newline_in_completion_documentation() {
14558        let doc = lsp::Documentation::String(
14559            "Inappropriate argument value (of correct type).\n".to_string(),
14560        );
14561        let completion_doc: CompletionDocumentation = doc.into();
14562        assert!(
14563            matches!(completion_doc, CompletionDocumentation::SingleLine(s) if s == "Inappropriate argument value (of correct type).")
14564        );
14565
14566        let doc = lsp::Documentation::String("  some value  \n".to_string());
14567        let completion_doc: CompletionDocumentation = doc.into();
14568        assert!(matches!(
14569            completion_doc,
14570            CompletionDocumentation::SingleLine(s) if s == "some value"
14571        ));
14572    }
14573}