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;
   13mod code_lens;
   14mod document_colors;
   15mod document_symbols;
   16mod folding_ranges;
   17mod inlay_hints;
   18pub mod json_language_server_ext;
   19pub mod log_store;
   20pub mod lsp_ext_command;
   21pub mod rust_analyzer_ext;
   22mod semantic_tokens;
   23pub mod vue_language_server_ext;
   24
   25use self::code_lens::CodeLensData;
   26use self::document_colors::DocumentColorData;
   27use self::document_symbols::DocumentSymbolsData;
   28use self::inlay_hints::BufferInlayHints;
   29use crate::{
   30    CodeAction, Completion, CompletionDisplayOptions, CompletionResponse, CompletionSource,
   31    CoreCompletion, Hover, InlayHint, InlayId, LocationLink, LspAction, LspPullDiagnostics,
   32    ManifestProvidersStore, Project, ProjectItem, ProjectPath, ProjectTransaction,
   33    PulledDiagnostics, ResolveState, Symbol,
   34    buffer_store::{BufferStore, BufferStoreEvent},
   35    environment::ProjectEnvironment,
   36    lsp_command::{self, *},
   37    lsp_store::{
   38        self,
   39        folding_ranges::FoldingRangeData,
   40        log_store::{GlobalLogStore, LanguageServerKind},
   41        semantic_tokens::{SemanticTokenConfig, SemanticTokensData},
   42    },
   43    manifest_tree::{
   44        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   45        ManifestTree,
   46    },
   47    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   48    project_settings::{BinarySettings, LspSettings, ProjectSettings},
   49    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   50    trusted_worktrees::{PathTrust, TrustedWorktrees, TrustedWorktreesEvent},
   51    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   52    yarn::YarnPathStore,
   53};
   54use anyhow::{Context as _, Result, anyhow};
   55use async_trait::async_trait;
   56use client::{TypedEnvelope, proto};
   57use clock::Global;
   58use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   59use futures::{
   60    AsyncWriteExt, Future, FutureExt, StreamExt,
   61    future::{Either, Shared, join_all, pending, select},
   62    select, select_biased,
   63    stream::FuturesUnordered,
   64};
   65use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   66use gpui::{
   67    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString,
   68    Subscription, Task, WeakEntity,
   69};
   70use http_client::HttpClient;
   71use itertools::Itertools as _;
   72use language::{
   73    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, Capability, CodeLabel,
   74    CodeLabelExt, Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff,
   75    File as _, Language, LanguageAwareStyling, LanguageName, LanguageRegistry, LocalFile,
   76    LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate, ManifestName, ModelineSettings,
   77    OffsetUtf16, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToOffsetUtf16, ToPointUtf16,
   78    Toolchain, Transaction, Unclipped,
   79    language_settings::{
   80        AllLanguageSettings, FormatOnSave, Formatter, LanguageSettings, all_language_settings,
   81    },
   82    modeline, point_to_lsp,
   83    proto::{
   84        deserialize_anchor, deserialize_anchor_range, deserialize_version, serialize_anchor,
   85        serialize_anchor_range, serialize_version,
   86    },
   87    range_from_lsp, range_to_lsp,
   88    row_chunk::RowChunk,
   89};
   90use lsp::{
   91    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   92    DEFAULT_LSP_REQUEST_TIMEOUT, DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   93    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   94    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LanguageServer,
   95    LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId, LanguageServerName,
   96    LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType, OneOf,
   97    RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles,
   98    WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   99};
  100use node_runtime::read_package_installed_version;
  101use parking_lot::Mutex;
  102use postage::{mpsc, sink::Sink, stream::Stream, watch};
  103use rand::prelude::*;
  104use rpc::{
  105    AnyProtoClient, ErrorCode, ErrorExt as _,
  106    proto::{LspRequestId, LspRequestMessage as _},
  107};
  108use semver::Version;
  109use serde::Serialize;
  110use serde_json::Value;
  111use settings::{Settings, SettingsLocation, SettingsStore};
  112use sha2::{Digest, Sha256};
  113use snippet::Snippet;
  114use std::{
  115    any::TypeId,
  116    borrow::Cow,
  117    cell::RefCell,
  118    cmp::{Ordering, Reverse},
  119    collections::{VecDeque, hash_map},
  120    convert::TryInto,
  121    ffi::OsStr,
  122    future::ready,
  123    iter, mem,
  124    ops::{ControlFlow, Range},
  125    path::{self, Path, PathBuf},
  126    pin::pin,
  127    rc::Rc,
  128    sync::{
  129        Arc,
  130        atomic::{self, AtomicUsize},
  131    },
  132    time::{Duration, Instant},
  133    vec,
  134};
  135use sum_tree::Dimensions;
  136use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  137
  138use util::{
  139    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  140    paths::{PathStyle, SanitizedPath, UrlExt},
  141    post_inc,
  142    redact::redact_command,
  143    rel_path::RelPath,
  144};
  145
  146pub use document_colors::DocumentColors;
  147pub use folding_ranges::LspFoldingRange;
  148pub use fs::*;
  149pub use language::Location;
  150pub use lsp_store::inlay_hints::{CacheInlayHints, InvalidationStrategy};
  151#[cfg(any(test, feature = "test-support"))]
  152pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  153#[cfg(any(test, feature = "test-support"))]
  154pub use prettier::RANGE_FORMAT_SUFFIX as TEST_PRETTIER_RANGE_FORMAT_SUFFIX;
  155pub use semantic_tokens::{
  156    BufferSemanticToken, BufferSemanticTokens, RefreshForServer, SemanticTokenStylizer, TokenType,
  157};
  158
  159pub use worktree::{
  160    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  161    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  162};
  163
  164const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  165pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  166const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  167const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  168static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  169
  170#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  171pub enum ProgressToken {
  172    Number(i32),
  173    String(SharedString),
  174}
  175
  176impl std::fmt::Display for ProgressToken {
  177    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  178        match self {
  179            Self::Number(number) => write!(f, "{number}"),
  180            Self::String(string) => write!(f, "{string}"),
  181        }
  182    }
  183}
  184
  185impl ProgressToken {
  186    fn from_lsp(value: lsp::NumberOrString) -> Self {
  187        match value {
  188            lsp::NumberOrString::Number(number) => Self::Number(number),
  189            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  190        }
  191    }
  192
  193    fn to_lsp(&self) -> lsp::NumberOrString {
  194        match self {
  195            Self::Number(number) => lsp::NumberOrString::Number(*number),
  196            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  197        }
  198    }
  199
  200    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  201        Some(match value.value? {
  202            proto::progress_token::Value::Number(number) => Self::Number(number),
  203            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  204        })
  205    }
  206
  207    fn to_proto(&self) -> proto::ProgressToken {
  208        proto::ProgressToken {
  209            value: Some(match self {
  210                Self::Number(number) => proto::progress_token::Value::Number(*number),
  211                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  212            }),
  213        }
  214    }
  215}
  216
  217#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  218pub enum FormatTrigger {
  219    Save,
  220    Manual,
  221}
  222
  223pub enum LspFormatTarget {
  224    Buffers,
  225    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  226}
  227
  228#[derive(Debug, Clone, PartialEq, Eq, Hash)]
  229pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  230
  231struct OpenLspBuffer(Entity<Buffer>);
  232
  233impl FormatTrigger {
  234    fn from_proto(value: i32) -> FormatTrigger {
  235        match value {
  236            0 => FormatTrigger::Save,
  237            1 => FormatTrigger::Manual,
  238            _ => FormatTrigger::Save,
  239        }
  240    }
  241}
  242
  243#[derive(Clone)]
  244struct UnifiedLanguageServer {
  245    id: LanguageServerId,
  246    project_roots: HashSet<Arc<RelPath>>,
  247}
  248
  249/// Settings that affect language server identity.
  250///
  251/// Dynamic settings (`LspSettings::settings`) are excluded because they can be
  252/// updated via `workspace/didChangeConfiguration` without restarting the server.
  253#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  254struct LanguageServerSeedSettings {
  255    binary: Option<BinarySettings>,
  256    initialization_options: Option<serde_json::Value>,
  257}
  258
  259#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  260struct LanguageServerSeed {
  261    worktree_id: WorktreeId,
  262    name: LanguageServerName,
  263    toolchain: Option<Toolchain>,
  264    settings: LanguageServerSeedSettings,
  265}
  266
  267#[derive(Debug)]
  268pub struct DocumentDiagnosticsUpdate<'a, D> {
  269    pub diagnostics: D,
  270    pub result_id: Option<SharedString>,
  271    pub registration_id: Option<SharedString>,
  272    pub server_id: LanguageServerId,
  273    pub disk_based_sources: Cow<'a, [String]>,
  274}
  275
  276pub struct DocumentDiagnostics {
  277    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  278    document_abs_path: PathBuf,
  279    version: Option<i32>,
  280}
  281
  282#[derive(Default, Debug)]
  283struct DynamicRegistrations {
  284    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  285    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  286}
  287
  288pub struct LocalLspStore {
  289    weak: WeakEntity<LspStore>,
  290    pub worktree_store: Entity<WorktreeStore>,
  291    toolchain_store: Entity<LocalToolchainStore>,
  292    http_client: Arc<dyn HttpClient>,
  293    environment: Entity<ProjectEnvironment>,
  294    fs: Arc<dyn Fs>,
  295    languages: Arc<LanguageRegistry>,
  296    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  297    yarn: Entity<YarnPathStore>,
  298    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  299    buffers_being_formatted: HashSet<BufferId>,
  300    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  301    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  302    watched_manifest_filenames: HashSet<ManifestName>,
  303    language_server_paths_watched_for_rename:
  304        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  305    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  306    supplementary_language_servers:
  307        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  308    prettier_store: Entity<PrettierStore>,
  309    next_diagnostic_group_id: usize,
  310    diagnostics: HashMap<
  311        WorktreeId,
  312        HashMap<
  313            Arc<RelPath>,
  314            Vec<(
  315                LanguageServerId,
  316                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  317            )>,
  318        >,
  319    >,
  320    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  321    _subscription: gpui::Subscription,
  322    lsp_tree: LanguageServerTree,
  323    registered_buffers: HashMap<BufferId, usize>,
  324    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  325    buffer_pull_diagnostics_result_ids: HashMap<
  326        LanguageServerId,
  327        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  328    >,
  329    workspace_pull_diagnostics_result_ids: HashMap<
  330        LanguageServerId,
  331        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  332    >,
  333    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  334
  335    buffers_to_refresh_hash_set: HashSet<BufferId>,
  336    buffers_to_refresh_queue: VecDeque<BufferId>,
  337    _background_diagnostics_worker: Shared<Task<()>>,
  338}
  339
  340impl LocalLspStore {
  341    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  342    pub fn running_language_server_for_id(
  343        &self,
  344        id: LanguageServerId,
  345    ) -> Option<&Arc<LanguageServer>> {
  346        let language_server_state = self.language_servers.get(&id)?;
  347
  348        match language_server_state {
  349            LanguageServerState::Running { server, .. } => Some(server),
  350            LanguageServerState::Starting { .. } => None,
  351        }
  352    }
  353
  354    fn get_or_insert_language_server(
  355        &mut self,
  356        worktree_handle: &Entity<Worktree>,
  357        delegate: Arc<LocalLspAdapterDelegate>,
  358        disposition: &Arc<LaunchDisposition>,
  359        language_name: &LanguageName,
  360        cx: &mut App,
  361    ) -> LanguageServerId {
  362        let key = LanguageServerSeed {
  363            worktree_id: worktree_handle.read(cx).id(),
  364            name: disposition.server_name.clone(),
  365            settings: LanguageServerSeedSettings {
  366                binary: disposition.settings.binary.clone(),
  367                initialization_options: disposition.settings.initialization_options.clone(),
  368            },
  369            toolchain: disposition.toolchain.clone(),
  370        };
  371        if let Some(state) = self.language_server_ids.get_mut(&key) {
  372            state.project_roots.insert(disposition.path.path.clone());
  373            state.id
  374        } else {
  375            let adapter = self
  376                .languages
  377                .lsp_adapters(language_name)
  378                .into_iter()
  379                .find(|adapter| adapter.name() == disposition.server_name)
  380                .expect("To find LSP adapter");
  381            let new_language_server_id = self.start_language_server(
  382                worktree_handle,
  383                delegate,
  384                adapter,
  385                disposition.settings.clone(),
  386                key.clone(),
  387                language_name.clone(),
  388                cx,
  389            );
  390            if let Some(state) = self.language_server_ids.get_mut(&key) {
  391                state.project_roots.insert(disposition.path.path.clone());
  392            } else {
  393                debug_assert!(
  394                    false,
  395                    "Expected `start_language_server` to ensure that `key` exists in a map"
  396                );
  397            }
  398            new_language_server_id
  399        }
  400    }
  401
  402    fn start_language_server(
  403        &mut self,
  404        worktree_handle: &Entity<Worktree>,
  405        delegate: Arc<LocalLspAdapterDelegate>,
  406        adapter: Arc<CachedLspAdapter>,
  407        settings: Arc<LspSettings>,
  408        key: LanguageServerSeed,
  409        language_name: LanguageName,
  410        cx: &mut App,
  411    ) -> LanguageServerId {
  412        let worktree = worktree_handle.read(cx);
  413
  414        let worktree_id = worktree.id();
  415        let worktree_abs_path = worktree.abs_path();
  416        let toolchain = key.toolchain.clone();
  417        let override_options = settings.initialization_options.clone();
  418
  419        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  420
  421        let server_id = self.languages.next_language_server_id();
  422        log::trace!(
  423            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  424            adapter.name.0
  425        );
  426
  427        let wait_until_worktree_trust =
  428            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  429                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  430                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  431                });
  432                if can_trust {
  433                    self.restricted_worktrees_tasks.remove(&worktree_id);
  434                    None
  435                } else {
  436                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  437                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  438                        hash_map::Entry::Vacant(v) => {
  439                            let (mut tx, rx) = watch::channel::<bool>();
  440                            let lsp_store = self.weak.clone();
  441                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  442                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  443                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  444                                        tx.blocking_send(true).ok();
  445                                        lsp_store
  446                                            .update(cx, |lsp_store, _| {
  447                                                if let Some(local_lsp_store) =
  448                                                    lsp_store.as_local_mut()
  449                                                {
  450                                                    local_lsp_store
  451                                                        .restricted_worktrees_tasks
  452                                                        .remove(&worktree_id);
  453                                                }
  454                                            })
  455                                            .ok();
  456                                    }
  457                                }
  458                            });
  459                            v.insert((subscription, rx.clone()));
  460                            Some(rx)
  461                        }
  462                    }
  463                }
  464            });
  465        let update_binary_status = wait_until_worktree_trust.is_none();
  466
  467        let binary = self.get_language_server_binary(
  468            worktree_abs_path.clone(),
  469            adapter.clone(),
  470            settings,
  471            toolchain.clone(),
  472            delegate.clone(),
  473            true,
  474            wait_until_worktree_trust,
  475            cx,
  476        );
  477        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  478
  479        let pending_server = cx.spawn({
  480            let adapter = adapter.clone();
  481            let server_name = adapter.name.clone();
  482            let stderr_capture = stderr_capture.clone();
  483            #[cfg(any(test, feature = "test-support"))]
  484            let lsp_store = self.weak.clone();
  485            let pending_workspace_folders = pending_workspace_folders.clone();
  486            async move |cx| {
  487                let binary = binary.await?;
  488                #[cfg(any(test, feature = "test-support"))]
  489                if let Some(server) = lsp_store
  490                    .update(&mut cx.clone(), |this, cx| {
  491                        this.languages.create_fake_language_server(
  492                            server_id,
  493                            &server_name,
  494                            binary.clone(),
  495                            &mut cx.to_async(),
  496                        )
  497                    })
  498                    .ok()
  499                    .flatten()
  500                {
  501                    return Ok(server);
  502                }
  503
  504                let code_action_kinds = adapter.code_action_kinds();
  505                lsp::LanguageServer::new(
  506                    stderr_capture,
  507                    server_id,
  508                    server_name,
  509                    binary,
  510                    &worktree_abs_path,
  511                    code_action_kinds,
  512                    Some(pending_workspace_folders),
  513                    cx,
  514                )
  515            }
  516        });
  517
  518        let startup = {
  519            let server_name = adapter.name.0.clone();
  520            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  521            let key = key.clone();
  522            let adapter = adapter.clone();
  523            let lsp_store = self.weak.clone();
  524            let pending_workspace_folders = pending_workspace_folders.clone();
  525            let pull_diagnostics = ProjectSettings::get_global(cx)
  526                .diagnostics
  527                .lsp_pull_diagnostics
  528                .enabled;
  529            let settings_location = SettingsLocation {
  530                worktree_id,
  531                path: RelPath::empty(),
  532            };
  533            let augments_syntax_tokens = AllLanguageSettings::get(Some(settings_location), cx)
  534                .language(Some(settings_location), Some(&language_name), cx)
  535                .semantic_tokens
  536                .use_tree_sitter();
  537            cx.spawn(async move |cx| {
  538                let result = async {
  539                    let language_server = pending_server.await?;
  540
  541                    let workspace_config = Self::workspace_configuration_for_adapter(
  542                        adapter.adapter.clone(),
  543                        &delegate,
  544                        toolchain,
  545                        None,
  546                        cx,
  547                    )
  548                    .await?;
  549
  550                    let mut initialization_options = Self::initialization_options_for_adapter(
  551                        adapter.adapter.clone(),
  552                        &delegate,
  553                        cx,
  554                    )
  555                    .await?;
  556
  557                    match (&mut initialization_options, override_options) {
  558                        (Some(initialization_options), Some(override_options)) => {
  559                            merge_json_value_into(override_options, initialization_options);
  560                        }
  561                        (None, override_options) => initialization_options = override_options,
  562                        _ => {}
  563                    }
  564
  565                    let initialization_params = cx.update(|cx| {
  566                        let mut params = language_server.default_initialize_params(
  567                            pull_diagnostics,
  568                            augments_syntax_tokens,
  569                            cx,
  570                        );
  571                        params.initialization_options = initialization_options;
  572                        adapter.adapter.prepare_initialize_params(params, cx)
  573                    })?;
  574
  575                    Self::setup_lsp_messages(
  576                        lsp_store.clone(),
  577                        &language_server,
  578                        delegate.clone(),
  579                        adapter.clone(),
  580                    );
  581
  582                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  583                        settings: workspace_config,
  584                    };
  585                    let language_server = cx
  586                        .update(|cx| {
  587                            let request_timeout = ProjectSettings::get_global(cx)
  588                                .global_lsp_settings
  589                                .get_request_timeout();
  590
  591                            language_server.initialize(
  592                                initialization_params,
  593                                Arc::new(did_change_configuration_params.clone()),
  594                                request_timeout,
  595                                cx,
  596                            )
  597                        })
  598                        .await
  599                        .inspect_err(|_| {
  600                            if let Some(lsp_store) = lsp_store.upgrade() {
  601                                lsp_store.update(cx, |lsp_store, cx| {
  602                                    lsp_store.cleanup_lsp_data(server_id);
  603                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  604                                });
  605                            }
  606                        })?;
  607
  608                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  609                        did_change_configuration_params,
  610                    )?;
  611
  612                    anyhow::Ok(language_server)
  613                }
  614                .await;
  615
  616                match result {
  617                    Ok(server) => {
  618                        lsp_store
  619                            .update(cx, |lsp_store, cx| {
  620                                lsp_store.insert_newly_running_language_server(
  621                                    adapter,
  622                                    server.clone(),
  623                                    server_id,
  624                                    key,
  625                                    pending_workspace_folders,
  626                                    cx,
  627                                );
  628                            })
  629                            .ok();
  630                        stderr_capture.lock().take();
  631                        Some(server)
  632                    }
  633
  634                    Err(err) => {
  635                        let log = stderr_capture.lock().take().unwrap_or_default();
  636                        delegate.update_status(
  637                            adapter.name(),
  638                            BinaryStatus::Failed {
  639                                error: if log.is_empty() {
  640                                    format!("{err:#}")
  641                                } else {
  642                                    format!("{err:#}\n-- stderr --\n{log}")
  643                                },
  644                            },
  645                        );
  646                        log::error!(
  647                            "Failed to start language server {server_name:?}: {}",
  648                            redact_command(&format!("{err:?}"))
  649                        );
  650                        if !log.is_empty() {
  651                            log::error!("server stderr: {}", redact_command(&log));
  652                        }
  653                        None
  654                    }
  655                }
  656            })
  657        };
  658        let state = LanguageServerState::Starting {
  659            startup,
  660            pending_workspace_folders,
  661        };
  662
  663        if update_binary_status {
  664            self.languages
  665                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  666        }
  667
  668        self.language_servers.insert(server_id, state);
  669        self.language_server_ids
  670            .entry(key)
  671            .or_insert(UnifiedLanguageServer {
  672                id: server_id,
  673                project_roots: Default::default(),
  674            });
  675        server_id
  676    }
  677
  678    fn get_language_server_binary(
  679        &self,
  680        worktree_abs_path: Arc<Path>,
  681        adapter: Arc<CachedLspAdapter>,
  682        settings: Arc<LspSettings>,
  683        toolchain: Option<Toolchain>,
  684        delegate: Arc<dyn LspAdapterDelegate>,
  685        allow_binary_download: bool,
  686        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  687        cx: &mut App,
  688    ) -> Task<Result<LanguageServerBinary>> {
  689        if let Some(settings) = &settings.binary
  690            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  691        {
  692            let settings = settings.clone();
  693            let languages = self.languages.clone();
  694            return cx.background_spawn(async move {
  695                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  696                    let already_trusted =  *wait_until_worktree_trust.borrow();
  697                    if !already_trusted {
  698                        log::info!(
  699                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  700                            adapter.name(),
  701                        );
  702                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  703                            if worktree_trusted {
  704                                break;
  705                            }
  706                        }
  707                        log::info!(
  708                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  709                            adapter.name(),
  710                        );
  711                    }
  712                    languages
  713                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  714                }
  715                let mut env = delegate.shell_env().await;
  716                env.extend(settings.env.unwrap_or_default());
  717
  718                Ok(LanguageServerBinary {
  719                    path: delegate.resolve_relative_path(path),
  720                    env: Some(env),
  721                    arguments: settings
  722                        .arguments
  723                        .unwrap_or_default()
  724                        .iter()
  725                        .map(Into::into)
  726                        .collect(),
  727                })
  728            });
  729        }
  730        let lsp_binary_options = LanguageServerBinaryOptions {
  731            allow_path_lookup: !settings
  732                .binary
  733                .as_ref()
  734                .and_then(|b| b.ignore_system_version)
  735                .unwrap_or_default(),
  736            allow_binary_download,
  737            pre_release: settings
  738                .fetch
  739                .as_ref()
  740                .and_then(|f| f.pre_release)
  741                .unwrap_or(false),
  742        };
  743
  744        cx.spawn(async move |cx| {
  745            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  746                let already_trusted =  *wait_until_worktree_trust.borrow();
  747                if !already_trusted {
  748                    log::info!(
  749                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  750                        adapter.name(),
  751                    );
  752                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  753                        if worktree_trusted {
  754                            break;
  755                        }
  756                    }
  757                    log::info!(
  758                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  759                            adapter.name(),
  760                    );
  761                }
  762            }
  763
  764            let (existing_binary, maybe_download_binary) = adapter
  765                .clone()
  766                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  767                .await
  768                .await;
  769
  770            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  771
  772            let mut binary = match (existing_binary, maybe_download_binary) {
  773                (binary, None) => binary?,
  774                (Err(_), Some(downloader)) => downloader.await?,
  775                (Ok(existing_binary), Some(downloader)) => {
  776                    let mut download_timeout = cx
  777                        .background_executor()
  778                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  779                        .fuse();
  780                    let mut downloader = downloader.fuse();
  781                    futures::select! {
  782                        _ = download_timeout => {
  783                            // Return existing binary and kick the existing work to the background.
  784                            cx.spawn(async move |_| downloader.await).detach();
  785                            Ok(existing_binary)
  786                        },
  787                        downloaded_or_existing_binary = downloader => {
  788                            // If download fails, this results in the existing binary.
  789                            downloaded_or_existing_binary
  790                        }
  791                    }?
  792                }
  793            };
  794            let mut shell_env = delegate.shell_env().await;
  795
  796            shell_env.extend(binary.env.unwrap_or_default());
  797
  798            if let Some(settings) = settings.binary.as_ref() {
  799                if let Some(arguments) = &settings.arguments {
  800                    binary.arguments = arguments.iter().map(Into::into).collect();
  801                }
  802                if let Some(env) = &settings.env {
  803                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  804                }
  805            }
  806
  807            binary.env = Some(shell_env);
  808            Ok(binary)
  809        })
  810    }
  811
  812    fn setup_lsp_messages(
  813        lsp_store: WeakEntity<LspStore>,
  814        language_server: &LanguageServer,
  815        delegate: Arc<dyn LspAdapterDelegate>,
  816        adapter: Arc<CachedLspAdapter>,
  817    ) {
  818        let name = language_server.name();
  819        let server_id = language_server.server_id();
  820        language_server
  821            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  822                let adapter = adapter.clone();
  823                let this = lsp_store.clone();
  824                move |mut params, cx| {
  825                    let adapter = adapter.clone();
  826                    if let Some(this) = this.upgrade() {
  827                        this.update(cx, |this, cx| {
  828                            adapter.process_diagnostics(&mut params, server_id);
  829
  830                            this.merge_lsp_diagnostics(
  831                                DiagnosticSourceKind::Pushed,
  832                                vec![DocumentDiagnosticsUpdate {
  833                                    server_id,
  834                                    diagnostics: params,
  835                                    result_id: None,
  836                                    disk_based_sources: Cow::Borrowed(
  837                                        &adapter.disk_based_diagnostic_sources,
  838                                    ),
  839                                    registration_id: None,
  840                                }],
  841                                |_, diagnostic, _cx| match diagnostic.source_kind {
  842                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  843                                        adapter.retain_old_diagnostic(diagnostic)
  844                                    }
  845                                    DiagnosticSourceKind::Pulled => true,
  846                                },
  847                                cx,
  848                            )
  849                            .log_err();
  850                        });
  851                    }
  852                }
  853            })
  854            .detach();
  855        language_server
  856            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  857                let adapter = adapter.adapter.clone();
  858                let delegate = delegate.clone();
  859                let this = lsp_store.clone();
  860                move |params, cx| {
  861                    let adapter = adapter.clone();
  862                    let delegate = delegate.clone();
  863                    let this = this.clone();
  864                    let mut cx = cx.clone();
  865                    async move {
  866                        let toolchain_for_id = this
  867                            .update(&mut cx, |this, _| {
  868                                this.as_local()?.language_server_ids.iter().find_map(
  869                                    |(seed, value)| {
  870                                        (value.id == server_id).then(|| seed.toolchain.clone())
  871                                    },
  872                                )
  873                            })?
  874                            .context("Expected the LSP store to be in a local mode")?;
  875
  876                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  877                        for item in &params.items {
  878                            let scope_uri = item.scope_uri.clone();
  879                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  880                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  881                            else {
  882                                // We've already queried workspace configuration of this URI.
  883                                continue;
  884                            };
  885                            let workspace_config = Self::workspace_configuration_for_adapter(
  886                                adapter.clone(),
  887                                &delegate,
  888                                toolchain_for_id.clone(),
  889                                scope_uri,
  890                                &mut cx,
  891                            )
  892                            .await?;
  893                            new_scope_uri.insert(workspace_config);
  894                        }
  895
  896                        Ok(params
  897                            .items
  898                            .into_iter()
  899                            .filter_map(|item| {
  900                                let workspace_config =
  901                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  902                                if let Some(section) = &item.section {
  903                                    Some(
  904                                        workspace_config
  905                                            .get(section)
  906                                            .cloned()
  907                                            .unwrap_or(serde_json::Value::Null),
  908                                    )
  909                                } else {
  910                                    Some(workspace_config.clone())
  911                                }
  912                            })
  913                            .collect())
  914                    }
  915                }
  916            })
  917            .detach();
  918
  919        language_server
  920            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  921                let this = lsp_store.clone();
  922                move |_, cx| {
  923                    let this = this.clone();
  924                    let cx = cx.clone();
  925                    async move {
  926                        let Some(server) =
  927                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  928                        else {
  929                            return Ok(None);
  930                        };
  931                        let root = server.workspace_folders();
  932                        Ok(Some(
  933                            root.into_iter()
  934                                .map(|uri| WorkspaceFolder {
  935                                    uri,
  936                                    name: Default::default(),
  937                                })
  938                                .collect(),
  939                        ))
  940                    }
  941                }
  942            })
  943            .detach();
  944        // Even though we don't have handling for these requests, respond to them to
  945        // avoid stalling any language server like `gopls` which waits for a response
  946        // to these requests when initializing.
  947        language_server
  948            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  949                let this = lsp_store.clone();
  950                move |params, cx| {
  951                    let this = this.clone();
  952                    let mut cx = cx.clone();
  953                    async move {
  954                        this.update(&mut cx, |this, _| {
  955                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  956                            {
  957                                status
  958                                    .progress_tokens
  959                                    .insert(ProgressToken::from_lsp(params.token));
  960                            }
  961                        })?;
  962
  963                        Ok(())
  964                    }
  965                }
  966            })
  967            .detach();
  968
  969        language_server
  970            .on_request::<lsp::request::RegisterCapability, _, _>({
  971                let lsp_store = lsp_store.clone();
  972                move |params, cx| {
  973                    let lsp_store = lsp_store.clone();
  974                    let mut cx = cx.clone();
  975                    async move {
  976                        lsp_store
  977                            .update(&mut cx, |lsp_store, cx| {
  978                                if lsp_store.as_local().is_some() {
  979                                    match lsp_store
  980                                        .register_server_capabilities(server_id, params, cx)
  981                                    {
  982                                        Ok(()) => {}
  983                                        Err(e) => {
  984                                            log::error!(
  985                                                "Failed to register server capabilities: {e:#}"
  986                                            );
  987                                        }
  988                                    };
  989                                }
  990                            })
  991                            .ok();
  992                        Ok(())
  993                    }
  994                }
  995            })
  996            .detach();
  997
  998        language_server
  999            .on_request::<lsp::request::UnregisterCapability, _, _>({
 1000                let lsp_store = lsp_store.clone();
 1001                move |params, cx| {
 1002                    let lsp_store = lsp_store.clone();
 1003                    let mut cx = cx.clone();
 1004                    async move {
 1005                        lsp_store
 1006                            .update(&mut cx, |lsp_store, cx| {
 1007                                if lsp_store.as_local().is_some() {
 1008                                    match lsp_store
 1009                                        .unregister_server_capabilities(server_id, params, cx)
 1010                                    {
 1011                                        Ok(()) => {}
 1012                                        Err(e) => {
 1013                                            log::error!(
 1014                                                "Failed to unregister server capabilities: {e:#}"
 1015                                            );
 1016                                        }
 1017                                    }
 1018                                }
 1019                            })
 1020                            .ok();
 1021                        Ok(())
 1022                    }
 1023                }
 1024            })
 1025            .detach();
 1026
 1027        language_server
 1028            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
 1029                let this = lsp_store.clone();
 1030                move |params, cx| {
 1031                    let mut cx = cx.clone();
 1032                    let this = this.clone();
 1033                    async move {
 1034                        LocalLspStore::on_lsp_workspace_edit(
 1035                            this.clone(),
 1036                            params,
 1037                            server_id,
 1038                            &mut cx,
 1039                        )
 1040                        .await
 1041                    }
 1042                }
 1043            })
 1044            .detach();
 1045
 1046        language_server
 1047            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1048                let lsp_store = lsp_store.clone();
 1049                let request_id = Arc::new(AtomicUsize::new(0));
 1050                move |(), cx| {
 1051                    let lsp_store = lsp_store.clone();
 1052                    let request_id = request_id.clone();
 1053                    let mut cx = cx.clone();
 1054                    async move {
 1055                        lsp_store
 1056                            .update(&mut cx, |lsp_store, cx| {
 1057                                let request_id =
 1058                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1059                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1060                                    server_id,
 1061                                    request_id,
 1062                                });
 1063                                lsp_store
 1064                                    .downstream_client
 1065                                    .as_ref()
 1066                                    .map(|(client, project_id)| {
 1067                                        client.send(proto::RefreshInlayHints {
 1068                                            project_id: *project_id,
 1069                                            server_id: server_id.to_proto(),
 1070                                            request_id: request_id.map(|id| id as u64),
 1071                                        })
 1072                                    })
 1073                            })?
 1074                            .transpose()?;
 1075                        Ok(())
 1076                    }
 1077                }
 1078            })
 1079            .detach();
 1080
 1081        language_server
 1082            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1083                let this = lsp_store.clone();
 1084                move |(), cx| {
 1085                    let this = this.clone();
 1086                    let mut cx = cx.clone();
 1087                    async move {
 1088                        this.update(&mut cx, |this, cx| {
 1089                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1090                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1091                                client.send(proto::RefreshCodeLens {
 1092                                    project_id: *project_id,
 1093                                })
 1094                            })
 1095                        })?
 1096                        .transpose()?;
 1097                        Ok(())
 1098                    }
 1099                }
 1100            })
 1101            .detach();
 1102
 1103        language_server
 1104            .on_request::<lsp::request::SemanticTokensRefresh, _, _>({
 1105                let lsp_store = lsp_store.clone();
 1106                let request_id = Arc::new(AtomicUsize::new(0));
 1107                move |(), cx| {
 1108                    let lsp_store = lsp_store.clone();
 1109                    let request_id = request_id.clone();
 1110                    let mut cx = cx.clone();
 1111                    async move {
 1112                        lsp_store
 1113                            .update(&mut cx, |lsp_store, cx| {
 1114                                let request_id =
 1115                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1116                                cx.emit(LspStoreEvent::RefreshSemanticTokens {
 1117                                    server_id,
 1118                                    request_id,
 1119                                });
 1120                                lsp_store
 1121                                    .downstream_client
 1122                                    .as_ref()
 1123                                    .map(|(client, project_id)| {
 1124                                        client.send(proto::RefreshSemanticTokens {
 1125                                            project_id: *project_id,
 1126                                            server_id: server_id.to_proto(),
 1127                                            request_id: request_id.map(|id| id as u64),
 1128                                        })
 1129                                    })
 1130                            })?
 1131                            .transpose()?;
 1132                        Ok(())
 1133                    }
 1134                }
 1135            })
 1136            .detach();
 1137
 1138        language_server
 1139            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1140                let this = lsp_store.clone();
 1141                move |(), cx| {
 1142                    let this = this.clone();
 1143                    let mut cx = cx.clone();
 1144                    async move {
 1145                        this.update(&mut cx, |lsp_store, cx| {
 1146                            lsp_store.pull_workspace_diagnostics(server_id);
 1147                            lsp_store
 1148                                .downstream_client
 1149                                .as_ref()
 1150                                .map(|(client, project_id)| {
 1151                                    client.send(proto::PullWorkspaceDiagnostics {
 1152                                        project_id: *project_id,
 1153                                        server_id: server_id.to_proto(),
 1154                                    })
 1155                                })
 1156                                .transpose()?;
 1157                            anyhow::Ok(
 1158                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1159                            )
 1160                        })??
 1161                        .await;
 1162                        Ok(())
 1163                    }
 1164                }
 1165            })
 1166            .detach();
 1167
 1168        language_server
 1169            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1170                let this = lsp_store.clone();
 1171                let name = name.to_string();
 1172                let adapter = adapter.clone();
 1173                move |params, cx| {
 1174                    let this = this.clone();
 1175                    let name = name.to_string();
 1176                    let adapter = adapter.clone();
 1177                    let mut cx = cx.clone();
 1178                    async move {
 1179                        let actions = params.actions.unwrap_or_default();
 1180                        let message = params.message.clone();
 1181                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1182                        let level = match params.typ {
 1183                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1184                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1185                            _ => PromptLevel::Info,
 1186                        };
 1187                        let request = LanguageServerPromptRequest::new(
 1188                            level,
 1189                            params.message,
 1190                            actions,
 1191                            name.clone(),
 1192                            tx,
 1193                        );
 1194
 1195                        let did_update = this
 1196                            .update(&mut cx, |_, cx| {
 1197                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1198                            })
 1199                            .is_ok();
 1200                        if did_update {
 1201                            let response = rx.recv().await.ok();
 1202                            if let Some(ref selected_action) = response {
 1203                                let context = language::PromptResponseContext {
 1204                                    message,
 1205                                    selected_action: selected_action.clone(),
 1206                                };
 1207                                adapter.process_prompt_response(&context, &mut cx)
 1208                            }
 1209
 1210                            Ok(response)
 1211                        } else {
 1212                            Ok(None)
 1213                        }
 1214                    }
 1215                }
 1216            })
 1217            .detach();
 1218        language_server
 1219            .on_notification::<lsp::notification::ShowMessage, _>({
 1220                let this = lsp_store.clone();
 1221                let name = name.to_string();
 1222                move |params, cx| {
 1223                    let this = this.clone();
 1224                    let name = name.to_string();
 1225                    let mut cx = cx.clone();
 1226
 1227                    let (tx, _) = smol::channel::bounded(1);
 1228                    let level = match params.typ {
 1229                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1230                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1231                        _ => PromptLevel::Info,
 1232                    };
 1233                    let request =
 1234                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1235
 1236                    let _ = this.update(&mut cx, |_, cx| {
 1237                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1238                    });
 1239                }
 1240            })
 1241            .detach();
 1242
 1243        let disk_based_diagnostics_progress_token =
 1244            adapter.disk_based_diagnostics_progress_token.clone();
 1245
 1246        language_server
 1247            .on_notification::<lsp::notification::Progress, _>({
 1248                let this = lsp_store.clone();
 1249                move |params, cx| {
 1250                    if let Some(this) = this.upgrade() {
 1251                        this.update(cx, |this, cx| {
 1252                            this.on_lsp_progress(
 1253                                params,
 1254                                server_id,
 1255                                disk_based_diagnostics_progress_token.clone(),
 1256                                cx,
 1257                            );
 1258                        });
 1259                    }
 1260                }
 1261            })
 1262            .detach();
 1263
 1264        language_server
 1265            .on_notification::<lsp::notification::LogMessage, _>({
 1266                let this = lsp_store.clone();
 1267                move |params, cx| {
 1268                    if let Some(this) = this.upgrade() {
 1269                        this.update(cx, |_, cx| {
 1270                            cx.emit(LspStoreEvent::LanguageServerLog(
 1271                                server_id,
 1272                                LanguageServerLogType::Log(params.typ),
 1273                                params.message,
 1274                            ));
 1275                        });
 1276                    }
 1277                }
 1278            })
 1279            .detach();
 1280
 1281        language_server
 1282            .on_notification::<lsp::notification::LogTrace, _>({
 1283                let this = lsp_store.clone();
 1284                move |params, cx| {
 1285                    let mut cx = cx.clone();
 1286                    if let Some(this) = this.upgrade() {
 1287                        this.update(&mut cx, |_, cx| {
 1288                            cx.emit(LspStoreEvent::LanguageServerLog(
 1289                                server_id,
 1290                                LanguageServerLogType::Trace {
 1291                                    verbose_info: params.verbose,
 1292                                },
 1293                                params.message,
 1294                            ));
 1295                        });
 1296                    }
 1297                }
 1298            })
 1299            .detach();
 1300
 1301        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1302        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1303        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1304        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1305    }
 1306
 1307    fn shutdown_language_servers_on_quit(&mut self) -> impl Future<Output = ()> + use<> {
 1308        let shutdown_futures = self
 1309            .language_servers
 1310            .drain()
 1311            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1312            .collect::<Vec<_>>();
 1313
 1314        async move {
 1315            join_all(shutdown_futures).await;
 1316        }
 1317    }
 1318
 1319    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1320        match server_state {
 1321            LanguageServerState::Running { server, .. } => {
 1322                if let Some(shutdown) = server.shutdown() {
 1323                    shutdown.await;
 1324                }
 1325            }
 1326            LanguageServerState::Starting { startup, .. } => {
 1327                if let Some(server) = startup.await
 1328                    && let Some(shutdown) = server.shutdown()
 1329                {
 1330                    shutdown.await;
 1331                }
 1332            }
 1333        }
 1334        Ok(())
 1335    }
 1336
 1337    fn language_servers_for_worktree(
 1338        &self,
 1339        worktree_id: WorktreeId,
 1340    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1341        self.language_server_ids
 1342            .iter()
 1343            .filter_map(move |(seed, state)| {
 1344                if seed.worktree_id != worktree_id {
 1345                    return None;
 1346                }
 1347
 1348                if let Some(LanguageServerState::Running { server, .. }) =
 1349                    self.language_servers.get(&state.id)
 1350                {
 1351                    Some(server)
 1352                } else {
 1353                    None
 1354                }
 1355            })
 1356    }
 1357
 1358    fn language_server_ids_for_project_path(
 1359        &self,
 1360        project_path: ProjectPath,
 1361        language: &Language,
 1362        cx: &mut App,
 1363    ) -> Vec<LanguageServerId> {
 1364        let Some(worktree) = self
 1365            .worktree_store
 1366            .read(cx)
 1367            .worktree_for_id(project_path.worktree_id, cx)
 1368        else {
 1369            return Vec::new();
 1370        };
 1371        let delegate: Arc<dyn ManifestDelegate> =
 1372            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1373
 1374        self.lsp_tree
 1375            .get(
 1376                project_path,
 1377                language.name(),
 1378                language.manifest(),
 1379                &delegate,
 1380                cx,
 1381            )
 1382            .collect::<Vec<_>>()
 1383    }
 1384
 1385    fn language_server_ids_for_buffer(
 1386        &self,
 1387        buffer: &Buffer,
 1388        cx: &mut App,
 1389    ) -> Vec<LanguageServerId> {
 1390        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1391            let worktree_id = file.worktree_id(cx);
 1392
 1393            let path: Arc<RelPath> = file
 1394                .path()
 1395                .parent()
 1396                .map(Arc::from)
 1397                .unwrap_or_else(|| file.path().clone());
 1398            let worktree_path = ProjectPath { worktree_id, path };
 1399            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1400        } else {
 1401            Vec::new()
 1402        }
 1403    }
 1404
 1405    fn language_servers_for_buffer<'a>(
 1406        &'a self,
 1407        buffer: &'a Buffer,
 1408        cx: &'a mut App,
 1409    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1410        self.language_server_ids_for_buffer(buffer, cx)
 1411            .into_iter()
 1412            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1413                LanguageServerState::Running {
 1414                    adapter, server, ..
 1415                } => Some((adapter, server)),
 1416                _ => None,
 1417            })
 1418    }
 1419
 1420    async fn execute_code_action_kind_locally(
 1421        lsp_store: WeakEntity<LspStore>,
 1422        mut buffers: Vec<Entity<Buffer>>,
 1423        kind: CodeActionKind,
 1424        push_to_history: bool,
 1425        cx: &mut AsyncApp,
 1426    ) -> anyhow::Result<ProjectTransaction> {
 1427        // Do not allow multiple concurrent code actions requests for the
 1428        // same buffer.
 1429        lsp_store.update(cx, |this, cx| {
 1430            let this = this.as_local_mut().unwrap();
 1431            buffers.retain(|buffer| {
 1432                this.buffers_being_formatted
 1433                    .insert(buffer.read(cx).remote_id())
 1434            });
 1435        })?;
 1436        let _cleanup = defer({
 1437            let this = lsp_store.clone();
 1438            let mut cx = cx.clone();
 1439            let buffers = &buffers;
 1440            move || {
 1441                this.update(&mut cx, |this, cx| {
 1442                    let this = this.as_local_mut().unwrap();
 1443                    for buffer in buffers {
 1444                        this.buffers_being_formatted
 1445                            .remove(&buffer.read(cx).remote_id());
 1446                    }
 1447                })
 1448                .ok();
 1449            }
 1450        });
 1451        let mut project_transaction = ProjectTransaction::default();
 1452
 1453        for buffer in &buffers {
 1454            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1455                buffer.update(cx, |buffer, cx| {
 1456                    lsp_store
 1457                        .as_local()
 1458                        .unwrap()
 1459                        .language_servers_for_buffer(buffer, cx)
 1460                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1461                        .collect::<Vec<_>>()
 1462                })
 1463            })?;
 1464            for (_, language_server) in adapters_and_servers.iter() {
 1465                let actions = Self::get_server_code_actions_from_action_kinds(
 1466                    &lsp_store,
 1467                    language_server.server_id(),
 1468                    vec![kind.clone()],
 1469                    buffer,
 1470                    cx,
 1471                )
 1472                .await?;
 1473                Self::execute_code_actions_on_server(
 1474                    &lsp_store,
 1475                    language_server,
 1476                    actions,
 1477                    push_to_history,
 1478                    &mut project_transaction,
 1479                    cx,
 1480                )
 1481                .await?;
 1482            }
 1483        }
 1484        Ok(project_transaction)
 1485    }
 1486
 1487    async fn format_locally(
 1488        lsp_store: WeakEntity<LspStore>,
 1489        mut buffers: Vec<FormattableBuffer>,
 1490        push_to_history: bool,
 1491        trigger: FormatTrigger,
 1492        logger: zlog::Logger,
 1493        cx: &mut AsyncApp,
 1494    ) -> anyhow::Result<ProjectTransaction> {
 1495        // Do not allow multiple concurrent formatting requests for the
 1496        // same buffer.
 1497        lsp_store.update(cx, |this, cx| {
 1498            let this = this.as_local_mut().unwrap();
 1499            buffers.retain(|buffer| {
 1500                this.buffers_being_formatted
 1501                    .insert(buffer.handle.read(cx).remote_id())
 1502            });
 1503        })?;
 1504
 1505        let _cleanup = defer({
 1506            let this = lsp_store.clone();
 1507            let mut cx = cx.clone();
 1508            let buffers = &buffers;
 1509            move || {
 1510                this.update(&mut cx, |this, cx| {
 1511                    let this = this.as_local_mut().unwrap();
 1512                    for buffer in buffers {
 1513                        this.buffers_being_formatted
 1514                            .remove(&buffer.handle.read(cx).remote_id());
 1515                    }
 1516                })
 1517                .ok();
 1518            }
 1519        });
 1520
 1521        let mut project_transaction = ProjectTransaction::default();
 1522
 1523        for buffer in &buffers {
 1524            zlog::debug!(
 1525                logger =>
 1526                "formatting buffer '{:?}'",
 1527                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1528            );
 1529            // Create an empty transaction to hold all of the formatting edits.
 1530            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1531                // ensure no transactions created while formatting are
 1532                // grouped with the previous transaction in the history
 1533                // based on the transaction group interval
 1534                buffer.finalize_last_transaction();
 1535                buffer
 1536                    .start_transaction()
 1537                    .context("transaction already open")?;
 1538                buffer.end_transaction(cx);
 1539                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1540                buffer.finalize_last_transaction();
 1541                anyhow::Ok(transaction_id)
 1542            })?;
 1543
 1544            let result = Self::format_buffer_locally(
 1545                lsp_store.clone(),
 1546                buffer,
 1547                formatting_transaction_id,
 1548                trigger,
 1549                logger,
 1550                cx,
 1551            )
 1552            .await;
 1553
 1554            buffer.handle.update(cx, |buffer, cx| {
 1555                let Some(formatting_transaction) =
 1556                    buffer.get_transaction(formatting_transaction_id).cloned()
 1557                else {
 1558                    zlog::warn!(logger => "no formatting transaction");
 1559                    return;
 1560                };
 1561                if formatting_transaction.edit_ids.is_empty() {
 1562                    zlog::debug!(logger => "no changes made while formatting");
 1563                    buffer.forget_transaction(formatting_transaction_id);
 1564                    return;
 1565                }
 1566                if !push_to_history {
 1567                    zlog::trace!(logger => "forgetting format transaction");
 1568                    buffer.forget_transaction(formatting_transaction.id);
 1569                }
 1570                project_transaction
 1571                    .0
 1572                    .insert(cx.entity(), formatting_transaction);
 1573            });
 1574
 1575            result?;
 1576        }
 1577
 1578        Ok(project_transaction)
 1579    }
 1580
 1581    async fn format_buffer_locally(
 1582        lsp_store: WeakEntity<LspStore>,
 1583        buffer: &FormattableBuffer,
 1584        formatting_transaction_id: clock::Lamport,
 1585        trigger: FormatTrigger,
 1586        logger: zlog::Logger,
 1587        cx: &mut AsyncApp,
 1588    ) -> Result<()> {
 1589        let (adapters_and_servers, settings, request_timeout) =
 1590            lsp_store.update(cx, |lsp_store, cx| {
 1591                buffer.handle.update(cx, |buffer, cx| {
 1592                    let adapters_and_servers = lsp_store
 1593                        .as_local()
 1594                        .unwrap()
 1595                        .language_servers_for_buffer(buffer, cx)
 1596                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1597                        .collect::<Vec<_>>();
 1598                    let settings = LanguageSettings::for_buffer(buffer, cx).into_owned();
 1599                    let request_timeout = ProjectSettings::get_global(cx)
 1600                        .global_lsp_settings
 1601                        .get_request_timeout();
 1602                    (adapters_and_servers, settings, request_timeout)
 1603                })
 1604            })?;
 1605
 1606        // handle whitespace formatting
 1607        if settings.remove_trailing_whitespace_on_save {
 1608            zlog::trace!(logger => "removing trailing whitespace");
 1609            let diff = buffer
 1610                .handle
 1611                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1612                .await;
 1613            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1614                buffer.apply_diff(diff, cx);
 1615            })?;
 1616        }
 1617
 1618        if settings.ensure_final_newline_on_save {
 1619            zlog::trace!(logger => "ensuring final newline");
 1620            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1621                buffer.ensure_final_newline(cx);
 1622            })?;
 1623        }
 1624
 1625        // Formatter for `code_actions_on_format` that runs before
 1626        // the rest of the formatters
 1627        let mut code_actions_on_format_formatters = None;
 1628        let should_run_code_actions_on_format = !matches!(
 1629            (trigger, &settings.format_on_save),
 1630            (FormatTrigger::Save, &FormatOnSave::Off)
 1631        );
 1632        if should_run_code_actions_on_format {
 1633            let have_code_actions_to_run_on_format = settings
 1634                .code_actions_on_format
 1635                .values()
 1636                .any(|enabled| *enabled);
 1637            if have_code_actions_to_run_on_format {
 1638                zlog::trace!(logger => "going to run code actions on format");
 1639                code_actions_on_format_formatters = Some(
 1640                    settings
 1641                        .code_actions_on_format
 1642                        .iter()
 1643                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1644                        .cloned()
 1645                        .map(Formatter::CodeAction)
 1646                        .collect::<Vec<_>>(),
 1647                );
 1648            }
 1649        }
 1650
 1651        let formatters = match (trigger, &settings.format_on_save) {
 1652            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1653            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1654                settings.formatter.as_ref()
 1655            }
 1656        };
 1657
 1658        let formatters = code_actions_on_format_formatters
 1659            .iter()
 1660            .flatten()
 1661            .chain(formatters);
 1662
 1663        for formatter in formatters {
 1664            let formatter = if formatter == &Formatter::Auto {
 1665                if settings.prettier.allowed {
 1666                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1667                    &Formatter::Prettier
 1668                } else {
 1669                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1670                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1671                }
 1672            } else {
 1673                formatter
 1674            };
 1675            if let Err(err) = Self::apply_formatter(
 1676                formatter,
 1677                &lsp_store,
 1678                buffer,
 1679                formatting_transaction_id,
 1680                &adapters_and_servers,
 1681                &settings,
 1682                request_timeout,
 1683                logger,
 1684                cx,
 1685            )
 1686            .await
 1687            {
 1688                zlog::error!(logger => "Formatter failed, skipping: {err:#}");
 1689            }
 1690        }
 1691
 1692        Ok(())
 1693    }
 1694
 1695    async fn apply_formatter(
 1696        formatter: &Formatter,
 1697        lsp_store: &WeakEntity<LspStore>,
 1698        buffer: &FormattableBuffer,
 1699        formatting_transaction_id: clock::Lamport,
 1700        adapters_and_servers: &[(Arc<CachedLspAdapter>, Arc<LanguageServer>)],
 1701        settings: &LanguageSettings,
 1702        request_timeout: Duration,
 1703        logger: zlog::Logger,
 1704        cx: &mut AsyncApp,
 1705    ) -> anyhow::Result<()> {
 1706        match formatter {
 1707            Formatter::None => {
 1708                zlog::trace!(logger => "skipping formatter 'none'");
 1709                return Ok(());
 1710            }
 1711            Formatter::Auto => {
 1712                debug_panic!("Auto resolved above");
 1713                return Ok(());
 1714            }
 1715            Formatter::Prettier => {
 1716                let logger = zlog::scoped!(logger => "prettier");
 1717                zlog::trace!(logger => "formatting");
 1718                let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1719
 1720                // When selection ranges are provided (via FormatSelections), we pass the
 1721                // encompassing UTF-16 range to Prettier so it can scope its formatting.
 1722                // After diffing, we filter the resulting edits to only keep those that
 1723                // overlap with the original byte-level selection ranges.
 1724                let (range_utf16, byte_ranges) = match buffer.ranges.as_ref() {
 1725                    Some(ranges) if !ranges.is_empty() => {
 1726                        let (utf16_range, byte_ranges) =
 1727                            buffer.handle.read_with(cx, |buffer, _cx| {
 1728                                let snapshot = buffer.snapshot();
 1729                                let mut min_start_utf16 = OffsetUtf16(usize::MAX);
 1730                                let mut max_end_utf16 = OffsetUtf16(0);
 1731                                let mut byte_ranges = Vec::with_capacity(ranges.len());
 1732                                for range in ranges {
 1733                                    let start_utf16 = range.start.to_offset_utf16(&snapshot);
 1734                                    let end_utf16 = range.end.to_offset_utf16(&snapshot);
 1735                                    min_start_utf16.0 = min_start_utf16.0.min(start_utf16.0);
 1736                                    max_end_utf16.0 = max_end_utf16.0.max(end_utf16.0);
 1737
 1738                                    let start_byte = range.start.to_offset(&snapshot);
 1739                                    let end_byte = range.end.to_offset(&snapshot);
 1740                                    byte_ranges.push(start_byte..end_byte);
 1741                                }
 1742                                (min_start_utf16..max_end_utf16, byte_ranges)
 1743                            });
 1744                        (Some(utf16_range), Some(byte_ranges))
 1745                    }
 1746                    _ => (None, None),
 1747                };
 1748
 1749                let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1750                    lsp_store.prettier_store().unwrap().downgrade()
 1751                })?;
 1752                let diff = prettier_store::format_with_prettier(
 1753                    &prettier,
 1754                    &buffer.handle,
 1755                    range_utf16,
 1756                    cx,
 1757                )
 1758                .await
 1759                .transpose()?;
 1760                let Some(mut diff) = diff else {
 1761                    zlog::trace!(logger => "No changes");
 1762                    return Ok(());
 1763                };
 1764
 1765                if let Some(byte_ranges) = byte_ranges {
 1766                    diff.edits.retain(|(edit_range, _)| {
 1767                        byte_ranges.iter().any(|selection_range| {
 1768                            edit_range.start < selection_range.end
 1769                                && edit_range.end > selection_range.start
 1770                        })
 1771                    });
 1772                    if diff.edits.is_empty() {
 1773                        zlog::trace!(logger => "No changes within selection");
 1774                        return Ok(());
 1775                    }
 1776                }
 1777
 1778                extend_formatting_transaction(
 1779                    buffer,
 1780                    formatting_transaction_id,
 1781                    cx,
 1782                    |buffer, cx| {
 1783                        buffer.apply_diff(diff, cx);
 1784                    },
 1785                )?;
 1786            }
 1787            Formatter::External { command, arguments } => {
 1788                let logger = zlog::scoped!(logger => "command");
 1789
 1790                if buffer.ranges.is_some() {
 1791                    zlog::debug!(logger => "External formatter does not support range formatting; skipping");
 1792                    return Ok(());
 1793                }
 1794
 1795                zlog::trace!(logger => "formatting");
 1796                let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1797
 1798                let diff =
 1799                    Self::format_via_external_command(buffer, &command, arguments.as_deref(), cx)
 1800                        .await
 1801                        .with_context(|| {
 1802                            format!("Failed to format buffer via external command: {}", command)
 1803                        })?;
 1804                let Some(diff) = diff else {
 1805                    zlog::trace!(logger => "No changes");
 1806                    return Ok(());
 1807                };
 1808
 1809                extend_formatting_transaction(
 1810                    buffer,
 1811                    formatting_transaction_id,
 1812                    cx,
 1813                    |buffer, cx| {
 1814                        buffer.apply_diff(diff, cx);
 1815                    },
 1816                )?;
 1817            }
 1818            Formatter::LanguageServer(specifier) => {
 1819                let logger = zlog::scoped!(logger => "language-server");
 1820                zlog::trace!(logger => "formatting");
 1821                let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1822
 1823                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1824                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1825                    return Ok(());
 1826                };
 1827
 1828                let language_server = match specifier {
 1829                    settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1830                        adapters_and_servers.iter().find_map(|(adapter, server)| {
 1831                            if adapter.name.0.as_ref() == name {
 1832                                Some(server.clone())
 1833                            } else {
 1834                                None
 1835                            }
 1836                        })
 1837                    }
 1838                    settings::LanguageServerFormatterSpecifier::Current => adapters_and_servers
 1839                        .iter()
 1840                        .find(|(_, server)| Self::server_supports_formatting(server))
 1841                        .map(|(_, server)| server.clone()),
 1842                };
 1843
 1844                let Some(language_server) = language_server else {
 1845                    log::debug!(
 1846                        "No language server found to format buffer '{:?}'. Skipping",
 1847                        buffer_path_abs.as_path().to_string_lossy()
 1848                    );
 1849                    return Ok(());
 1850                };
 1851
 1852                zlog::trace!(
 1853                    logger =>
 1854                    "Formatting buffer '{:?}' using language server '{:?}'",
 1855                    buffer_path_abs.as_path().to_string_lossy(),
 1856                    language_server.name()
 1857                );
 1858
 1859                let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1860                    zlog::trace!(logger => "formatting ranges");
 1861                    Self::format_ranges_via_lsp(
 1862                        &lsp_store,
 1863                        &buffer.handle,
 1864                        ranges,
 1865                        buffer_path_abs,
 1866                        &language_server,
 1867                        &settings,
 1868                        cx,
 1869                    )
 1870                    .await
 1871                    .context("Failed to format ranges via language server")?
 1872                } else {
 1873                    zlog::trace!(logger => "formatting full");
 1874                    Self::format_via_lsp(
 1875                        &lsp_store,
 1876                        &buffer.handle,
 1877                        buffer_path_abs,
 1878                        &language_server,
 1879                        &settings,
 1880                        cx,
 1881                    )
 1882                    .await
 1883                    .context("failed to format via language server")?
 1884                };
 1885
 1886                if edits.is_empty() {
 1887                    zlog::trace!(logger => "No changes");
 1888                    return Ok(());
 1889                }
 1890                extend_formatting_transaction(
 1891                    buffer,
 1892                    formatting_transaction_id,
 1893                    cx,
 1894                    |buffer, cx| {
 1895                        buffer.edit(edits, None, cx);
 1896                    },
 1897                )?;
 1898            }
 1899            Formatter::CodeAction(code_action_name) => {
 1900                let logger = zlog::scoped!(logger => "code-actions");
 1901                zlog::trace!(logger => "formatting");
 1902                let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1903
 1904                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1905                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1906                    return Ok(());
 1907                };
 1908
 1909                let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1910                zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1911
 1912                let mut actions_and_servers = Vec::new();
 1913
 1914                for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1915                    let actions_result = Self::get_server_code_actions_from_action_kinds(
 1916                        &lsp_store,
 1917                        language_server.server_id(),
 1918                        vec![code_action_kind.clone()],
 1919                        &buffer.handle,
 1920                        cx,
 1921                    )
 1922                    .await
 1923                    .with_context(|| {
 1924                        format!(
 1925                            "Failed to resolve code action {:?} with language server {}",
 1926                            code_action_kind,
 1927                            language_server.name()
 1928                        )
 1929                    });
 1930                    let Ok(actions) = actions_result else {
 1931                        // note: it may be better to set result to the error and break formatters here
 1932                        // but for now we try to execute the actions that we can resolve and skip the rest
 1933                        zlog::error!(
 1934                            logger =>
 1935                            "Failed to resolve code action {:?} with language server {}",
 1936                            code_action_kind,
 1937                            language_server.name()
 1938                        );
 1939                        continue;
 1940                    };
 1941                    for action in actions {
 1942                        actions_and_servers.push((action, index));
 1943                    }
 1944                }
 1945
 1946                if actions_and_servers.is_empty() {
 1947                    zlog::warn!(logger => "No code actions were resolved, continuing");
 1948                    return Ok(());
 1949                }
 1950
 1951                'actions: for (mut action, server_index) in actions_and_servers {
 1952                    let server = &adapters_and_servers[server_index].1;
 1953
 1954                    let describe_code_action = |action: &CodeAction| {
 1955                        format!(
 1956                            "code action '{}' with title \"{}\" on server {}",
 1957                            action
 1958                                .lsp_action
 1959                                .action_kind()
 1960                                .unwrap_or("unknown".into())
 1961                                .as_str(),
 1962                            action.lsp_action.title(),
 1963                            server.name(),
 1964                        )
 1965                    };
 1966
 1967                    zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1968
 1969                    if let Err(err) =
 1970                        Self::try_resolve_code_action(server, &mut action, request_timeout).await
 1971                    {
 1972                        zlog::error!(
 1973                            logger =>
 1974                            "Failed to resolve {}. Error: {}",
 1975                            describe_code_action(&action),
 1976                            err
 1977                        );
 1978                        continue;
 1979                    }
 1980
 1981                    if let Some(edit) = action.lsp_action.edit().cloned() {
 1982                        // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1983                        // but filters out and logs warnings for code actions that require unreasonably
 1984                        // difficult handling on our part, such as:
 1985                        // - applying edits that call commands
 1986                        //   which can result in arbitrary workspace edits being sent from the server that
 1987                        //   have no way of being tied back to the command that initiated them (i.e. we
 1988                        //   can't know which edits are part of the format request, or if the server is done sending
 1989                        //   actions in response to the command)
 1990                        // - actions that create/delete/modify/rename files other than the one we are formatting
 1991                        //   as we then would need to handle such changes correctly in the local history as well
 1992                        //   as the remote history through the ProjectTransaction
 1993                        // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1994                        // Supporting these actions is not impossible, but not supported as of yet.
 1995                        if edit.changes.is_none() && edit.document_changes.is_none() {
 1996                            zlog::trace!(
 1997                                logger =>
 1998                                "No changes for code action. Skipping {}",
 1999                                describe_code_action(&action),
 2000                            );
 2001                            continue;
 2002                        }
 2003
 2004                        let mut operations = Vec::new();
 2005                        if let Some(document_changes) = edit.document_changes {
 2006                            match document_changes {
 2007                                lsp::DocumentChanges::Edits(edits) => operations.extend(
 2008                                    edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 2009                                ),
 2010                                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2011                            }
 2012                        } else if let Some(changes) = edit.changes {
 2013                            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2014                                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2015                                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2016                                        uri,
 2017                                        version: None,
 2018                                    },
 2019                                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2020                                })
 2021                            }));
 2022                        }
 2023
 2024                        let mut edits = Vec::with_capacity(operations.len());
 2025
 2026                        if operations.is_empty() {
 2027                            zlog::trace!(
 2028                                logger =>
 2029                                "No changes for code action. Skipping {}",
 2030                                describe_code_action(&action),
 2031                            );
 2032                            continue;
 2033                        }
 2034                        for operation in operations {
 2035                            let op = match operation {
 2036                                lsp::DocumentChangeOperation::Edit(op) => op,
 2037                                lsp::DocumentChangeOperation::Op(_) => {
 2038                                    zlog::warn!(
 2039                                        logger =>
 2040                                        "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 2041                                        describe_code_action(&action),
 2042                                    );
 2043                                    continue 'actions;
 2044                                }
 2045                            };
 2046                            let Ok(file_path) = op.text_document.uri.to_file_path() else {
 2047                                zlog::warn!(
 2048                                    logger =>
 2049                                    "Failed to convert URI '{:?}' to file path. Skipping {}",
 2050                                    &op.text_document.uri,
 2051                                    describe_code_action(&action),
 2052                                );
 2053                                continue 'actions;
 2054                            };
 2055                            if &file_path != buffer_path_abs {
 2056                                zlog::warn!(
 2057                                    logger =>
 2058                                    "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 2059                                    file_path,
 2060                                    buffer_path_abs,
 2061                                    describe_code_action(&action),
 2062                                );
 2063                                continue 'actions;
 2064                            }
 2065
 2066                            let mut lsp_edits = Vec::new();
 2067                            for edit in op.edits {
 2068                                match edit {
 2069                                    Edit::Plain(edit) => {
 2070                                        if !lsp_edits.contains(&edit) {
 2071                                            lsp_edits.push(edit);
 2072                                        }
 2073                                    }
 2074                                    Edit::Annotated(edit) => {
 2075                                        if !lsp_edits.contains(&edit.text_edit) {
 2076                                            lsp_edits.push(edit.text_edit);
 2077                                        }
 2078                                    }
 2079                                    Edit::Snippet(_) => {
 2080                                        zlog::warn!(
 2081                                            logger =>
 2082                                            "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 2083                                            describe_code_action(&action),
 2084                                        );
 2085                                        continue 'actions;
 2086                                    }
 2087                                }
 2088                            }
 2089                            let edits_result = lsp_store
 2090                                .update(cx, |lsp_store, cx| {
 2091                                    lsp_store.as_local_mut().unwrap().edits_from_lsp(
 2092                                        &buffer.handle,
 2093                                        lsp_edits,
 2094                                        server.server_id(),
 2095                                        op.text_document.version,
 2096                                        cx,
 2097                                    )
 2098                                })?
 2099                                .await;
 2100                            let Ok(resolved_edits) = edits_result else {
 2101                                zlog::warn!(
 2102                                    logger =>
 2103                                    "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 2104                                    buffer_path_abs.as_path(),
 2105                                    describe_code_action(&action),
 2106                                );
 2107                                continue 'actions;
 2108                            };
 2109                            edits.extend(resolved_edits);
 2110                        }
 2111
 2112                        if edits.is_empty() {
 2113                            zlog::warn!(logger => "No edits resolved from LSP");
 2114                            continue;
 2115                        }
 2116
 2117                        extend_formatting_transaction(
 2118                            buffer,
 2119                            formatting_transaction_id,
 2120                            cx,
 2121                            |buffer, cx| {
 2122                                zlog::info!(
 2123                                    "Applying edits {edits:?}. Content: {:?}",
 2124                                    buffer.text()
 2125                                );
 2126                                buffer.edit(edits, None, cx);
 2127                                zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 2128                            },
 2129                        )?;
 2130                    }
 2131
 2132                    let Some(command) = action.lsp_action.command() else {
 2133                        continue;
 2134                    };
 2135
 2136                    zlog::warn!(
 2137                        logger =>
 2138                        "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2139                        &command.command,
 2140                    );
 2141
 2142                    let server_capabilities = server.capabilities();
 2143                    let available_commands = server_capabilities
 2144                        .execute_command_provider
 2145                        .as_ref()
 2146                        .map(|options| options.commands.as_slice())
 2147                        .unwrap_or_default();
 2148                    if !available_commands.contains(&command.command) {
 2149                        zlog::warn!(
 2150                            logger =>
 2151                            "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2152                            command.command,
 2153                            server.name(),
 2154                        );
 2155                        continue;
 2156                    }
 2157
 2158                    extend_formatting_transaction(
 2159                        buffer,
 2160                        formatting_transaction_id,
 2161                        cx,
 2162                        |_, _| {},
 2163                    )?;
 2164                    zlog::info!(logger => "Executing command {}", &command.command);
 2165
 2166                    lsp_store.update(cx, |this, _| {
 2167                        this.as_local_mut()
 2168                            .unwrap()
 2169                            .last_workspace_edits_by_language_server
 2170                            .remove(&server.server_id());
 2171                    })?;
 2172
 2173                    let execute_command_result = server
 2174                        .request::<lsp::request::ExecuteCommand>(
 2175                            lsp::ExecuteCommandParams {
 2176                                command: command.command.clone(),
 2177                                arguments: command.arguments.clone().unwrap_or_default(),
 2178                                ..Default::default()
 2179                            },
 2180                            request_timeout,
 2181                        )
 2182                        .await
 2183                        .into_response();
 2184
 2185                    if execute_command_result.is_err() {
 2186                        zlog::error!(
 2187                            logger =>
 2188                            "Failed to execute command '{}' as part of {}",
 2189                            &command.command,
 2190                            describe_code_action(&action),
 2191                        );
 2192                        continue 'actions;
 2193                    }
 2194
 2195                    let mut project_transaction_command = lsp_store.update(cx, |this, _| {
 2196                        this.as_local_mut()
 2197                            .unwrap()
 2198                            .last_workspace_edits_by_language_server
 2199                            .remove(&server.server_id())
 2200                            .unwrap_or_default()
 2201                    })?;
 2202
 2203                    if let Some(transaction) = project_transaction_command.0.remove(&buffer.handle)
 2204                    {
 2205                        zlog::trace!(
 2206                            logger =>
 2207                            "Successfully captured {} edits that resulted from command {}",
 2208                            transaction.edit_ids.len(),
 2209                            &command.command,
 2210                        );
 2211                        let transaction_id_project_transaction = transaction.id;
 2212                        buffer.handle.update(cx, |buffer, _| {
 2213                            // it may have been removed from history if push_to_history was
 2214                            // false in deserialize_workspace_edit. If so push it so we
 2215                            // can merge it with the format transaction
 2216                            // and pop the combined transaction off the history stack
 2217                            // later if push_to_history is false
 2218                            if buffer.get_transaction(transaction.id).is_none() {
 2219                                buffer.push_transaction(transaction, Instant::now());
 2220                            }
 2221                            buffer.merge_transactions(
 2222                                transaction_id_project_transaction,
 2223                                formatting_transaction_id,
 2224                            );
 2225                        });
 2226                    }
 2227
 2228                    if project_transaction_command.0.is_empty() {
 2229                        continue;
 2230                    }
 2231
 2232                    let mut extra_buffers = String::new();
 2233                    for buffer in project_transaction_command.0.keys() {
 2234                        buffer.read_with(cx, |b, cx| {
 2235                            let Some(path) = b.project_path(cx) else {
 2236                                return;
 2237                            };
 2238
 2239                            if !extra_buffers.is_empty() {
 2240                                extra_buffers.push_str(", ");
 2241                            }
 2242                            extra_buffers.push_str(path.path.as_unix_str());
 2243                        });
 2244                    }
 2245                    zlog::warn!(
 2246                        logger =>
 2247                        "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2248                        &command.command,
 2249                        extra_buffers,
 2250                    );
 2251                    // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2252                    // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2253                    // add it so it's included, and merge it into the format transaction when its created later
 2254                }
 2255            }
 2256        }
 2257
 2258        Ok(())
 2259    }
 2260
 2261    pub async fn format_ranges_via_lsp(
 2262        this: &WeakEntity<LspStore>,
 2263        buffer_handle: &Entity<Buffer>,
 2264        ranges: &[Range<Anchor>],
 2265        abs_path: &Path,
 2266        language_server: &Arc<LanguageServer>,
 2267        settings: &LanguageSettings,
 2268        cx: &mut AsyncApp,
 2269    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2270        let capabilities = &language_server.capabilities();
 2271        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2272        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2273            anyhow::bail!(
 2274                "{} language server does not support range formatting",
 2275                language_server.name()
 2276            );
 2277        }
 2278
 2279        let uri = file_path_to_lsp_url(abs_path)?;
 2280        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2281
 2282        let request_timeout = cx.update(|app| {
 2283            ProjectSettings::get_global(app)
 2284                .global_lsp_settings
 2285                .get_request_timeout()
 2286        });
 2287        let lsp_edits = {
 2288            let mut lsp_ranges = Vec::new();
 2289            this.update(cx, |_this, cx| {
 2290                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2291                // not have been sent to the language server. This seems like a fairly systemic
 2292                // issue, though, the resolution probably is not specific to formatting.
 2293                //
 2294                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2295                // LSP.
 2296                let snapshot = buffer_handle.read(cx).snapshot();
 2297                for range in ranges {
 2298                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2299                }
 2300                anyhow::Ok(())
 2301            })??;
 2302
 2303            let mut edits = None;
 2304            for range in lsp_ranges {
 2305                if let Some(mut edit) = language_server
 2306                    .request::<lsp::request::RangeFormatting>(
 2307                        lsp::DocumentRangeFormattingParams {
 2308                            text_document: text_document.clone(),
 2309                            range,
 2310                            options: lsp_command::lsp_formatting_options(settings),
 2311                            work_done_progress_params: Default::default(),
 2312                        },
 2313                        request_timeout,
 2314                    )
 2315                    .await
 2316                    .into_response()?
 2317                {
 2318                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2319                }
 2320            }
 2321            edits
 2322        };
 2323
 2324        if let Some(lsp_edits) = lsp_edits {
 2325            this.update(cx, |this, cx| {
 2326                this.as_local_mut().unwrap().edits_from_lsp(
 2327                    buffer_handle,
 2328                    lsp_edits,
 2329                    language_server.server_id(),
 2330                    None,
 2331                    cx,
 2332                )
 2333            })?
 2334            .await
 2335        } else {
 2336            Ok(Vec::with_capacity(0))
 2337        }
 2338    }
 2339
 2340    fn server_supports_formatting(server: &Arc<LanguageServer>) -> bool {
 2341        let capabilities = server.capabilities();
 2342        let formatting = capabilities.document_formatting_provider.as_ref();
 2343        matches!(formatting, Some(p) if *p != OneOf::Left(false))
 2344            || server_capabilities_support_range_formatting(&capabilities)
 2345    }
 2346
 2347    async fn format_via_lsp(
 2348        this: &WeakEntity<LspStore>,
 2349        buffer: &Entity<Buffer>,
 2350        abs_path: &Path,
 2351        language_server: &Arc<LanguageServer>,
 2352        settings: &LanguageSettings,
 2353        cx: &mut AsyncApp,
 2354    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2355        let logger = zlog::scoped!("lsp_format");
 2356        zlog::debug!(logger => "Formatting via LSP");
 2357
 2358        let uri = file_path_to_lsp_url(abs_path)?;
 2359        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2360        let capabilities = &language_server.capabilities();
 2361
 2362        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2363        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2364
 2365        let request_timeout = cx.update(|app| {
 2366            ProjectSettings::get_global(app)
 2367                .global_lsp_settings
 2368                .get_request_timeout()
 2369        });
 2370
 2371        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2372            let _timer = zlog::time!(logger => "format-full");
 2373            language_server
 2374                .request::<lsp::request::Formatting>(
 2375                    lsp::DocumentFormattingParams {
 2376                        text_document,
 2377                        options: lsp_command::lsp_formatting_options(settings),
 2378                        work_done_progress_params: Default::default(),
 2379                    },
 2380                    request_timeout,
 2381                )
 2382                .await
 2383                .into_response()?
 2384        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2385            let _timer = zlog::time!(logger => "format-range");
 2386            let buffer_start = lsp::Position::new(0, 0);
 2387            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2388            language_server
 2389                .request::<lsp::request::RangeFormatting>(
 2390                    lsp::DocumentRangeFormattingParams {
 2391                        text_document: text_document.clone(),
 2392                        range: lsp::Range::new(buffer_start, buffer_end),
 2393                        options: lsp_command::lsp_formatting_options(settings),
 2394                        work_done_progress_params: Default::default(),
 2395                    },
 2396                    request_timeout,
 2397                )
 2398                .await
 2399                .into_response()?
 2400        } else {
 2401            None
 2402        };
 2403
 2404        if let Some(lsp_edits) = lsp_edits {
 2405            this.update(cx, |this, cx| {
 2406                this.as_local_mut().unwrap().edits_from_lsp(
 2407                    buffer,
 2408                    lsp_edits,
 2409                    language_server.server_id(),
 2410                    None,
 2411                    cx,
 2412                )
 2413            })?
 2414            .await
 2415        } else {
 2416            Ok(Vec::with_capacity(0))
 2417        }
 2418    }
 2419
 2420    async fn format_via_external_command(
 2421        buffer: &FormattableBuffer,
 2422        command: &str,
 2423        arguments: Option<&[String]>,
 2424        cx: &mut AsyncApp,
 2425    ) -> Result<Option<Diff>> {
 2426        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2427            let file = File::from_dyn(buffer.file())?;
 2428            let worktree = file.worktree.read(cx);
 2429            let mut worktree_path = worktree.abs_path().to_path_buf();
 2430            if worktree.root_entry()?.is_file() {
 2431                worktree_path.pop();
 2432            }
 2433            Some(worktree_path)
 2434        });
 2435
 2436        use util::command::Stdio;
 2437        let mut child = util::command::new_command(command);
 2438
 2439        if let Some(buffer_env) = buffer.env.as_ref() {
 2440            child.envs(buffer_env);
 2441        }
 2442
 2443        if let Some(working_dir_path) = working_dir_path {
 2444            child.current_dir(working_dir_path);
 2445        }
 2446
 2447        if let Some(arguments) = arguments {
 2448            child.args(arguments.iter().map(|arg| {
 2449                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2450                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2451                } else {
 2452                    arg.replace("{buffer_path}", "Untitled")
 2453                }
 2454            }));
 2455        }
 2456
 2457        let mut child = child
 2458            .stdin(Stdio::piped())
 2459            .stdout(Stdio::piped())
 2460            .stderr(Stdio::piped())
 2461            .spawn()?;
 2462
 2463        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2464        let text = buffer
 2465            .handle
 2466            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2467        for chunk in text.chunks() {
 2468            stdin.write_all(chunk.as_bytes()).await?;
 2469        }
 2470        stdin.flush().await?;
 2471
 2472        let output = child.output().await?;
 2473        anyhow::ensure!(
 2474            output.status.success(),
 2475            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2476            output.status.code(),
 2477            String::from_utf8_lossy(&output.stdout),
 2478            String::from_utf8_lossy(&output.stderr),
 2479        );
 2480
 2481        let stdout = String::from_utf8(output.stdout)?;
 2482        Ok(Some(
 2483            buffer
 2484                .handle
 2485                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2486                .await,
 2487        ))
 2488    }
 2489
 2490    async fn try_resolve_code_action(
 2491        lang_server: &LanguageServer,
 2492        action: &mut CodeAction,
 2493        request_timeout: Duration,
 2494    ) -> anyhow::Result<()> {
 2495        match &mut action.lsp_action {
 2496            LspAction::Action(lsp_action) => {
 2497                if !action.resolved
 2498                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2499                    && lsp_action.data.is_some()
 2500                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2501                {
 2502                    **lsp_action = lang_server
 2503                        .request::<lsp::request::CodeActionResolveRequest>(
 2504                            *lsp_action.clone(),
 2505                            request_timeout,
 2506                        )
 2507                        .await
 2508                        .into_response()?;
 2509                }
 2510            }
 2511            LspAction::CodeLens(lens) => {
 2512                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2513                    *lens = lang_server
 2514                        .request::<lsp::request::CodeLensResolve>(lens.clone(), request_timeout)
 2515                        .await
 2516                        .into_response()?;
 2517                }
 2518            }
 2519            LspAction::Command(_) => {}
 2520        }
 2521
 2522        action.resolved = true;
 2523        anyhow::Ok(())
 2524    }
 2525
 2526    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2527        let buffer = buffer_handle.read(cx);
 2528
 2529        let file = buffer.file().cloned();
 2530
 2531        let Some(file) = File::from_dyn(file.as_ref()) else {
 2532            return;
 2533        };
 2534        if !file.is_local() {
 2535            return;
 2536        }
 2537        let path = ProjectPath::from_file(file, cx);
 2538        let worktree_id = file.worktree_id(cx);
 2539        let language = buffer.language().cloned();
 2540
 2541        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2542            for (server_id, diagnostics) in
 2543                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2544            {
 2545                self.update_buffer_diagnostics(
 2546                    buffer_handle,
 2547                    server_id,
 2548                    None,
 2549                    None,
 2550                    None,
 2551                    Vec::new(),
 2552                    diagnostics,
 2553                    cx,
 2554                )
 2555                .log_err();
 2556            }
 2557        }
 2558        let Some(language) = language else {
 2559            return;
 2560        };
 2561        let Some(snapshot) = self
 2562            .worktree_store
 2563            .read(cx)
 2564            .worktree_for_id(worktree_id, cx)
 2565            .map(|worktree| worktree.read(cx).snapshot())
 2566        else {
 2567            return;
 2568        };
 2569        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2570
 2571        for server_id in
 2572            self.lsp_tree
 2573                .get(path, language.name(), language.manifest(), &delegate, cx)
 2574        {
 2575            let server = self
 2576                .language_servers
 2577                .get(&server_id)
 2578                .and_then(|server_state| {
 2579                    if let LanguageServerState::Running { server, .. } = server_state {
 2580                        Some(server.clone())
 2581                    } else {
 2582                        None
 2583                    }
 2584                });
 2585            let server = match server {
 2586                Some(server) => server,
 2587                None => continue,
 2588            };
 2589
 2590            buffer_handle.update(cx, |buffer, cx| {
 2591                buffer.set_completion_triggers(
 2592                    server.server_id(),
 2593                    server
 2594                        .capabilities()
 2595                        .completion_provider
 2596                        .as_ref()
 2597                        .and_then(|provider| {
 2598                            provider
 2599                                .trigger_characters
 2600                                .as_ref()
 2601                                .map(|characters| characters.iter().cloned().collect())
 2602                        })
 2603                        .unwrap_or_default(),
 2604                    cx,
 2605                );
 2606            });
 2607        }
 2608    }
 2609
 2610    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2611        buffer.update(cx, |buffer, cx| {
 2612            let Some(language) = buffer.language() else {
 2613                return;
 2614            };
 2615            let path = ProjectPath {
 2616                worktree_id: old_file.worktree_id(cx),
 2617                path: old_file.path.clone(),
 2618            };
 2619            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2620                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2621                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2622            }
 2623        });
 2624    }
 2625
 2626    fn update_buffer_diagnostics(
 2627        &mut self,
 2628        buffer: &Entity<Buffer>,
 2629        server_id: LanguageServerId,
 2630        registration_id: Option<Option<SharedString>>,
 2631        result_id: Option<SharedString>,
 2632        version: Option<i32>,
 2633        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2634        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2635        cx: &mut Context<LspStore>,
 2636    ) -> Result<()> {
 2637        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2638            Ordering::Equal
 2639                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2640                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2641                .then_with(|| a.severity.cmp(&b.severity))
 2642                .then_with(|| a.message.cmp(&b.message))
 2643        }
 2644
 2645        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2646        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2647        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2648
 2649        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2650            Ordering::Equal
 2651                .then_with(|| a.range.start.cmp(&b.range.start))
 2652                .then_with(|| b.range.end.cmp(&a.range.end))
 2653                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2654        });
 2655
 2656        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2657
 2658        let edits_since_save = std::cell::LazyCell::new(|| {
 2659            let saved_version = buffer.read(cx).saved_version();
 2660            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2661        });
 2662
 2663        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2664
 2665        for (new_diagnostic, entry) in diagnostics {
 2666            let start;
 2667            let end;
 2668            if new_diagnostic && entry.diagnostic.is_disk_based {
 2669                // Some diagnostics are based on files on disk instead of buffers'
 2670                // current contents. Adjust these diagnostics' ranges to reflect
 2671                // any unsaved edits.
 2672                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2673                // and were properly adjusted on reuse.
 2674                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2675                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2676            } else {
 2677                start = entry.range.start;
 2678                end = entry.range.end;
 2679            }
 2680
 2681            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2682                ..snapshot.clip_point_utf16(end, Bias::Right);
 2683
 2684            // Expand empty ranges by one codepoint
 2685            if range.start == range.end {
 2686                // This will be go to the next boundary when being clipped
 2687                range.end.column += 1;
 2688                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2689                if range.start == range.end && range.end.column > 0 {
 2690                    range.start.column -= 1;
 2691                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2692                }
 2693            }
 2694
 2695            sanitized_diagnostics.push(DiagnosticEntry {
 2696                range,
 2697                diagnostic: entry.diagnostic,
 2698            });
 2699        }
 2700        drop(edits_since_save);
 2701
 2702        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2703        buffer.update(cx, |buffer, cx| {
 2704            if let Some(registration_id) = registration_id {
 2705                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2706                    self.buffer_pull_diagnostics_result_ids
 2707                        .entry(server_id)
 2708                        .or_default()
 2709                        .entry(registration_id)
 2710                        .or_default()
 2711                        .insert(abs_path, result_id);
 2712                }
 2713            }
 2714
 2715            buffer.update_diagnostics(server_id, set, cx)
 2716        });
 2717
 2718        Ok(())
 2719    }
 2720
 2721    fn register_language_server_for_invisible_worktree(
 2722        &mut self,
 2723        worktree: &Entity<Worktree>,
 2724        language_server_id: LanguageServerId,
 2725        cx: &mut App,
 2726    ) {
 2727        let worktree = worktree.read(cx);
 2728        let worktree_id = worktree.id();
 2729        debug_assert!(!worktree.is_visible());
 2730        let Some(mut origin_seed) = self
 2731            .language_server_ids
 2732            .iter()
 2733            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2734        else {
 2735            return;
 2736        };
 2737        origin_seed.worktree_id = worktree_id;
 2738        self.language_server_ids
 2739            .entry(origin_seed)
 2740            .or_insert_with(|| UnifiedLanguageServer {
 2741                id: language_server_id,
 2742                project_roots: Default::default(),
 2743            });
 2744    }
 2745
 2746    fn register_buffer_with_language_servers(
 2747        &mut self,
 2748        buffer_handle: &Entity<Buffer>,
 2749        only_register_servers: HashSet<LanguageServerSelector>,
 2750        cx: &mut Context<LspStore>,
 2751    ) {
 2752        let buffer = buffer_handle.read(cx);
 2753        let buffer_id = buffer.remote_id();
 2754
 2755        let Some(file) = File::from_dyn(buffer.file()) else {
 2756            return;
 2757        };
 2758        if !file.is_local() {
 2759            return;
 2760        }
 2761
 2762        let abs_path = file.abs_path(cx);
 2763        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2764            return;
 2765        };
 2766        let initial_snapshot = buffer.text_snapshot();
 2767        let worktree_id = file.worktree_id(cx);
 2768
 2769        let Some(language) = buffer.language().cloned() else {
 2770            return;
 2771        };
 2772        let path: Arc<RelPath> = file
 2773            .path()
 2774            .parent()
 2775            .map(Arc::from)
 2776            .unwrap_or_else(|| file.path().clone());
 2777        let Some(worktree) = self
 2778            .worktree_store
 2779            .read(cx)
 2780            .worktree_for_id(worktree_id, cx)
 2781        else {
 2782            return;
 2783        };
 2784        let language_name = language.name();
 2785        let (reused, delegate, servers) = self
 2786            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2787            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2788            .unwrap_or_else(|| {
 2789                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2790                let delegate: Arc<dyn ManifestDelegate> =
 2791                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2792
 2793                let servers = self
 2794                    .lsp_tree
 2795                    .walk(
 2796                        ProjectPath { worktree_id, path },
 2797                        language.name(),
 2798                        language.manifest(),
 2799                        &delegate,
 2800                        cx,
 2801                    )
 2802                    .collect::<Vec<_>>();
 2803                (false, lsp_delegate, servers)
 2804            });
 2805        let servers_and_adapters = servers
 2806            .into_iter()
 2807            .filter_map(|server_node| {
 2808                if reused && server_node.server_id().is_none() {
 2809                    return None;
 2810                }
 2811                if !only_register_servers.is_empty() {
 2812                    if let Some(server_id) = server_node.server_id()
 2813                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2814                    {
 2815                        return None;
 2816                    }
 2817                    if let Some(name) = server_node.name()
 2818                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2819                    {
 2820                        return None;
 2821                    }
 2822                }
 2823
 2824                let server_id = server_node.server_id_or_init(|disposition| {
 2825                    let path = &disposition.path;
 2826
 2827                    {
 2828                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2829
 2830                        let server_id = self.get_or_insert_language_server(
 2831                            &worktree,
 2832                            delegate.clone(),
 2833                            disposition,
 2834                            &language_name,
 2835                            cx,
 2836                        );
 2837
 2838                        if let Some(state) = self.language_servers.get(&server_id)
 2839                            && let Ok(uri) = uri
 2840                        {
 2841                            state.add_workspace_folder(uri);
 2842                        };
 2843                        server_id
 2844                    }
 2845                })?;
 2846                let server_state = self.language_servers.get(&server_id)?;
 2847                if let LanguageServerState::Running {
 2848                    server, adapter, ..
 2849                } = server_state
 2850                {
 2851                    Some((server.clone(), adapter.clone()))
 2852                } else {
 2853                    None
 2854                }
 2855            })
 2856            .collect::<Vec<_>>();
 2857        for (server, adapter) in servers_and_adapters {
 2858            buffer_handle.update(cx, |buffer, cx| {
 2859                buffer.set_completion_triggers(
 2860                    server.server_id(),
 2861                    server
 2862                        .capabilities()
 2863                        .completion_provider
 2864                        .as_ref()
 2865                        .and_then(|provider| {
 2866                            provider
 2867                                .trigger_characters
 2868                                .as_ref()
 2869                                .map(|characters| characters.iter().cloned().collect())
 2870                        })
 2871                        .unwrap_or_default(),
 2872                    cx,
 2873                );
 2874            });
 2875
 2876            let snapshot = LspBufferSnapshot {
 2877                version: 0,
 2878                snapshot: initial_snapshot.clone(),
 2879            };
 2880
 2881            let mut registered = false;
 2882            self.buffer_snapshots
 2883                .entry(buffer_id)
 2884                .or_default()
 2885                .entry(server.server_id())
 2886                .or_insert_with(|| {
 2887                    registered = true;
 2888                    server.register_buffer(
 2889                        uri.clone(),
 2890                        adapter.language_id(&language.name()),
 2891                        0,
 2892                        initial_snapshot.text(),
 2893                    );
 2894
 2895                    vec![snapshot]
 2896                });
 2897
 2898            self.buffers_opened_in_servers
 2899                .entry(buffer_id)
 2900                .or_default()
 2901                .insert(server.server_id());
 2902            if registered {
 2903                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2904                    language_server_id: server.server_id(),
 2905                    name: None,
 2906                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2907                        proto::RegisteredForBuffer {
 2908                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2909                            buffer_id: buffer_id.to_proto(),
 2910                        },
 2911                    ),
 2912                });
 2913            }
 2914        }
 2915    }
 2916
 2917    fn reuse_existing_language_server<'lang_name>(
 2918        &self,
 2919        server_tree: &LanguageServerTree,
 2920        worktree: &Entity<Worktree>,
 2921        language_name: &'lang_name LanguageName,
 2922        cx: &mut App,
 2923    ) -> Option<(
 2924        Arc<LocalLspAdapterDelegate>,
 2925        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2926    )> {
 2927        if worktree.read(cx).is_visible() {
 2928            return None;
 2929        }
 2930
 2931        let worktree_store = self.worktree_store.read(cx);
 2932        let servers = server_tree
 2933            .instances
 2934            .iter()
 2935            .filter(|(worktree_id, _)| {
 2936                worktree_store
 2937                    .worktree_for_id(**worktree_id, cx)
 2938                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2939            })
 2940            .flat_map(|(worktree_id, servers)| {
 2941                servers
 2942                    .roots
 2943                    .iter()
 2944                    .flat_map(|(_, language_servers)| language_servers)
 2945                    .map(move |(_, (server_node, server_languages))| {
 2946                        (worktree_id, server_node, server_languages)
 2947                    })
 2948                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2949                    .map(|(worktree_id, server_node, _)| {
 2950                        (
 2951                            *worktree_id,
 2952                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2953                        )
 2954                    })
 2955            })
 2956            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2957                acc.entry(worktree_id)
 2958                    .or_insert_with(Vec::new)
 2959                    .push(server_node);
 2960                acc
 2961            })
 2962            .into_values()
 2963            .max_by_key(|servers| servers.len())?;
 2964
 2965        let worktree_id = worktree.read(cx).id();
 2966        let apply = move |tree: &mut LanguageServerTree| {
 2967            for server_node in &servers {
 2968                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2969            }
 2970            servers
 2971        };
 2972
 2973        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2974        Some((delegate, apply))
 2975    }
 2976
 2977    pub(crate) fn unregister_old_buffer_from_language_servers(
 2978        &mut self,
 2979        buffer: &Entity<Buffer>,
 2980        old_file: &File,
 2981        cx: &mut App,
 2982    ) {
 2983        let old_path = match old_file.as_local() {
 2984            Some(local) => local.abs_path(cx),
 2985            None => return,
 2986        };
 2987
 2988        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2989            debug_panic!("{old_path:?} is not parseable as an URI");
 2990            return;
 2991        };
 2992        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2993    }
 2994
 2995    pub(crate) fn unregister_buffer_from_language_servers(
 2996        &mut self,
 2997        buffer: &Entity<Buffer>,
 2998        file_url: &lsp::Uri,
 2999        cx: &mut App,
 3000    ) {
 3001        buffer.update(cx, |buffer, cx| {
 3002            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 3003
 3004            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 3005                if snapshots
 3006                    .as_mut()
 3007                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 3008                {
 3009                    language_server.unregister_buffer(file_url.clone());
 3010                }
 3011            }
 3012        });
 3013    }
 3014
 3015    fn buffer_snapshot_for_lsp_version(
 3016        &mut self,
 3017        buffer: &Entity<Buffer>,
 3018        server_id: LanguageServerId,
 3019        version: Option<i32>,
 3020        cx: &App,
 3021    ) -> Result<TextBufferSnapshot> {
 3022        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 3023
 3024        if let Some(version) = version {
 3025            let buffer_id = buffer.read(cx).remote_id();
 3026            let snapshots = if let Some(snapshots) = self
 3027                .buffer_snapshots
 3028                .get_mut(&buffer_id)
 3029                .and_then(|m| m.get_mut(&server_id))
 3030            {
 3031                snapshots
 3032            } else if version == 0 {
 3033                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 3034                // We detect this case and treat it as if the version was `None`.
 3035                return Ok(buffer.read(cx).text_snapshot());
 3036            } else {
 3037                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 3038            };
 3039
 3040            let found_snapshot = snapshots
 3041                    .binary_search_by_key(&version, |e| e.version)
 3042                    .map(|ix| snapshots[ix].snapshot.clone())
 3043                    .map_err(|_| {
 3044                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 3045                    })?;
 3046
 3047            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 3048            Ok(found_snapshot)
 3049        } else {
 3050            Ok((buffer.read(cx)).text_snapshot())
 3051        }
 3052    }
 3053
 3054    async fn get_server_code_actions_from_action_kinds(
 3055        lsp_store: &WeakEntity<LspStore>,
 3056        language_server_id: LanguageServerId,
 3057        code_action_kinds: Vec<lsp::CodeActionKind>,
 3058        buffer: &Entity<Buffer>,
 3059        cx: &mut AsyncApp,
 3060    ) -> Result<Vec<CodeAction>> {
 3061        let actions = lsp_store
 3062            .update(cx, move |this, cx| {
 3063                let request = GetCodeActions {
 3064                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 3065                    kinds: Some(code_action_kinds),
 3066                };
 3067                let server = LanguageServerToQuery::Other(language_server_id);
 3068                this.request_lsp(buffer.clone(), server, request, cx)
 3069            })?
 3070            .await?;
 3071        Ok(actions)
 3072    }
 3073
 3074    pub async fn execute_code_actions_on_server(
 3075        lsp_store: &WeakEntity<LspStore>,
 3076        language_server: &Arc<LanguageServer>,
 3077        actions: Vec<CodeAction>,
 3078        push_to_history: bool,
 3079        project_transaction: &mut ProjectTransaction,
 3080        cx: &mut AsyncApp,
 3081    ) -> anyhow::Result<()> {
 3082        let request_timeout = cx.update(|app| {
 3083            ProjectSettings::get_global(app)
 3084                .global_lsp_settings
 3085                .get_request_timeout()
 3086        });
 3087
 3088        for mut action in actions {
 3089            Self::try_resolve_code_action(language_server, &mut action, request_timeout)
 3090                .await
 3091                .context("resolving a formatting code action")?;
 3092
 3093            if let Some(edit) = action.lsp_action.edit() {
 3094                if edit.changes.is_none() && edit.document_changes.is_none() {
 3095                    continue;
 3096                }
 3097
 3098                let new = Self::deserialize_workspace_edit(
 3099                    lsp_store.upgrade().context("project dropped")?,
 3100                    edit.clone(),
 3101                    push_to_history,
 3102                    language_server.clone(),
 3103                    cx,
 3104                )
 3105                .await?;
 3106                project_transaction.0.extend(new.0);
 3107            }
 3108
 3109            let Some(command) = action.lsp_action.command() else {
 3110                continue;
 3111            };
 3112
 3113            let server_capabilities = language_server.capabilities();
 3114            let available_commands = server_capabilities
 3115                .execute_command_provider
 3116                .as_ref()
 3117                .map(|options| options.commands.as_slice())
 3118                .unwrap_or_default();
 3119            if !available_commands.contains(&command.command) {
 3120                log::warn!(
 3121                    "Cannot execute a command {} not listed in the language server capabilities",
 3122                    command.command
 3123                );
 3124                continue;
 3125            }
 3126
 3127            lsp_store.update(cx, |lsp_store, _| {
 3128                if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 3129                    mode.last_workspace_edits_by_language_server
 3130                        .remove(&language_server.server_id());
 3131                }
 3132            })?;
 3133
 3134            language_server
 3135                .request::<lsp::request::ExecuteCommand>(
 3136                    lsp::ExecuteCommandParams {
 3137                        command: command.command.clone(),
 3138                        arguments: command.arguments.clone().unwrap_or_default(),
 3139                        ..Default::default()
 3140                    },
 3141                    request_timeout,
 3142                )
 3143                .await
 3144                .into_response()
 3145                .context("execute command")?;
 3146
 3147            lsp_store.update(cx, |this, _| {
 3148                if let LspStoreMode::Local(mode) = &mut this.mode {
 3149                    project_transaction.0.extend(
 3150                        mode.last_workspace_edits_by_language_server
 3151                            .remove(&language_server.server_id())
 3152                            .unwrap_or_default()
 3153                            .0,
 3154                    )
 3155                }
 3156            })?;
 3157        }
 3158        Ok(())
 3159    }
 3160
 3161    pub async fn deserialize_text_edits(
 3162        this: Entity<LspStore>,
 3163        buffer_to_edit: Entity<Buffer>,
 3164        edits: Vec<lsp::TextEdit>,
 3165        push_to_history: bool,
 3166        _: Arc<CachedLspAdapter>,
 3167        language_server: Arc<LanguageServer>,
 3168        cx: &mut AsyncApp,
 3169    ) -> Result<Option<Transaction>> {
 3170        let edits = this
 3171            .update(cx, |this, cx| {
 3172                this.as_local_mut().unwrap().edits_from_lsp(
 3173                    &buffer_to_edit,
 3174                    edits,
 3175                    language_server.server_id(),
 3176                    None,
 3177                    cx,
 3178                )
 3179            })
 3180            .await?;
 3181
 3182        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3183            buffer.finalize_last_transaction();
 3184            buffer.start_transaction();
 3185            for (range, text) in edits {
 3186                buffer.edit([(range, text)], None, cx);
 3187            }
 3188
 3189            if buffer.end_transaction(cx).is_some() {
 3190                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3191                if !push_to_history {
 3192                    buffer.forget_transaction(transaction.id);
 3193                }
 3194                Some(transaction)
 3195            } else {
 3196                None
 3197            }
 3198        });
 3199
 3200        Ok(transaction)
 3201    }
 3202
 3203    #[allow(clippy::type_complexity)]
 3204    pub fn edits_from_lsp(
 3205        &mut self,
 3206        buffer: &Entity<Buffer>,
 3207        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3208        server_id: LanguageServerId,
 3209        version: Option<i32>,
 3210        cx: &mut Context<LspStore>,
 3211    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3212        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3213        cx.background_spawn(async move {
 3214            let snapshot = snapshot?;
 3215            let mut lsp_edits = lsp_edits
 3216                .into_iter()
 3217                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3218                .collect::<Vec<_>>();
 3219
 3220            lsp_edits.sort_unstable_by_key(|(range, _)| (range.start, range.end));
 3221
 3222            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3223            let mut edits = Vec::new();
 3224            while let Some((range, mut new_text)) = lsp_edits.next() {
 3225                // Clip invalid ranges provided by the language server.
 3226                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3227                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3228
 3229                // Combine any LSP edits that are adjacent.
 3230                //
 3231                // Also, combine LSP edits that are separated from each other by only
 3232                // a newline. This is important because for some code actions,
 3233                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3234                // are separated by unchanged newline characters.
 3235                //
 3236                // In order for the diffing logic below to work properly, any edits that
 3237                // cancel each other out must be combined into one.
 3238                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3239                    if next_range.start.0 > range.end {
 3240                        if next_range.start.0.row > range.end.row + 1
 3241                            || next_range.start.0.column > 0
 3242                            || snapshot.clip_point_utf16(
 3243                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3244                                Bias::Left,
 3245                            ) > range.end
 3246                        {
 3247                            break;
 3248                        }
 3249                        new_text.push('\n');
 3250                    }
 3251                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3252                    new_text.push_str(next_text);
 3253                    lsp_edits.next();
 3254                }
 3255
 3256                // For multiline edits, perform a diff of the old and new text so that
 3257                // we can identify the changes more precisely, preserving the locations
 3258                // of any anchors positioned in the unchanged regions.
 3259                if range.end.row > range.start.row {
 3260                    let offset = range.start.to_offset(&snapshot);
 3261                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3262                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3263                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3264                        (
 3265                            snapshot.anchor_after(offset + range.start)
 3266                                ..snapshot.anchor_before(offset + range.end),
 3267                            replacement,
 3268                        )
 3269                    }));
 3270                } else if range.end == range.start {
 3271                    let anchor = snapshot.anchor_after(range.start);
 3272                    edits.push((anchor..anchor, new_text.into()));
 3273                } else {
 3274                    let edit_start = snapshot.anchor_after(range.start);
 3275                    let edit_end = snapshot.anchor_before(range.end);
 3276                    edits.push((edit_start..edit_end, new_text.into()));
 3277                }
 3278            }
 3279
 3280            Ok(edits)
 3281        })
 3282    }
 3283
 3284    pub(crate) async fn deserialize_workspace_edit(
 3285        this: Entity<LspStore>,
 3286        edit: lsp::WorkspaceEdit,
 3287        push_to_history: bool,
 3288        language_server: Arc<LanguageServer>,
 3289        cx: &mut AsyncApp,
 3290    ) -> Result<ProjectTransaction> {
 3291        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3292
 3293        let mut operations = Vec::new();
 3294        if let Some(document_changes) = edit.document_changes {
 3295            match document_changes {
 3296                lsp::DocumentChanges::Edits(edits) => {
 3297                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3298                }
 3299                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3300            }
 3301        } else if let Some(changes) = edit.changes {
 3302            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3303                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3304                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3305                        uri,
 3306                        version: None,
 3307                    },
 3308                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3309                })
 3310            }));
 3311        }
 3312
 3313        let mut project_transaction = ProjectTransaction::default();
 3314        for operation in operations {
 3315            match operation {
 3316                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3317                    let abs_path = op
 3318                        .uri
 3319                        .to_file_path()
 3320                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3321
 3322                    if let Some(parent_path) = abs_path.parent() {
 3323                        fs.create_dir(parent_path).await?;
 3324                    }
 3325                    if abs_path.ends_with("/") {
 3326                        fs.create_dir(&abs_path).await?;
 3327                    } else {
 3328                        fs.create_file(
 3329                            &abs_path,
 3330                            op.options
 3331                                .map(|options| fs::CreateOptions {
 3332                                    overwrite: options.overwrite.unwrap_or(false),
 3333                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3334                                })
 3335                                .unwrap_or_default(),
 3336                        )
 3337                        .await?;
 3338                    }
 3339                }
 3340
 3341                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3342                    let source_abs_path = op
 3343                        .old_uri
 3344                        .to_file_path()
 3345                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3346                    let target_abs_path = op
 3347                        .new_uri
 3348                        .to_file_path()
 3349                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3350
 3351                    let options = fs::RenameOptions {
 3352                        overwrite: op
 3353                            .options
 3354                            .as_ref()
 3355                            .and_then(|options| options.overwrite)
 3356                            .unwrap_or(false),
 3357                        ignore_if_exists: op
 3358                            .options
 3359                            .as_ref()
 3360                            .and_then(|options| options.ignore_if_exists)
 3361                            .unwrap_or(false),
 3362                        create_parents: true,
 3363                    };
 3364
 3365                    fs.rename(&source_abs_path, &target_abs_path, options)
 3366                        .await?;
 3367                }
 3368
 3369                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3370                    let abs_path = op
 3371                        .uri
 3372                        .to_file_path()
 3373                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3374                    let options = op
 3375                        .options
 3376                        .map(|options| fs::RemoveOptions {
 3377                            recursive: options.recursive.unwrap_or(false),
 3378                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3379                        })
 3380                        .unwrap_or_default();
 3381                    if abs_path.ends_with("/") {
 3382                        fs.remove_dir(&abs_path, options).await?;
 3383                    } else {
 3384                        fs.remove_file(&abs_path, options).await?;
 3385                    }
 3386                }
 3387
 3388                lsp::DocumentChangeOperation::Edit(op) => {
 3389                    let buffer_to_edit = this
 3390                        .update(cx, |this, cx| {
 3391                            this.open_local_buffer_via_lsp(
 3392                                op.text_document.uri.clone(),
 3393                                language_server.server_id(),
 3394                                cx,
 3395                            )
 3396                        })
 3397                        .await?;
 3398
 3399                    let edits = this
 3400                        .update(cx, |this, cx| {
 3401                            let path = buffer_to_edit.read(cx).project_path(cx);
 3402                            let active_entry = this.active_entry;
 3403                            let is_active_entry = path.is_some_and(|project_path| {
 3404                                this.worktree_store
 3405                                    .read(cx)
 3406                                    .entry_for_path(&project_path, cx)
 3407                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3408                            });
 3409                            let local = this.as_local_mut().unwrap();
 3410
 3411                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3412                            for edit in op.edits {
 3413                                match edit {
 3414                                    Edit::Plain(edit) => {
 3415                                        if !edits.contains(&edit) {
 3416                                            edits.push(edit)
 3417                                        }
 3418                                    }
 3419                                    Edit::Annotated(edit) => {
 3420                                        if !edits.contains(&edit.text_edit) {
 3421                                            edits.push(edit.text_edit)
 3422                                        }
 3423                                    }
 3424                                    Edit::Snippet(edit) => {
 3425                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3426                                        else {
 3427                                            continue;
 3428                                        };
 3429
 3430                                        if is_active_entry {
 3431                                            snippet_edits.push((edit.range, snippet));
 3432                                        } else {
 3433                                            // Since this buffer is not focused, apply a normal edit.
 3434                                            let new_edit = TextEdit {
 3435                                                range: edit.range,
 3436                                                new_text: snippet.text,
 3437                                            };
 3438                                            if !edits.contains(&new_edit) {
 3439                                                edits.push(new_edit);
 3440                                            }
 3441                                        }
 3442                                    }
 3443                                }
 3444                            }
 3445                            if !snippet_edits.is_empty() {
 3446                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3447                                let version = if let Some(buffer_version) = op.text_document.version
 3448                                {
 3449                                    local
 3450                                        .buffer_snapshot_for_lsp_version(
 3451                                            &buffer_to_edit,
 3452                                            language_server.server_id(),
 3453                                            Some(buffer_version),
 3454                                            cx,
 3455                                        )
 3456                                        .ok()
 3457                                        .map(|snapshot| snapshot.version)
 3458                                } else {
 3459                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3460                                };
 3461
 3462                                let most_recent_edit =
 3463                                    version.and_then(|version| version.most_recent());
 3464                                // Check if the edit that triggered that edit has been made by this participant.
 3465
 3466                                if let Some(most_recent_edit) = most_recent_edit {
 3467                                    cx.emit(LspStoreEvent::SnippetEdit {
 3468                                        buffer_id,
 3469                                        edits: snippet_edits,
 3470                                        most_recent_edit,
 3471                                    });
 3472                                }
 3473                            }
 3474
 3475                            local.edits_from_lsp(
 3476                                &buffer_to_edit,
 3477                                edits,
 3478                                language_server.server_id(),
 3479                                op.text_document.version,
 3480                                cx,
 3481                            )
 3482                        })
 3483                        .await?;
 3484
 3485                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3486                        buffer.finalize_last_transaction();
 3487                        buffer.start_transaction();
 3488                        for (range, text) in edits {
 3489                            buffer.edit([(range, text)], None, cx);
 3490                        }
 3491
 3492                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3493                            if push_to_history {
 3494                                buffer.finalize_last_transaction();
 3495                                buffer.get_transaction(transaction_id).cloned()
 3496                            } else {
 3497                                buffer.forget_transaction(transaction_id)
 3498                            }
 3499                        })
 3500                    });
 3501                    if let Some(transaction) = transaction {
 3502                        project_transaction.0.insert(buffer_to_edit, transaction);
 3503                    }
 3504                }
 3505            }
 3506        }
 3507
 3508        Ok(project_transaction)
 3509    }
 3510
 3511    async fn on_lsp_workspace_edit(
 3512        this: WeakEntity<LspStore>,
 3513        params: lsp::ApplyWorkspaceEditParams,
 3514        server_id: LanguageServerId,
 3515        cx: &mut AsyncApp,
 3516    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3517        let this = this.upgrade().context("project project closed")?;
 3518        let language_server = this
 3519            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3520            .context("language server not found")?;
 3521        let transaction = Self::deserialize_workspace_edit(
 3522            this.clone(),
 3523            params.edit,
 3524            true,
 3525            language_server.clone(),
 3526            cx,
 3527        )
 3528        .await
 3529        .log_err();
 3530        this.update(cx, |this, cx| {
 3531            if let Some(transaction) = transaction {
 3532                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3533
 3534                this.as_local_mut()
 3535                    .unwrap()
 3536                    .last_workspace_edits_by_language_server
 3537                    .insert(server_id, transaction);
 3538            }
 3539        });
 3540        Ok(lsp::ApplyWorkspaceEditResponse {
 3541            applied: true,
 3542            failed_change: None,
 3543            failure_reason: None,
 3544        })
 3545    }
 3546
 3547    fn remove_worktree(
 3548        &mut self,
 3549        id_to_remove: WorktreeId,
 3550        cx: &mut Context<LspStore>,
 3551    ) -> Vec<LanguageServerId> {
 3552        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3553        self.diagnostics.remove(&id_to_remove);
 3554        self.prettier_store.update(cx, |prettier_store, cx| {
 3555            prettier_store.remove_worktree(id_to_remove, cx);
 3556        });
 3557
 3558        let mut servers_to_remove = BTreeSet::default();
 3559        let mut servers_to_preserve = HashSet::default();
 3560        for (seed, state) in &self.language_server_ids {
 3561            if seed.worktree_id == id_to_remove {
 3562                servers_to_remove.insert(state.id);
 3563            } else {
 3564                servers_to_preserve.insert(state.id);
 3565            }
 3566        }
 3567        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3568        self.language_server_ids
 3569            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3570        for server_id_to_remove in &servers_to_remove {
 3571            self.language_server_watched_paths
 3572                .remove(server_id_to_remove);
 3573            self.language_server_paths_watched_for_rename
 3574                .remove(server_id_to_remove);
 3575            self.last_workspace_edits_by_language_server
 3576                .remove(server_id_to_remove);
 3577            self.language_servers.remove(server_id_to_remove);
 3578            self.buffer_pull_diagnostics_result_ids
 3579                .remove(server_id_to_remove);
 3580            self.workspace_pull_diagnostics_result_ids
 3581                .remove(server_id_to_remove);
 3582            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3583                buffer_servers.remove(server_id_to_remove);
 3584            }
 3585            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3586        }
 3587        servers_to_remove.into_iter().collect()
 3588    }
 3589
 3590    fn rebuild_watched_paths_inner<'a>(
 3591        &'a self,
 3592        language_server_id: LanguageServerId,
 3593        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3594        cx: &mut Context<LspStore>,
 3595    ) -> LanguageServerWatchedPathsBuilder {
 3596        let worktrees = self
 3597            .worktree_store
 3598            .read(cx)
 3599            .worktrees()
 3600            .filter_map(|worktree| {
 3601                self.language_servers_for_worktree(worktree.read(cx).id())
 3602                    .find(|server| server.server_id() == language_server_id)
 3603                    .map(|_| worktree)
 3604            })
 3605            .collect::<Vec<_>>();
 3606
 3607        let mut worktree_globs = HashMap::default();
 3608        let mut abs_globs = HashMap::default();
 3609        log::trace!(
 3610            "Processing new watcher paths for language server with id {}",
 3611            language_server_id
 3612        );
 3613
 3614        for watcher in watchers {
 3615            if let Some((worktree, literal_prefix, pattern)) =
 3616                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3617            {
 3618                worktree.update(cx, |worktree, _| {
 3619                    if let Some((tree, glob)) =
 3620                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3621                    {
 3622                        tree.add_path_prefix_to_scan(literal_prefix);
 3623                        worktree_globs
 3624                            .entry(tree.id())
 3625                            .or_insert_with(GlobSetBuilder::new)
 3626                            .add(glob);
 3627                    }
 3628                });
 3629            } else {
 3630                let (path, pattern) = match &watcher.glob_pattern {
 3631                    lsp::GlobPattern::String(s) => {
 3632                        let watcher_path = SanitizedPath::new(s);
 3633                        let path = glob_literal_prefix(watcher_path.as_path());
 3634                        let pattern = watcher_path
 3635                            .as_path()
 3636                            .strip_prefix(&path)
 3637                            .map(|p| p.to_string_lossy().into_owned())
 3638                            .unwrap_or_else(|e| {
 3639                                debug_panic!(
 3640                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3641                                    s,
 3642                                    path.display(),
 3643                                    e
 3644                                );
 3645                                watcher_path.as_path().to_string_lossy().into_owned()
 3646                            });
 3647                        (path, pattern)
 3648                    }
 3649                    lsp::GlobPattern::Relative(rp) => {
 3650                        let Ok(mut base_uri) = match &rp.base_uri {
 3651                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3652                            lsp::OneOf::Right(base_uri) => base_uri,
 3653                        }
 3654                        .to_file_path() else {
 3655                            continue;
 3656                        };
 3657
 3658                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3659                        let pattern = Path::new(&rp.pattern)
 3660                            .strip_prefix(&path)
 3661                            .map(|p| p.to_string_lossy().into_owned())
 3662                            .unwrap_or_else(|e| {
 3663                                debug_panic!(
 3664                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3665                                    rp.pattern,
 3666                                    path.display(),
 3667                                    e
 3668                                );
 3669                                rp.pattern.clone()
 3670                            });
 3671                        base_uri.push(path);
 3672                        (base_uri, pattern)
 3673                    }
 3674                };
 3675
 3676                if let Some(glob) = Glob::new(&pattern).log_err() {
 3677                    if !path
 3678                        .components()
 3679                        .any(|c| matches!(c, path::Component::Normal(_)))
 3680                    {
 3681                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3682                        // rather than adding a new watcher for `/`.
 3683                        for worktree in &worktrees {
 3684                            worktree_globs
 3685                                .entry(worktree.read(cx).id())
 3686                                .or_insert_with(GlobSetBuilder::new)
 3687                                .add(glob.clone());
 3688                        }
 3689                    } else {
 3690                        abs_globs
 3691                            .entry(path.into())
 3692                            .or_insert_with(GlobSetBuilder::new)
 3693                            .add(glob);
 3694                    }
 3695                }
 3696            }
 3697        }
 3698
 3699        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3700        for (worktree_id, builder) in worktree_globs {
 3701            if let Ok(globset) = builder.build() {
 3702                watch_builder.watch_worktree(worktree_id, globset);
 3703            }
 3704        }
 3705        for (abs_path, builder) in abs_globs {
 3706            if let Ok(globset) = builder.build() {
 3707                watch_builder.watch_abs_path(abs_path, globset);
 3708            }
 3709        }
 3710        watch_builder
 3711    }
 3712
 3713    fn worktree_and_path_for_file_watcher(
 3714        worktrees: &[Entity<Worktree>],
 3715        watcher: &FileSystemWatcher,
 3716        cx: &App,
 3717    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3718        worktrees.iter().find_map(|worktree| {
 3719            let tree = worktree.read(cx);
 3720            let worktree_root_path = tree.abs_path();
 3721            let path_style = tree.path_style();
 3722            match &watcher.glob_pattern {
 3723                lsp::GlobPattern::String(s) => {
 3724                    let watcher_path = SanitizedPath::new(s);
 3725                    let relative = watcher_path
 3726                        .as_path()
 3727                        .strip_prefix(&worktree_root_path)
 3728                        .ok()?;
 3729                    let literal_prefix = glob_literal_prefix(relative);
 3730                    Some((
 3731                        worktree.clone(),
 3732                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3733                        relative.to_string_lossy().into_owned(),
 3734                    ))
 3735                }
 3736                lsp::GlobPattern::Relative(rp) => {
 3737                    let base_uri = match &rp.base_uri {
 3738                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3739                        lsp::OneOf::Right(base_uri) => base_uri,
 3740                    }
 3741                    .to_file_path()
 3742                    .ok()?;
 3743                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3744                    let mut literal_prefix = relative.to_owned();
 3745                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3746                    Some((
 3747                        worktree.clone(),
 3748                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3749                        rp.pattern.clone(),
 3750                    ))
 3751                }
 3752            }
 3753        })
 3754    }
 3755
 3756    fn rebuild_watched_paths(
 3757        &mut self,
 3758        language_server_id: LanguageServerId,
 3759        cx: &mut Context<LspStore>,
 3760    ) {
 3761        let Some(registrations) = self
 3762            .language_server_dynamic_registrations
 3763            .get(&language_server_id)
 3764        else {
 3765            return;
 3766        };
 3767
 3768        let watch_builder = self.rebuild_watched_paths_inner(
 3769            language_server_id,
 3770            registrations.did_change_watched_files.values().flatten(),
 3771            cx,
 3772        );
 3773        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3774        self.language_server_watched_paths
 3775            .insert(language_server_id, watcher);
 3776
 3777        cx.notify();
 3778    }
 3779
 3780    fn on_lsp_did_change_watched_files(
 3781        &mut self,
 3782        language_server_id: LanguageServerId,
 3783        registration_id: &str,
 3784        params: DidChangeWatchedFilesRegistrationOptions,
 3785        cx: &mut Context<LspStore>,
 3786    ) {
 3787        let registrations = self
 3788            .language_server_dynamic_registrations
 3789            .entry(language_server_id)
 3790            .or_default();
 3791
 3792        registrations
 3793            .did_change_watched_files
 3794            .insert(registration_id.to_string(), params.watchers);
 3795
 3796        self.rebuild_watched_paths(language_server_id, cx);
 3797    }
 3798
 3799    fn on_lsp_unregister_did_change_watched_files(
 3800        &mut self,
 3801        language_server_id: LanguageServerId,
 3802        registration_id: &str,
 3803        cx: &mut Context<LspStore>,
 3804    ) {
 3805        let registrations = self
 3806            .language_server_dynamic_registrations
 3807            .entry(language_server_id)
 3808            .or_default();
 3809
 3810        if registrations
 3811            .did_change_watched_files
 3812            .remove(registration_id)
 3813            .is_some()
 3814        {
 3815            log::info!(
 3816                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3817                language_server_id,
 3818                registration_id
 3819            );
 3820        } else {
 3821            log::warn!(
 3822                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3823                language_server_id,
 3824                registration_id
 3825            );
 3826        }
 3827
 3828        self.rebuild_watched_paths(language_server_id, cx);
 3829    }
 3830
 3831    async fn initialization_options_for_adapter(
 3832        adapter: Arc<dyn LspAdapter>,
 3833        delegate: &Arc<dyn LspAdapterDelegate>,
 3834        cx: &mut AsyncApp,
 3835    ) -> Result<Option<serde_json::Value>> {
 3836        let Some(mut initialization_config) =
 3837            adapter.clone().initialization_options(delegate, cx).await?
 3838        else {
 3839            return Ok(None);
 3840        };
 3841
 3842        for other_adapter in delegate.registered_lsp_adapters() {
 3843            if other_adapter.name() == adapter.name() {
 3844                continue;
 3845            }
 3846            if let Ok(Some(target_config)) = other_adapter
 3847                .clone()
 3848                .additional_initialization_options(adapter.name(), delegate)
 3849                .await
 3850            {
 3851                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3852            }
 3853        }
 3854
 3855        Ok(Some(initialization_config))
 3856    }
 3857
 3858    async fn workspace_configuration_for_adapter(
 3859        adapter: Arc<dyn LspAdapter>,
 3860        delegate: &Arc<dyn LspAdapterDelegate>,
 3861        toolchain: Option<Toolchain>,
 3862        requested_uri: Option<Uri>,
 3863        cx: &mut AsyncApp,
 3864    ) -> Result<serde_json::Value> {
 3865        let mut workspace_config = adapter
 3866            .clone()
 3867            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3868            .await?;
 3869
 3870        for other_adapter in delegate.registered_lsp_adapters() {
 3871            if other_adapter.name() == adapter.name() {
 3872                continue;
 3873            }
 3874            if let Ok(Some(target_config)) = other_adapter
 3875                .clone()
 3876                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3877                .await
 3878            {
 3879                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3880            }
 3881        }
 3882
 3883        Ok(workspace_config)
 3884    }
 3885
 3886    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3887        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3888            Some(server.clone())
 3889        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3890            Some(Arc::clone(server))
 3891        } else {
 3892            None
 3893        }
 3894    }
 3895}
 3896
 3897fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3898    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3899        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3900            language_server_id: server.server_id(),
 3901            name: Some(server.name()),
 3902            message: proto::update_language_server::Variant::MetadataUpdated(
 3903                proto::ServerMetadataUpdated {
 3904                    capabilities: Some(capabilities),
 3905                    binary: Some(proto::LanguageServerBinaryInfo {
 3906                        path: server.binary().path.to_string_lossy().into_owned(),
 3907                        arguments: server
 3908                            .binary()
 3909                            .arguments
 3910                            .iter()
 3911                            .map(|arg| arg.to_string_lossy().into_owned())
 3912                            .collect(),
 3913                    }),
 3914                    configuration: serde_json::to_string(server.configuration()).ok(),
 3915                    workspace_folders: server
 3916                        .workspace_folders()
 3917                        .iter()
 3918                        .map(|uri| uri.to_string())
 3919                        .collect(),
 3920                },
 3921            ),
 3922        });
 3923    }
 3924}
 3925
 3926#[derive(Debug)]
 3927pub struct FormattableBuffer {
 3928    handle: Entity<Buffer>,
 3929    abs_path: Option<PathBuf>,
 3930    env: Option<HashMap<String, String>>,
 3931    ranges: Option<Vec<Range<Anchor>>>,
 3932}
 3933
 3934pub struct RemoteLspStore {
 3935    upstream_client: Option<AnyProtoClient>,
 3936    upstream_project_id: u64,
 3937}
 3938
 3939pub(crate) enum LspStoreMode {
 3940    Local(LocalLspStore),   // ssh host and collab host
 3941    Remote(RemoteLspStore), // collab guest
 3942}
 3943
 3944impl LspStoreMode {
 3945    fn is_local(&self) -> bool {
 3946        matches!(self, LspStoreMode::Local(_))
 3947    }
 3948}
 3949
 3950pub struct LspStore {
 3951    mode: LspStoreMode,
 3952    last_formatting_failure: Option<String>,
 3953    downstream_client: Option<(AnyProtoClient, u64)>,
 3954    nonce: u128,
 3955    buffer_store: Entity<BufferStore>,
 3956    worktree_store: Entity<WorktreeStore>,
 3957    pub languages: Arc<LanguageRegistry>,
 3958    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3959    active_entry: Option<ProjectEntryId>,
 3960    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3961    _maintain_buffer_languages: Task<()>,
 3962    diagnostic_summaries:
 3963        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3964    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3965    semantic_token_config: SemanticTokenConfig,
 3966    lsp_data: HashMap<BufferId, BufferLspData>,
 3967    buffer_reload_tasks: HashMap<BufferId, Task<anyhow::Result<()>>>,
 3968    next_hint_id: Arc<AtomicUsize>,
 3969}
 3970
 3971#[derive(Debug)]
 3972pub struct BufferLspData {
 3973    buffer_version: Global,
 3974    document_colors: Option<DocumentColorData>,
 3975    code_lens: Option<CodeLensData>,
 3976    semantic_tokens: Option<SemanticTokensData>,
 3977    folding_ranges: Option<FoldingRangeData>,
 3978    document_symbols: Option<DocumentSymbolsData>,
 3979    inlay_hints: BufferInlayHints,
 3980    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3981    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3982}
 3983
 3984#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3985struct LspKey {
 3986    request_type: TypeId,
 3987    server_queried: Option<LanguageServerId>,
 3988}
 3989
 3990impl BufferLspData {
 3991    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3992        Self {
 3993            buffer_version: buffer.read(cx).version(),
 3994            document_colors: None,
 3995            code_lens: None,
 3996            semantic_tokens: None,
 3997            folding_ranges: None,
 3998            document_symbols: None,
 3999            inlay_hints: BufferInlayHints::new(buffer, cx),
 4000            lsp_requests: HashMap::default(),
 4001            chunk_lsp_requests: HashMap::default(),
 4002        }
 4003    }
 4004
 4005    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 4006        if let Some(document_colors) = &mut self.document_colors {
 4007            document_colors.remove_server_data(for_server);
 4008        }
 4009
 4010        if let Some(code_lens) = &mut self.code_lens {
 4011            code_lens.remove_server_data(for_server);
 4012        }
 4013
 4014        self.inlay_hints.remove_server_data(for_server);
 4015
 4016        if let Some(semantic_tokens) = &mut self.semantic_tokens {
 4017            semantic_tokens.remove_server_data(for_server);
 4018        }
 4019
 4020        if let Some(folding_ranges) = &mut self.folding_ranges {
 4021            folding_ranges.ranges.remove(&for_server);
 4022        }
 4023
 4024        if let Some(document_symbols) = &mut self.document_symbols {
 4025            document_symbols.remove_server_data(for_server);
 4026        }
 4027    }
 4028
 4029    #[cfg(any(test, feature = "test-support"))]
 4030    pub fn inlay_hints(&self) -> &BufferInlayHints {
 4031        &self.inlay_hints
 4032    }
 4033}
 4034
 4035#[derive(Debug)]
 4036pub enum LspStoreEvent {
 4037    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 4038    LanguageServerRemoved(LanguageServerId),
 4039    LanguageServerUpdate {
 4040        language_server_id: LanguageServerId,
 4041        name: Option<LanguageServerName>,
 4042        message: proto::update_language_server::Variant,
 4043    },
 4044    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 4045    LanguageServerPrompt(LanguageServerPromptRequest),
 4046    LanguageDetected {
 4047        buffer: Entity<Buffer>,
 4048        new_language: Option<Arc<Language>>,
 4049    },
 4050    Notification(String),
 4051    RefreshInlayHints {
 4052        server_id: LanguageServerId,
 4053        request_id: Option<usize>,
 4054    },
 4055    RefreshSemanticTokens {
 4056        server_id: LanguageServerId,
 4057        request_id: Option<usize>,
 4058    },
 4059    RefreshCodeLens,
 4060    DiagnosticsUpdated {
 4061        server_id: LanguageServerId,
 4062        paths: Vec<ProjectPath>,
 4063    },
 4064    DiskBasedDiagnosticsStarted {
 4065        language_server_id: LanguageServerId,
 4066    },
 4067    DiskBasedDiagnosticsFinished {
 4068        language_server_id: LanguageServerId,
 4069    },
 4070    SnippetEdit {
 4071        buffer_id: BufferId,
 4072        edits: Vec<(lsp::Range, Snippet)>,
 4073        most_recent_edit: clock::Lamport,
 4074    },
 4075    WorkspaceEditApplied(ProjectTransaction),
 4076}
 4077
 4078#[derive(Clone, Debug, Serialize)]
 4079pub struct LanguageServerStatus {
 4080    pub name: LanguageServerName,
 4081    pub server_version: Option<SharedString>,
 4082    pub server_readable_version: Option<SharedString>,
 4083    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 4084    pub has_pending_diagnostic_updates: bool,
 4085    pub progress_tokens: HashSet<ProgressToken>,
 4086    pub worktree: Option<WorktreeId>,
 4087    pub binary: Option<LanguageServerBinary>,
 4088    pub configuration: Option<Value>,
 4089    pub workspace_folders: BTreeSet<Uri>,
 4090    pub process_id: Option<u32>,
 4091}
 4092
 4093#[derive(Clone, Debug)]
 4094struct CoreSymbol {
 4095    pub language_server_name: LanguageServerName,
 4096    pub source_worktree_id: WorktreeId,
 4097    pub source_language_server_id: LanguageServerId,
 4098    pub path: SymbolLocation,
 4099    pub name: String,
 4100    pub kind: lsp::SymbolKind,
 4101    pub range: Range<Unclipped<PointUtf16>>,
 4102    pub container_name: Option<String>,
 4103}
 4104
 4105#[derive(Clone, Debug, PartialEq, Eq)]
 4106pub enum SymbolLocation {
 4107    InProject(ProjectPath),
 4108    OutsideProject {
 4109        abs_path: Arc<Path>,
 4110        signature: [u8; 32],
 4111    },
 4112}
 4113
 4114impl SymbolLocation {
 4115    fn file_name(&self) -> Option<&str> {
 4116        match self {
 4117            Self::InProject(path) => path.path.file_name(),
 4118            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 4119        }
 4120    }
 4121}
 4122
 4123impl LspStore {
 4124    pub fn init(client: &AnyProtoClient) {
 4125        client.add_entity_request_handler(Self::handle_lsp_query);
 4126        client.add_entity_message_handler(Self::handle_lsp_query_response);
 4127        client.add_entity_request_handler(Self::handle_restart_language_servers);
 4128        client.add_entity_request_handler(Self::handle_stop_language_servers);
 4129        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 4130        client.add_entity_message_handler(Self::handle_start_language_server);
 4131        client.add_entity_message_handler(Self::handle_update_language_server);
 4132        client.add_entity_message_handler(Self::handle_language_server_log);
 4133        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 4134        client.add_entity_request_handler(Self::handle_format_buffers);
 4135        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 4136        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 4137        client.add_entity_request_handler(Self::handle_apply_code_action);
 4138        client.add_entity_request_handler(Self::handle_get_project_symbols);
 4139        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 4140        client.add_entity_request_handler(Self::handle_get_color_presentation);
 4141        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 4142        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 4143        client.add_entity_request_handler(Self::handle_refresh_semantic_tokens);
 4144        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 4145        client.add_entity_request_handler(Self::handle_on_type_formatting);
 4146        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 4147        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 4148        client.add_entity_request_handler(Self::handle_rename_project_entry);
 4149        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 4150        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 4151        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 4152        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 4153        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 4154        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 4155        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 4156
 4157        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 4158        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 4159        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 4160        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 4161        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 4162        client.add_entity_request_handler(
 4163            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 4164        );
 4165        client.add_entity_request_handler(
 4166            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 4167        );
 4168        client.add_entity_request_handler(
 4169            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 4170        );
 4171    }
 4172
 4173    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 4174        match &self.mode {
 4175            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 4176            _ => None,
 4177        }
 4178    }
 4179
 4180    pub fn as_local(&self) -> Option<&LocalLspStore> {
 4181        match &self.mode {
 4182            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4183            _ => None,
 4184        }
 4185    }
 4186
 4187    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4188        match &mut self.mode {
 4189            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4190            _ => None,
 4191        }
 4192    }
 4193
 4194    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4195        match &self.mode {
 4196            LspStoreMode::Remote(RemoteLspStore {
 4197                upstream_client: Some(upstream_client),
 4198                upstream_project_id,
 4199                ..
 4200            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4201
 4202            LspStoreMode::Remote(RemoteLspStore {
 4203                upstream_client: None,
 4204                ..
 4205            }) => None,
 4206            LspStoreMode::Local(_) => None,
 4207        }
 4208    }
 4209
 4210    pub fn new_local(
 4211        buffer_store: Entity<BufferStore>,
 4212        worktree_store: Entity<WorktreeStore>,
 4213        prettier_store: Entity<PrettierStore>,
 4214        toolchain_store: Entity<LocalToolchainStore>,
 4215        environment: Entity<ProjectEnvironment>,
 4216        manifest_tree: Entity<ManifestTree>,
 4217        languages: Arc<LanguageRegistry>,
 4218        http_client: Arc<dyn HttpClient>,
 4219        fs: Arc<dyn Fs>,
 4220        cx: &mut Context<Self>,
 4221    ) -> Self {
 4222        let yarn = YarnPathStore::new(fs.clone(), cx);
 4223        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4224            .detach();
 4225        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4226            .detach();
 4227        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4228            .detach();
 4229        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4230            .detach();
 4231        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4232            .detach();
 4233        subscribe_to_binary_statuses(&languages, cx).detach();
 4234
 4235        let _maintain_workspace_config = {
 4236            let (sender, receiver) = watch::channel();
 4237            (Self::maintain_workspace_config(receiver, cx), sender)
 4238        };
 4239
 4240        Self {
 4241            mode: LspStoreMode::Local(LocalLspStore {
 4242                weak: cx.weak_entity(),
 4243                worktree_store: worktree_store.clone(),
 4244
 4245                supplementary_language_servers: Default::default(),
 4246                languages: languages.clone(),
 4247                language_server_ids: Default::default(),
 4248                language_servers: Default::default(),
 4249                last_workspace_edits_by_language_server: Default::default(),
 4250                language_server_watched_paths: Default::default(),
 4251                language_server_paths_watched_for_rename: Default::default(),
 4252                language_server_dynamic_registrations: Default::default(),
 4253                buffers_being_formatted: Default::default(),
 4254                buffers_to_refresh_hash_set: HashSet::default(),
 4255                buffers_to_refresh_queue: VecDeque::new(),
 4256                _background_diagnostics_worker: Task::ready(()).shared(),
 4257                buffer_snapshots: Default::default(),
 4258                prettier_store,
 4259                environment,
 4260                http_client,
 4261                fs,
 4262                yarn,
 4263                next_diagnostic_group_id: Default::default(),
 4264                diagnostics: Default::default(),
 4265                _subscription: cx.on_app_quit(|this, _| {
 4266                    this.as_local_mut()
 4267                        .unwrap()
 4268                        .shutdown_language_servers_on_quit()
 4269                }),
 4270                lsp_tree: LanguageServerTree::new(
 4271                    manifest_tree,
 4272                    languages.clone(),
 4273                    toolchain_store.clone(),
 4274                ),
 4275                toolchain_store,
 4276                registered_buffers: HashMap::default(),
 4277                buffers_opened_in_servers: HashMap::default(),
 4278                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4279                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4280                restricted_worktrees_tasks: HashMap::default(),
 4281                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4282                    .manifest_file_names(),
 4283            }),
 4284            last_formatting_failure: None,
 4285            downstream_client: None,
 4286            buffer_store,
 4287            worktree_store,
 4288            languages: languages.clone(),
 4289            language_server_statuses: Default::default(),
 4290            nonce: StdRng::from_os_rng().random(),
 4291            diagnostic_summaries: HashMap::default(),
 4292            lsp_server_capabilities: HashMap::default(),
 4293            semantic_token_config: SemanticTokenConfig::new(cx),
 4294            lsp_data: HashMap::default(),
 4295            buffer_reload_tasks: HashMap::default(),
 4296            next_hint_id: Arc::default(),
 4297            active_entry: None,
 4298            _maintain_workspace_config,
 4299            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4300        }
 4301    }
 4302
 4303    fn send_lsp_proto_request<R: LspCommand>(
 4304        &self,
 4305        buffer: Entity<Buffer>,
 4306        client: AnyProtoClient,
 4307        upstream_project_id: u64,
 4308        request: R,
 4309        cx: &mut Context<LspStore>,
 4310    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4311        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4312            return Task::ready(Ok(R::Response::default()));
 4313        }
 4314        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4315        cx.spawn(async move |this, cx| {
 4316            let response = client.request(message).await?;
 4317            let this = this.upgrade().context("project dropped")?;
 4318            request
 4319                .response_from_proto(response, this, buffer, cx.clone())
 4320                .await
 4321        })
 4322    }
 4323
 4324    pub(super) fn new_remote(
 4325        buffer_store: Entity<BufferStore>,
 4326        worktree_store: Entity<WorktreeStore>,
 4327        languages: Arc<LanguageRegistry>,
 4328        upstream_client: AnyProtoClient,
 4329        project_id: u64,
 4330        cx: &mut Context<Self>,
 4331    ) -> Self {
 4332        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4333            .detach();
 4334        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4335            .detach();
 4336        subscribe_to_binary_statuses(&languages, cx).detach();
 4337        let _maintain_workspace_config = {
 4338            let (sender, receiver) = watch::channel();
 4339            (Self::maintain_workspace_config(receiver, cx), sender)
 4340        };
 4341        Self {
 4342            mode: LspStoreMode::Remote(RemoteLspStore {
 4343                upstream_client: Some(upstream_client),
 4344                upstream_project_id: project_id,
 4345            }),
 4346            downstream_client: None,
 4347            last_formatting_failure: None,
 4348            buffer_store,
 4349            worktree_store,
 4350            languages: languages.clone(),
 4351            language_server_statuses: Default::default(),
 4352            nonce: StdRng::from_os_rng().random(),
 4353            diagnostic_summaries: HashMap::default(),
 4354            lsp_server_capabilities: HashMap::default(),
 4355            semantic_token_config: SemanticTokenConfig::new(cx),
 4356            next_hint_id: Arc::default(),
 4357            lsp_data: HashMap::default(),
 4358            buffer_reload_tasks: HashMap::default(),
 4359            active_entry: None,
 4360
 4361            _maintain_workspace_config,
 4362            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4363        }
 4364    }
 4365
 4366    fn on_buffer_store_event(
 4367        &mut self,
 4368        _: Entity<BufferStore>,
 4369        event: &BufferStoreEvent,
 4370        cx: &mut Context<Self>,
 4371    ) {
 4372        match event {
 4373            BufferStoreEvent::BufferAdded(buffer) => {
 4374                self.on_buffer_added(buffer, cx).log_err();
 4375            }
 4376            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4377                let buffer_id = buffer.read(cx).remote_id();
 4378                if let Some(local) = self.as_local_mut()
 4379                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4380                {
 4381                    local.reset_buffer(buffer, old_file, cx);
 4382
 4383                    if local.registered_buffers.contains_key(&buffer_id) {
 4384                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4385                    }
 4386                }
 4387
 4388                self.detect_language_for_buffer(buffer, cx);
 4389                if let Some(local) = self.as_local_mut() {
 4390                    local.initialize_buffer(buffer, cx);
 4391                    if local.registered_buffers.contains_key(&buffer_id) {
 4392                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4393                    }
 4394                }
 4395            }
 4396            _ => {}
 4397        }
 4398    }
 4399
 4400    fn on_worktree_store_event(
 4401        &mut self,
 4402        _: Entity<WorktreeStore>,
 4403        event: &WorktreeStoreEvent,
 4404        cx: &mut Context<Self>,
 4405    ) {
 4406        match event {
 4407            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4408                if !worktree.read(cx).is_local() {
 4409                    return;
 4410                }
 4411                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4412                    worktree::Event::UpdatedEntries(changes) => {
 4413                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4414                    }
 4415                    worktree::Event::UpdatedGitRepositories(_)
 4416                    | worktree::Event::DeletedEntry(_)
 4417                    | worktree::Event::Deleted
 4418                    | worktree::Event::UpdatedRootRepoCommonDir { .. } => {}
 4419                })
 4420                .detach()
 4421            }
 4422            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4423            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4424                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4425            }
 4426            WorktreeStoreEvent::WorktreeUpdatedEntries(worktree_id, changes) => {
 4427                self.invalidate_diagnostic_summaries_for_removed_entries(*worktree_id, changes, cx);
 4428            }
 4429            WorktreeStoreEvent::WorktreeReleased(..)
 4430            | WorktreeStoreEvent::WorktreeOrderChanged
 4431            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4432            | WorktreeStoreEvent::WorktreeDeletedEntry(..)
 4433            | WorktreeStoreEvent::WorktreeUpdatedRootRepoCommonDir(..) => {}
 4434        }
 4435    }
 4436
 4437    fn on_prettier_store_event(
 4438        &mut self,
 4439        _: Entity<PrettierStore>,
 4440        event: &PrettierStoreEvent,
 4441        cx: &mut Context<Self>,
 4442    ) {
 4443        match event {
 4444            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4445                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4446            }
 4447            PrettierStoreEvent::LanguageServerAdded {
 4448                new_server_id,
 4449                name,
 4450                prettier_server,
 4451            } => {
 4452                self.register_supplementary_language_server(
 4453                    *new_server_id,
 4454                    name.clone(),
 4455                    prettier_server.clone(),
 4456                    cx,
 4457                );
 4458            }
 4459        }
 4460    }
 4461
 4462    fn on_toolchain_store_event(
 4463        &mut self,
 4464        _: Entity<LocalToolchainStore>,
 4465        event: &ToolchainStoreEvent,
 4466        _: &mut Context<Self>,
 4467    ) {
 4468        if let ToolchainStoreEvent::ToolchainActivated = event {
 4469            self.request_workspace_config_refresh()
 4470        }
 4471    }
 4472
 4473    fn request_workspace_config_refresh(&mut self) {
 4474        *self._maintain_workspace_config.1.borrow_mut() = ();
 4475    }
 4476
 4477    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4478        self.as_local().map(|local| local.prettier_store.clone())
 4479    }
 4480
 4481    fn on_buffer_event(
 4482        &mut self,
 4483        buffer: Entity<Buffer>,
 4484        event: &language::BufferEvent,
 4485        cx: &mut Context<Self>,
 4486    ) {
 4487        match event {
 4488            language::BufferEvent::Edited { .. } => {
 4489                self.on_buffer_edited(buffer, cx);
 4490            }
 4491
 4492            language::BufferEvent::Saved => {
 4493                self.on_buffer_saved(buffer, cx);
 4494            }
 4495
 4496            language::BufferEvent::Reloaded => {
 4497                self.on_buffer_reloaded(buffer, cx);
 4498            }
 4499
 4500            _ => {}
 4501        }
 4502    }
 4503
 4504    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4505        buffer
 4506            .read(cx)
 4507            .set_language_registry(self.languages.clone());
 4508
 4509        cx.subscribe(buffer, |this, buffer, event, cx| {
 4510            this.on_buffer_event(buffer, event, cx);
 4511        })
 4512        .detach();
 4513
 4514        self.parse_modeline(buffer, cx);
 4515        self.detect_language_for_buffer(buffer, cx);
 4516        if let Some(local) = self.as_local_mut() {
 4517            local.initialize_buffer(buffer, cx);
 4518        }
 4519
 4520        Ok(())
 4521    }
 4522
 4523    pub fn refresh_background_diagnostics_for_buffers(
 4524        &mut self,
 4525        buffers: HashSet<BufferId>,
 4526        cx: &mut Context<Self>,
 4527    ) -> Shared<Task<()>> {
 4528        let Some(local) = self.as_local_mut() else {
 4529            return Task::ready(()).shared();
 4530        };
 4531        for buffer in buffers {
 4532            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4533                local.buffers_to_refresh_queue.push_back(buffer);
 4534                if local.buffers_to_refresh_queue.len() == 1 {
 4535                    local._background_diagnostics_worker =
 4536                        Self::background_diagnostics_worker(cx).shared();
 4537                }
 4538            }
 4539        }
 4540
 4541        local._background_diagnostics_worker.clone()
 4542    }
 4543
 4544    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4545        let buffer_store = self.buffer_store.clone();
 4546        let local = self.as_local_mut()?;
 4547        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4548            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4549            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4550                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4551            }
 4552        }
 4553        None
 4554    }
 4555
 4556    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4557        cx.spawn(async move |this, cx| {
 4558            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4559                task.await.log_err();
 4560            }
 4561        })
 4562    }
 4563
 4564    fn on_buffer_reloaded(&mut self, buffer: Entity<Buffer>, cx: &mut Context<Self>) {
 4565        if self.parse_modeline(&buffer, cx) {
 4566            self.detect_language_for_buffer(&buffer, cx);
 4567        }
 4568
 4569        let buffer_id = buffer.read(cx).remote_id();
 4570        let task = self.pull_diagnostics_for_buffer(buffer, cx);
 4571        self.buffer_reload_tasks.insert(buffer_id, task);
 4572    }
 4573
 4574    pub(crate) fn register_buffer_with_language_servers(
 4575        &mut self,
 4576        buffer: &Entity<Buffer>,
 4577        only_register_servers: HashSet<LanguageServerSelector>,
 4578        ignore_refcounts: bool,
 4579        cx: &mut Context<Self>,
 4580    ) -> OpenLspBufferHandle {
 4581        let buffer_id = buffer.read(cx).remote_id();
 4582        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4583        if let Some(local) = self.as_local_mut() {
 4584            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4585            if !ignore_refcounts {
 4586                *refcount += 1;
 4587            }
 4588
 4589            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4590            // 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
 4591            // 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
 4592            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4593            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4594                return handle;
 4595            };
 4596            if !file.is_local() {
 4597                return handle;
 4598            }
 4599
 4600            if ignore_refcounts || *refcount == 1 {
 4601                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4602            }
 4603            if !ignore_refcounts {
 4604                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4605                    let refcount = {
 4606                        let local = lsp_store.as_local_mut().unwrap();
 4607                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4608                            debug_panic!("bad refcounting");
 4609                            return;
 4610                        };
 4611
 4612                        *refcount -= 1;
 4613                        *refcount
 4614                    };
 4615                    if refcount == 0 {
 4616                        lsp_store.lsp_data.remove(&buffer_id);
 4617                        lsp_store.buffer_reload_tasks.remove(&buffer_id);
 4618                        let local = lsp_store.as_local_mut().unwrap();
 4619                        local.registered_buffers.remove(&buffer_id);
 4620
 4621                        local.buffers_opened_in_servers.remove(&buffer_id);
 4622                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4623                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4624
 4625                            let buffer_abs_path = file.abs_path(cx);
 4626                            for (_, buffer_pull_diagnostics_result_ids) in
 4627                                &mut local.buffer_pull_diagnostics_result_ids
 4628                            {
 4629                                buffer_pull_diagnostics_result_ids.retain(
 4630                                    |_, buffer_result_ids| {
 4631                                        buffer_result_ids.remove(&buffer_abs_path);
 4632                                        !buffer_result_ids.is_empty()
 4633                                    },
 4634                                );
 4635                            }
 4636
 4637                            let diagnostic_updates = local
 4638                                .language_servers
 4639                                .keys()
 4640                                .cloned()
 4641                                .map(|server_id| DocumentDiagnosticsUpdate {
 4642                                    diagnostics: DocumentDiagnostics {
 4643                                        document_abs_path: buffer_abs_path.clone(),
 4644                                        version: None,
 4645                                        diagnostics: Vec::new(),
 4646                                    },
 4647                                    result_id: None,
 4648                                    registration_id: None,
 4649                                    server_id,
 4650                                    disk_based_sources: Cow::Borrowed(&[]),
 4651                                })
 4652                                .collect::<Vec<_>>();
 4653
 4654                            lsp_store
 4655                                .merge_diagnostic_entries(
 4656                                    diagnostic_updates,
 4657                                    |_, diagnostic, _| {
 4658                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4659                                    },
 4660                                    cx,
 4661                                )
 4662                                .context("Clearing diagnostics for the closed buffer")
 4663                                .log_err();
 4664                        }
 4665                    }
 4666                })
 4667                .detach();
 4668            }
 4669        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4670            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4671            cx.background_spawn(async move {
 4672                upstream_client
 4673                    .request(proto::RegisterBufferWithLanguageServers {
 4674                        project_id: upstream_project_id,
 4675                        buffer_id,
 4676                        only_servers: only_register_servers
 4677                            .into_iter()
 4678                            .map(|selector| {
 4679                                let selector = match selector {
 4680                                    LanguageServerSelector::Id(language_server_id) => {
 4681                                        proto::language_server_selector::Selector::ServerId(
 4682                                            language_server_id.to_proto(),
 4683                                        )
 4684                                    }
 4685                                    LanguageServerSelector::Name(language_server_name) => {
 4686                                        proto::language_server_selector::Selector::Name(
 4687                                            language_server_name.to_string(),
 4688                                        )
 4689                                    }
 4690                                };
 4691                                proto::LanguageServerSelector {
 4692                                    selector: Some(selector),
 4693                                }
 4694                            })
 4695                            .collect(),
 4696                    })
 4697                    .await
 4698            })
 4699            .detach();
 4700        } else {
 4701            // Our remote connection got closed
 4702        }
 4703        handle
 4704    }
 4705
 4706    fn maintain_buffer_languages(
 4707        languages: Arc<LanguageRegistry>,
 4708        cx: &mut Context<Self>,
 4709    ) -> Task<()> {
 4710        let mut subscription = languages.subscribe();
 4711        let mut prev_reload_count = languages.reload_count();
 4712        cx.spawn(async move |this, cx| {
 4713            while let Some(()) = subscription.next().await {
 4714                if let Some(this) = this.upgrade() {
 4715                    // If the language registry has been reloaded, then remove and
 4716                    // re-assign the languages on all open buffers.
 4717                    let reload_count = languages.reload_count();
 4718                    if reload_count > prev_reload_count {
 4719                        prev_reload_count = reload_count;
 4720                        this.update(cx, |this, cx| {
 4721                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4722                                for buffer in buffer_store.buffers() {
 4723                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4724                                    {
 4725                                        buffer.update(cx, |buffer, cx| {
 4726                                            buffer.set_language_async(None, cx)
 4727                                        });
 4728                                        if let Some(local) = this.as_local_mut() {
 4729                                            local.reset_buffer(&buffer, &f, cx);
 4730
 4731                                            if local
 4732                                                .registered_buffers
 4733                                                .contains_key(&buffer.read(cx).remote_id())
 4734                                                && let Some(file_url) =
 4735                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4736                                            {
 4737                                                local.unregister_buffer_from_language_servers(
 4738                                                    &buffer, &file_url, cx,
 4739                                                );
 4740                                            }
 4741                                        }
 4742                                    }
 4743                                }
 4744                            });
 4745                        });
 4746                    }
 4747
 4748                    this.update(cx, |this, cx| {
 4749                        let mut plain_text_buffers = Vec::new();
 4750                        let mut buffers_with_language = Vec::new();
 4751                        let mut buffers_with_unknown_injections = Vec::new();
 4752                        for handle in this.buffer_store.read(cx).buffers() {
 4753                            let buffer = handle.read(cx);
 4754                            if buffer.language().is_none()
 4755                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4756                            {
 4757                                plain_text_buffers.push(handle);
 4758                            } else {
 4759                                if buffer.contains_unknown_injections() {
 4760                                    buffers_with_unknown_injections.push(handle.clone());
 4761                                }
 4762                                buffers_with_language.push(handle);
 4763                            }
 4764                        }
 4765
 4766                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4767                        // and reused later in the invisible worktrees.
 4768                        plain_text_buffers.sort_by_key(|buffer| {
 4769                            Reverse(
 4770                                File::from_dyn(buffer.read(cx).file())
 4771                                    .map(|file| file.worktree.read(cx).is_visible()),
 4772                            )
 4773                        });
 4774
 4775                        for buffer in plain_text_buffers {
 4776                            this.detect_language_for_buffer(&buffer, cx);
 4777                            if let Some(local) = this.as_local_mut() {
 4778                                local.initialize_buffer(&buffer, cx);
 4779                                if local
 4780                                    .registered_buffers
 4781                                    .contains_key(&buffer.read(cx).remote_id())
 4782                                {
 4783                                    local.register_buffer_with_language_servers(
 4784                                        &buffer,
 4785                                        HashSet::default(),
 4786                                        cx,
 4787                                    );
 4788                                }
 4789                            }
 4790                        }
 4791
 4792                        // Also register buffers that already have a language with
 4793                        // any newly-available language servers (e.g., from extensions
 4794                        // that finished loading after buffers were restored).
 4795                        if let Some(local) = this.as_local_mut() {
 4796                            for buffer in buffers_with_language {
 4797                                if local
 4798                                    .registered_buffers
 4799                                    .contains_key(&buffer.read(cx).remote_id())
 4800                                {
 4801                                    local.register_buffer_with_language_servers(
 4802                                        &buffer,
 4803                                        HashSet::default(),
 4804                                        cx,
 4805                                    );
 4806                                }
 4807                            }
 4808                        }
 4809
 4810                        for buffer in buffers_with_unknown_injections {
 4811                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4812                        }
 4813                    });
 4814                }
 4815            }
 4816        })
 4817    }
 4818
 4819    fn parse_modeline(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<Self>) -> bool {
 4820        let buffer = buffer_handle.read(cx);
 4821        let content = buffer.as_rope();
 4822
 4823        let modeline_settings = {
 4824            let settings_store = cx.global::<SettingsStore>();
 4825            let modeline_lines = settings_store
 4826                .raw_user_settings()
 4827                .and_then(|s| s.content.modeline_lines)
 4828                .or(settings_store.raw_default_settings().modeline_lines)
 4829                .unwrap_or(5);
 4830
 4831            const MAX_MODELINE_BYTES: usize = 1024;
 4832
 4833            let first_bytes =
 4834                content.clip_offset(content.len().min(MAX_MODELINE_BYTES), Bias::Left);
 4835            let mut first_lines = Vec::new();
 4836            let mut lines = content.chunks_in_range(0..first_bytes).lines();
 4837            for _ in 0..modeline_lines {
 4838                if let Some(line) = lines.next() {
 4839                    first_lines.push(line.to_string());
 4840                } else {
 4841                    break;
 4842                }
 4843            }
 4844            let first_lines_ref: Vec<_> = first_lines.iter().map(|line| line.as_str()).collect();
 4845
 4846            let last_start =
 4847                content.clip_offset(content.len().saturating_sub(MAX_MODELINE_BYTES), Bias::Left);
 4848            let mut last_lines = Vec::new();
 4849            let mut lines = content
 4850                .reversed_chunks_in_range(last_start..content.len())
 4851                .lines();
 4852            for _ in 0..modeline_lines {
 4853                if let Some(line) = lines.next() {
 4854                    last_lines.push(line.to_string());
 4855                } else {
 4856                    break;
 4857                }
 4858            }
 4859            let last_lines_ref: Vec<_> =
 4860                last_lines.iter().rev().map(|line| line.as_str()).collect();
 4861            modeline::parse_modeline(&first_lines_ref, &last_lines_ref)
 4862        };
 4863
 4864        log::debug!("Parsed modeline settings: {:?}", modeline_settings);
 4865
 4866        buffer_handle.update(cx, |buffer, _cx| buffer.set_modeline(modeline_settings))
 4867    }
 4868
 4869    fn detect_language_for_buffer(
 4870        &mut self,
 4871        buffer_handle: &Entity<Buffer>,
 4872        cx: &mut Context<Self>,
 4873    ) -> Option<language::AvailableLanguage> {
 4874        // If the buffer has a language, set it and start the language server if we haven't already.
 4875        let buffer = buffer_handle.read(cx);
 4876        let file = buffer.file()?;
 4877        let content = buffer.as_rope();
 4878        let modeline_settings = buffer.modeline().map(Arc::as_ref);
 4879
 4880        let available_language = if let Some(ModelineSettings {
 4881            mode: Some(mode_name),
 4882            ..
 4883        }) = modeline_settings
 4884        {
 4885            self.languages
 4886                .available_language_for_modeline_name(mode_name)
 4887        } else {
 4888            self.languages.language_for_file(file, Some(content), cx)
 4889        };
 4890        if let Some(available_language) = &available_language {
 4891            if let Some(Ok(Ok(new_language))) = self
 4892                .languages
 4893                .load_language(available_language)
 4894                .now_or_never()
 4895            {
 4896                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4897            }
 4898        } else {
 4899            cx.emit(LspStoreEvent::LanguageDetected {
 4900                buffer: buffer_handle.clone(),
 4901                new_language: None,
 4902            });
 4903        }
 4904
 4905        available_language
 4906    }
 4907
 4908    pub(crate) fn set_language_for_buffer(
 4909        &mut self,
 4910        buffer_entity: &Entity<Buffer>,
 4911        new_language: Arc<Language>,
 4912        cx: &mut Context<Self>,
 4913    ) {
 4914        let buffer = buffer_entity.read(cx);
 4915        let buffer_file = buffer.file().cloned();
 4916        let buffer_id = buffer.remote_id();
 4917        if let Some(local_store) = self.as_local_mut()
 4918            && local_store.registered_buffers.contains_key(&buffer_id)
 4919            && let Some(abs_path) =
 4920                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4921            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4922        {
 4923            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4924        }
 4925        buffer_entity.update(cx, |buffer, cx| {
 4926            if buffer
 4927                .language()
 4928                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4929            {
 4930                buffer.set_language_async(Some(new_language.clone()), cx);
 4931            }
 4932        });
 4933
 4934        let settings = LanguageSettings::resolve(
 4935            Some(&buffer_entity.read(cx)),
 4936            Some(&new_language.name()),
 4937            cx,
 4938        )
 4939        .into_owned();
 4940        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4941
 4942        let worktree_id = if let Some(file) = buffer_file {
 4943            let worktree = file.worktree.clone();
 4944
 4945            if let Some(local) = self.as_local_mut()
 4946                && local.registered_buffers.contains_key(&buffer_id)
 4947            {
 4948                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4949            }
 4950            Some(worktree.read(cx).id())
 4951        } else {
 4952            None
 4953        };
 4954
 4955        if settings.prettier.allowed
 4956            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4957        {
 4958            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4959            if let Some(prettier_store) = prettier_store {
 4960                prettier_store.update(cx, |prettier_store, cx| {
 4961                    prettier_store.install_default_prettier(
 4962                        worktree_id,
 4963                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4964                        cx,
 4965                    )
 4966                })
 4967            }
 4968        }
 4969
 4970        cx.emit(LspStoreEvent::LanguageDetected {
 4971            buffer: buffer_entity.clone(),
 4972            new_language: Some(new_language),
 4973        })
 4974    }
 4975
 4976    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4977        self.buffer_store.clone()
 4978    }
 4979
 4980    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4981        self.active_entry = active_entry;
 4982    }
 4983
 4984    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4985        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4986            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4987        {
 4988            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4989                summaries
 4990                    .iter()
 4991                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4992            });
 4993            if let Some(summary) = summaries.next() {
 4994                client
 4995                    .send(proto::UpdateDiagnosticSummary {
 4996                        project_id: downstream_project_id,
 4997                        worktree_id: worktree.id().to_proto(),
 4998                        summary: Some(summary),
 4999                        more_summaries: summaries.collect(),
 5000                    })
 5001                    .log_err();
 5002            }
 5003        }
 5004    }
 5005
 5006    fn is_capable_for_proto_request<R>(
 5007        &self,
 5008        buffer: &Entity<Buffer>,
 5009        request: &R,
 5010        cx: &App,
 5011    ) -> bool
 5012    where
 5013        R: LspCommand,
 5014    {
 5015        self.check_if_capable_for_proto_request(
 5016            buffer,
 5017            |capabilities| {
 5018                request.check_capabilities(AdapterServerCapabilities {
 5019                    server_capabilities: capabilities.clone(),
 5020                    code_action_kinds: None,
 5021                })
 5022            },
 5023            cx,
 5024        )
 5025    }
 5026
 5027    fn relevant_server_ids_for_capability_check(
 5028        &self,
 5029        buffer: &Entity<Buffer>,
 5030        cx: &App,
 5031    ) -> Vec<LanguageServerId> {
 5032        let buffer_id = buffer.read(cx).remote_id();
 5033        if let Some(local) = self.as_local() {
 5034            return local
 5035                .buffers_opened_in_servers
 5036                .get(&buffer_id)
 5037                .into_iter()
 5038                .flatten()
 5039                .copied()
 5040                .collect();
 5041        }
 5042
 5043        let Some(language) = buffer.read(cx).language().cloned() else {
 5044            return Vec::default();
 5045        };
 5046        let registered_language_servers = self
 5047            .languages
 5048            .lsp_adapters(&language.name())
 5049            .into_iter()
 5050            .map(|lsp_adapter| lsp_adapter.name())
 5051            .collect::<HashSet<_>>();
 5052        self.language_server_statuses
 5053            .iter()
 5054            .filter_map(|(server_id, server_status)| {
 5055                // Include servers that are either registered for this language OR
 5056                // available to be loaded (for SSH remote mode where adapters like
 5057                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 5058                // but only loaded on the server side)
 5059                let is_relevant = registered_language_servers.contains(&server_status.name)
 5060                    || self.languages.is_lsp_adapter_available(&server_status.name);
 5061                is_relevant.then_some(*server_id)
 5062            })
 5063            .collect()
 5064    }
 5065
 5066    fn check_if_any_relevant_server_matches<F>(
 5067        &self,
 5068        buffer: &Entity<Buffer>,
 5069        mut check: F,
 5070        cx: &App,
 5071    ) -> bool
 5072    where
 5073        F: FnMut(&LanguageServerStatus, &lsp::ServerCapabilities) -> bool,
 5074    {
 5075        self.relevant_server_ids_for_capability_check(buffer, cx)
 5076            .into_iter()
 5077            .filter_map(|server_id| {
 5078                Some((
 5079                    self.language_server_statuses.get(&server_id)?,
 5080                    self.lsp_server_capabilities.get(&server_id)?,
 5081                ))
 5082            })
 5083            .any(|(server_status, capabilities)| check(server_status, capabilities))
 5084    }
 5085
 5086    fn check_if_capable_for_proto_request<F>(
 5087        &self,
 5088        buffer: &Entity<Buffer>,
 5089        mut check: F,
 5090        cx: &App,
 5091    ) -> bool
 5092    where
 5093        F: FnMut(&lsp::ServerCapabilities) -> bool,
 5094    {
 5095        self.check_if_any_relevant_server_matches(buffer, |_, capabilities| check(capabilities), cx)
 5096    }
 5097
 5098    pub fn supports_range_formatting(&self, buffer: &Entity<Buffer>, cx: &App) -> bool {
 5099        let settings = LanguageSettings::for_buffer(buffer.read(cx), cx);
 5100        settings.formatter.as_ref().iter().any(|formatter| {
 5101            match formatter {
 5102                Formatter::None => false,
 5103                Formatter::Auto => {
 5104                    settings.prettier.allowed
 5105                        || self.check_if_capable_for_proto_request(
 5106                            buffer,
 5107                            server_capabilities_support_range_formatting,
 5108                            cx,
 5109                        )
 5110                }
 5111                Formatter::Prettier => true,
 5112                Formatter::External { .. } => false,
 5113                Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current) => {
 5114                    self.check_if_capable_for_proto_request(
 5115                        buffer,
 5116                        server_capabilities_support_range_formatting,
 5117                        cx,
 5118                    )
 5119                }
 5120                Formatter::LanguageServer(
 5121                    settings::LanguageServerFormatterSpecifier::Specific { name },
 5122                ) => self.check_if_any_relevant_server_matches(
 5123                    buffer,
 5124                    |server_status, capabilities| {
 5125                        server_status.name.0.as_ref() == name
 5126                            && server_capabilities_support_range_formatting(capabilities)
 5127                    },
 5128                    cx,
 5129                ),
 5130                // `FormatSelections` should only surface when a formatter can honor the
 5131                // selected ranges. Code actions can still run as part of formatting, but
 5132                // they operate on the whole buffer rather than the selected text.
 5133                Formatter::CodeAction(_) => false,
 5134            }
 5135        })
 5136    }
 5137
 5138    fn all_capable_for_proto_request<F>(
 5139        &self,
 5140        buffer: &Entity<Buffer>,
 5141        mut check: F,
 5142        cx: &App,
 5143    ) -> Vec<(lsp::LanguageServerId, lsp::LanguageServerName)>
 5144    where
 5145        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 5146    {
 5147        self.relevant_server_ids_for_capability_check(buffer, cx)
 5148            .into_iter()
 5149            .filter_map(|server_id| {
 5150                Some((
 5151                    server_id,
 5152                    &self.language_server_statuses.get(&server_id)?.name,
 5153                    self.lsp_server_capabilities.get(&server_id)?,
 5154                ))
 5155            })
 5156            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 5157            .map(|(server_id, server_name, _)| (server_id, server_name.clone()))
 5158            .collect()
 5159    }
 5160
 5161    pub fn request_lsp<R>(
 5162        &mut self,
 5163        buffer: Entity<Buffer>,
 5164        server: LanguageServerToQuery,
 5165        request: R,
 5166        cx: &mut Context<Self>,
 5167    ) -> Task<Result<R::Response>>
 5168    where
 5169        R: LspCommand,
 5170        <R::LspRequest as lsp::request::Request>::Result: Send,
 5171        <R::LspRequest as lsp::request::Request>::Params: Send,
 5172    {
 5173        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 5174            return self.send_lsp_proto_request(
 5175                buffer,
 5176                upstream_client,
 5177                upstream_project_id,
 5178                request,
 5179                cx,
 5180            );
 5181        }
 5182
 5183        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 5184            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 5185                local
 5186                    .language_servers_for_buffer(buffer, cx)
 5187                    .find(|(_, server)| {
 5188                        request.check_capabilities(server.adapter_server_capabilities())
 5189                    })
 5190                    .map(|(_, server)| server.clone())
 5191            }),
 5192            LanguageServerToQuery::Other(id) => self
 5193                .language_server_for_local_buffer(buffer, id, cx)
 5194                .and_then(|(_, server)| {
 5195                    request
 5196                        .check_capabilities(server.adapter_server_capabilities())
 5197                        .then(|| Arc::clone(server))
 5198                }),
 5199        }) else {
 5200            return Task::ready(Ok(Default::default()));
 5201        };
 5202
 5203        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 5204
 5205        let Some(file) = file else {
 5206            return Task::ready(Ok(Default::default()));
 5207        };
 5208
 5209        let lsp_params = match request.to_lsp_params_or_response(
 5210            &file.abs_path(cx),
 5211            buffer.read(cx),
 5212            &language_server,
 5213            cx,
 5214        ) {
 5215            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 5216            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 5217            Err(err) => {
 5218                let message = format!(
 5219                    "{} via {} failed: {}",
 5220                    request.display_name(),
 5221                    language_server.name(),
 5222                    err
 5223                );
 5224                // rust-analyzer likes to error with this when its still loading up
 5225                if !message.ends_with("content modified") {
 5226                    log::warn!("{message}");
 5227                }
 5228                return Task::ready(Err(anyhow!(message)));
 5229            }
 5230        };
 5231
 5232        let status = request.status();
 5233        let request_timeout = ProjectSettings::get_global(cx)
 5234            .global_lsp_settings
 5235            .get_request_timeout();
 5236
 5237        cx.spawn(async move |this, cx| {
 5238            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5239
 5240            let id = lsp_request.id();
 5241            let _cleanup = if status.is_some() {
 5242                cx.update(|cx| {
 5243                    this.update(cx, |this, cx| {
 5244                        this.on_lsp_work_start(
 5245                            language_server.server_id(),
 5246                            ProgressToken::Number(id),
 5247                            LanguageServerProgress {
 5248                                is_disk_based_diagnostics_progress: false,
 5249                                is_cancellable: false,
 5250                                title: None,
 5251                                message: status.clone(),
 5252                                percentage: None,
 5253                                last_update_at: cx.background_executor().now(),
 5254                            },
 5255                            cx,
 5256                        );
 5257                    })
 5258                })
 5259                .log_err();
 5260
 5261                Some(defer(|| {
 5262                    cx.update(|cx| {
 5263                        this.update(cx, |this, cx| {
 5264                            this.on_lsp_work_end(
 5265                                language_server.server_id(),
 5266                                ProgressToken::Number(id),
 5267                                cx,
 5268                            );
 5269                        })
 5270                    })
 5271                    .log_err();
 5272                }))
 5273            } else {
 5274                None
 5275            };
 5276
 5277            let result = lsp_request.await.into_response();
 5278
 5279            let response = result.map_err(|err| {
 5280                let message = format!(
 5281                    "{} via {} failed: {}",
 5282                    request.display_name(),
 5283                    language_server.name(),
 5284                    err
 5285                );
 5286                // rust-analyzer likes to error with this when its still loading up
 5287                if !message.ends_with("content modified") {
 5288                    log::warn!("{message}");
 5289                }
 5290                anyhow::anyhow!(message)
 5291            })?;
 5292
 5293            request
 5294                .response_from_lsp(
 5295                    response,
 5296                    this.upgrade().context("no app context")?,
 5297                    buffer,
 5298                    language_server.server_id(),
 5299                    cx.clone(),
 5300                )
 5301                .await
 5302        })
 5303    }
 5304
 5305    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5306        let mut language_formatters_to_check = Vec::new();
 5307        for buffer in self.buffer_store.read(cx).buffers() {
 5308            let buffer = buffer.read(cx);
 5309            let settings = LanguageSettings::for_buffer(buffer, cx);
 5310            if buffer.language().is_some() {
 5311                let buffer_file = File::from_dyn(buffer.file());
 5312                language_formatters_to_check.push((
 5313                    buffer_file.map(|f| f.worktree_id(cx)),
 5314                    settings.into_owned(),
 5315                ));
 5316            }
 5317        }
 5318
 5319        self.request_workspace_config_refresh();
 5320
 5321        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5322            prettier_store.update(cx, |prettier_store, cx| {
 5323                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5324            })
 5325        }
 5326
 5327        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5328            .global_lsp_settings
 5329            .semantic_token_rules
 5330            .clone();
 5331        self.semantic_token_config
 5332            .update_rules(new_semantic_token_rules);
 5333        // Always clear cached stylizers so that changes to language-specific
 5334        // semantic token rules (e.g. from extension install/uninstall) are
 5335        // picked up. Stylizers are recreated lazily, so this is cheap.
 5336        self.semantic_token_config.clear_stylizers();
 5337
 5338        let new_global_semantic_tokens_mode =
 5339            all_language_settings(None, cx).defaults.semantic_tokens;
 5340        if self
 5341            .semantic_token_config
 5342            .update_global_mode(new_global_semantic_tokens_mode)
 5343        {
 5344            self.restart_all_language_servers(cx);
 5345        }
 5346
 5347        cx.notify();
 5348    }
 5349
 5350    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5351        let buffer_store = self.buffer_store.clone();
 5352        let Some(local) = self.as_local_mut() else {
 5353            return;
 5354        };
 5355        let mut adapters = BTreeMap::default();
 5356        let get_adapter = {
 5357            let languages = local.languages.clone();
 5358            let environment = local.environment.clone();
 5359            let weak = local.weak.clone();
 5360            let worktree_store = local.worktree_store.clone();
 5361            let http_client = local.http_client.clone();
 5362            let fs = local.fs.clone();
 5363            move |worktree_id, cx: &mut App| {
 5364                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5365                Some(LocalLspAdapterDelegate::new(
 5366                    languages.clone(),
 5367                    &environment,
 5368                    weak.clone(),
 5369                    &worktree,
 5370                    http_client.clone(),
 5371                    fs.clone(),
 5372                    cx,
 5373                ))
 5374            }
 5375        };
 5376
 5377        let mut messages_to_report = Vec::new();
 5378        let (new_tree, to_stop) = {
 5379            let mut rebase = local.lsp_tree.rebase();
 5380            let buffers = buffer_store
 5381                .read(cx)
 5382                .buffers()
 5383                .filter_map(|buffer| {
 5384                    let raw_buffer = buffer.read(cx);
 5385                    if !local
 5386                        .registered_buffers
 5387                        .contains_key(&raw_buffer.remote_id())
 5388                    {
 5389                        return None;
 5390                    }
 5391                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5392                    let language = raw_buffer.language().cloned()?;
 5393                    Some((file, language, raw_buffer.remote_id()))
 5394                })
 5395                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5396            for (file, language, buffer_id) in buffers {
 5397                let worktree_id = file.worktree_id(cx);
 5398                let Some(worktree) = local
 5399                    .worktree_store
 5400                    .read(cx)
 5401                    .worktree_for_id(worktree_id, cx)
 5402                else {
 5403                    continue;
 5404                };
 5405
 5406                if let Some((_, apply)) = local.reuse_existing_language_server(
 5407                    rebase.server_tree(),
 5408                    &worktree,
 5409                    &language.name(),
 5410                    cx,
 5411                ) {
 5412                    (apply)(rebase.server_tree());
 5413                } else if let Some(lsp_delegate) = adapters
 5414                    .entry(worktree_id)
 5415                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5416                    .clone()
 5417                {
 5418                    let delegate =
 5419                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5420                    let path = file
 5421                        .path()
 5422                        .parent()
 5423                        .map(Arc::from)
 5424                        .unwrap_or_else(|| file.path().clone());
 5425                    let worktree_path = ProjectPath { worktree_id, path };
 5426                    let abs_path = file.abs_path(cx);
 5427                    let nodes = rebase
 5428                        .walk(
 5429                            worktree_path,
 5430                            language.name(),
 5431                            language.manifest(),
 5432                            delegate.clone(),
 5433                            cx,
 5434                        )
 5435                        .collect::<Vec<_>>();
 5436                    for node in nodes {
 5437                        let server_id = node.server_id_or_init(|disposition| {
 5438                            let path = &disposition.path;
 5439                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5440                            let key = LanguageServerSeed {
 5441                                worktree_id,
 5442                                name: disposition.server_name.clone(),
 5443                                settings: LanguageServerSeedSettings {
 5444                                    binary: disposition.settings.binary.clone(),
 5445                                    initialization_options: disposition
 5446                                        .settings
 5447                                        .initialization_options
 5448                                        .clone(),
 5449                                },
 5450                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5451                                    path.worktree_id,
 5452                                    &path.path,
 5453                                    language.name(),
 5454                                ),
 5455                            };
 5456                            local.language_server_ids.remove(&key);
 5457
 5458                            let server_id = local.get_or_insert_language_server(
 5459                                &worktree,
 5460                                lsp_delegate.clone(),
 5461                                disposition,
 5462                                &language.name(),
 5463                                cx,
 5464                            );
 5465                            if let Some(state) = local.language_servers.get(&server_id)
 5466                                && let Ok(uri) = uri
 5467                            {
 5468                                state.add_workspace_folder(uri);
 5469                            };
 5470                            server_id
 5471                        });
 5472
 5473                        if let Some(language_server_id) = server_id {
 5474                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5475                                language_server_id,
 5476                                name: node.name(),
 5477                                message:
 5478                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5479                                        proto::RegisteredForBuffer {
 5480                                            buffer_abs_path: abs_path
 5481                                                .to_string_lossy()
 5482                                                .into_owned(),
 5483                                            buffer_id: buffer_id.to_proto(),
 5484                                        },
 5485                                    ),
 5486                            });
 5487                        }
 5488                    }
 5489                } else {
 5490                    continue;
 5491                }
 5492            }
 5493            rebase.finish()
 5494        };
 5495        for message in messages_to_report {
 5496            cx.emit(message);
 5497        }
 5498        local.lsp_tree = new_tree;
 5499        for (id, _) in to_stop {
 5500            self.stop_local_language_server(id, cx).detach();
 5501        }
 5502    }
 5503
 5504    pub fn apply_code_action(
 5505        &self,
 5506        buffer_handle: Entity<Buffer>,
 5507        mut action: CodeAction,
 5508        push_to_history: bool,
 5509        cx: &mut Context<Self>,
 5510    ) -> Task<Result<ProjectTransaction>> {
 5511        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5512            let request = proto::ApplyCodeAction {
 5513                project_id,
 5514                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5515                action: Some(Self::serialize_code_action(&action)),
 5516            };
 5517            let buffer_store = self.buffer_store();
 5518            cx.spawn(async move |_, cx| {
 5519                let response = upstream_client
 5520                    .request(request)
 5521                    .await?
 5522                    .transaction
 5523                    .context("missing transaction")?;
 5524
 5525                buffer_store
 5526                    .update(cx, |buffer_store, cx| {
 5527                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5528                    })
 5529                    .await
 5530            })
 5531        } else if self.mode.is_local() {
 5532            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5533                let request_timeout = ProjectSettings::get_global(cx)
 5534                    .global_lsp_settings
 5535                    .get_request_timeout();
 5536                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5537                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5538            }) else {
 5539                return Task::ready(Ok(ProjectTransaction::default()));
 5540            };
 5541
 5542            cx.spawn(async move |this, cx| {
 5543                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5544                    .await
 5545                    .context("resolving a code action")?;
 5546                if let Some(edit) = action.lsp_action.edit()
 5547                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5548                        return LocalLspStore::deserialize_workspace_edit(
 5549                            this.upgrade().context("no app present")?,
 5550                            edit.clone(),
 5551                            push_to_history,
 5552
 5553                            lang_server.clone(),
 5554                            cx,
 5555                        )
 5556                        .await;
 5557                    }
 5558
 5559                let Some(command) = action.lsp_action.command() else {
 5560                    return Ok(ProjectTransaction::default())
 5561                };
 5562
 5563                let server_capabilities = lang_server.capabilities();
 5564                let available_commands = server_capabilities
 5565                    .execute_command_provider
 5566                    .as_ref()
 5567                    .map(|options| options.commands.as_slice())
 5568                    .unwrap_or_default();
 5569
 5570                if !available_commands.contains(&command.command) {
 5571                    log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5572                    return Ok(ProjectTransaction::default())
 5573                }
 5574
 5575                let request_timeout = cx.update(|app|
 5576                    ProjectSettings::get_global(app)
 5577                    .global_lsp_settings
 5578                    .get_request_timeout()
 5579                );
 5580
 5581                this.update(cx, |this, _| {
 5582                    this.as_local_mut()
 5583                        .unwrap()
 5584                        .last_workspace_edits_by_language_server
 5585                        .remove(&lang_server.server_id());
 5586                })?;
 5587
 5588                let _result = lang_server
 5589                    .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5590                        command: command.command.clone(),
 5591                        arguments: command.arguments.clone().unwrap_or_default(),
 5592                        ..lsp::ExecuteCommandParams::default()
 5593                    }, request_timeout)
 5594                    .await.into_response()
 5595                    .context("execute command")?;
 5596
 5597                return this.update(cx, |this, _| {
 5598                    this.as_local_mut()
 5599                        .unwrap()
 5600                        .last_workspace_edits_by_language_server
 5601                        .remove(&lang_server.server_id())
 5602                        .unwrap_or_default()
 5603                });
 5604            })
 5605        } else {
 5606            Task::ready(Err(anyhow!("no upstream client and not local")))
 5607        }
 5608    }
 5609
 5610    pub fn apply_code_action_kind(
 5611        &mut self,
 5612        buffers: HashSet<Entity<Buffer>>,
 5613        kind: CodeActionKind,
 5614        push_to_history: bool,
 5615        cx: &mut Context<Self>,
 5616    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5617        if self.as_local().is_some() {
 5618            cx.spawn(async move |lsp_store, cx| {
 5619                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5620                let result = LocalLspStore::execute_code_action_kind_locally(
 5621                    lsp_store.clone(),
 5622                    buffers,
 5623                    kind,
 5624                    push_to_history,
 5625                    cx,
 5626                )
 5627                .await;
 5628                lsp_store.update(cx, |lsp_store, _| {
 5629                    lsp_store.update_last_formatting_failure(&result);
 5630                })?;
 5631                result
 5632            })
 5633        } else if let Some((client, project_id)) = self.upstream_client() {
 5634            let buffer_store = self.buffer_store();
 5635            cx.spawn(async move |lsp_store, cx| {
 5636                let result = client
 5637                    .request(proto::ApplyCodeActionKind {
 5638                        project_id,
 5639                        kind: kind.as_str().to_owned(),
 5640                        buffer_ids: buffers
 5641                            .iter()
 5642                            .map(|buffer| {
 5643                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5644                            })
 5645                            .collect(),
 5646                    })
 5647                    .await
 5648                    .and_then(|result| result.transaction.context("missing transaction"));
 5649                lsp_store.update(cx, |lsp_store, _| {
 5650                    lsp_store.update_last_formatting_failure(&result);
 5651                })?;
 5652
 5653                let transaction_response = result?;
 5654                buffer_store
 5655                    .update(cx, |buffer_store, cx| {
 5656                        buffer_store.deserialize_project_transaction(
 5657                            transaction_response,
 5658                            push_to_history,
 5659                            cx,
 5660                        )
 5661                    })
 5662                    .await
 5663            })
 5664        } else {
 5665            Task::ready(Ok(ProjectTransaction::default()))
 5666        }
 5667    }
 5668
 5669    pub fn resolved_hint(
 5670        &mut self,
 5671        buffer_id: BufferId,
 5672        id: InlayId,
 5673        cx: &mut Context<Self>,
 5674    ) -> Option<ResolvedHint> {
 5675        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5676
 5677        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5678        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5679        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5680        let (server_id, resolve_data) = match &hint.resolve_state {
 5681            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5682            ResolveState::Resolving => {
 5683                return Some(ResolvedHint::Resolving(
 5684                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5685                ));
 5686            }
 5687            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5688        };
 5689
 5690        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5691        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5692        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5693            id,
 5694            cx.spawn(async move |lsp_store, cx| {
 5695                let resolved_hint = resolve_task.await;
 5696                lsp_store
 5697                    .update(cx, |lsp_store, _| {
 5698                        if let Some(old_inlay_hint) = lsp_store
 5699                            .lsp_data
 5700                            .get_mut(&buffer_id)
 5701                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5702                        {
 5703                            match resolved_hint {
 5704                                Ok(resolved_hint) => {
 5705                                    *old_inlay_hint = resolved_hint;
 5706                                }
 5707                                Err(e) => {
 5708                                    old_inlay_hint.resolve_state =
 5709                                        ResolveState::CanResolve(server_id, resolve_data);
 5710                                    log::error!("Inlay hint resolve failed: {e:#}");
 5711                                }
 5712                            }
 5713                        }
 5714                    })
 5715                    .ok();
 5716            })
 5717            .shared(),
 5718        );
 5719        debug_assert!(
 5720            previous_task.is_none(),
 5721            "Did not change hint's resolve state after spawning its resolve"
 5722        );
 5723        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5724        None
 5725    }
 5726
 5727    pub(crate) fn linked_edits(
 5728        &mut self,
 5729        buffer: &Entity<Buffer>,
 5730        position: Anchor,
 5731        cx: &mut Context<Self>,
 5732    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5733        let snapshot = buffer.read(cx).snapshot();
 5734        let scope = snapshot.language_scope_at(position);
 5735        let Some(server_id) = self
 5736            .as_local()
 5737            .and_then(|local| {
 5738                buffer.update(cx, |buffer, cx| {
 5739                    local
 5740                        .language_servers_for_buffer(buffer, cx)
 5741                        .filter(|(_, server)| {
 5742                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5743                        })
 5744                        .filter(|(adapter, _)| {
 5745                            scope
 5746                                .as_ref()
 5747                                .map(|scope| scope.language_allowed(&adapter.name))
 5748                                .unwrap_or(true)
 5749                        })
 5750                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5751                        .next()
 5752                })
 5753            })
 5754            .or_else(|| {
 5755                self.upstream_client()
 5756                    .is_some()
 5757                    .then_some(LanguageServerToQuery::FirstCapable)
 5758            })
 5759            .filter(|_| {
 5760                maybe!({
 5761                    buffer.read(cx).language_at(position)?;
 5762                    Some(
 5763                        LanguageSettings::for_buffer_at(&buffer.read(cx), position, cx)
 5764                            .linked_edits,
 5765                    )
 5766                }) == Some(true)
 5767            })
 5768        else {
 5769            return Task::ready(Ok(Vec::new()));
 5770        };
 5771
 5772        self.request_lsp(
 5773            buffer.clone(),
 5774            server_id,
 5775            LinkedEditingRange { position },
 5776            cx,
 5777        )
 5778    }
 5779
 5780    fn apply_on_type_formatting(
 5781        &mut self,
 5782        buffer: Entity<Buffer>,
 5783        position: Anchor,
 5784        trigger: String,
 5785        cx: &mut Context<Self>,
 5786    ) -> Task<Result<Option<Transaction>>> {
 5787        if let Some((client, project_id)) = self.upstream_client() {
 5788            if !self.check_if_capable_for_proto_request(
 5789                &buffer,
 5790                |capabilities| {
 5791                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5792                },
 5793                cx,
 5794            ) {
 5795                return Task::ready(Ok(None));
 5796            }
 5797            let request = proto::OnTypeFormatting {
 5798                project_id,
 5799                buffer_id: buffer.read(cx).remote_id().into(),
 5800                position: Some(serialize_anchor(&position)),
 5801                trigger,
 5802                version: serialize_version(&buffer.read(cx).version()),
 5803            };
 5804            cx.background_spawn(async move {
 5805                client
 5806                    .request(request)
 5807                    .await?
 5808                    .transaction
 5809                    .map(language::proto::deserialize_transaction)
 5810                    .transpose()
 5811            })
 5812        } else if let Some(local) = self.as_local_mut() {
 5813            let buffer_id = buffer.read(cx).remote_id();
 5814            local.buffers_being_formatted.insert(buffer_id);
 5815            cx.spawn(async move |this, cx| {
 5816                let _cleanup = defer({
 5817                    let this = this.clone();
 5818                    let mut cx = cx.clone();
 5819                    move || {
 5820                        this.update(&mut cx, |this, _| {
 5821                            if let Some(local) = this.as_local_mut() {
 5822                                local.buffers_being_formatted.remove(&buffer_id);
 5823                            }
 5824                        })
 5825                        .ok();
 5826                    }
 5827                });
 5828
 5829                buffer
 5830                    .update(cx, |buffer, _| {
 5831                        buffer.wait_for_edits(Some(position.timestamp()))
 5832                    })
 5833                    .await?;
 5834                this.update(cx, |this, cx| {
 5835                    let position = position.to_point_utf16(buffer.read(cx));
 5836                    this.on_type_format(buffer, position, trigger, false, cx)
 5837                })?
 5838                .await
 5839            })
 5840        } else {
 5841            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5842        }
 5843    }
 5844
 5845    pub fn on_type_format<T: ToPointUtf16>(
 5846        &mut self,
 5847        buffer: Entity<Buffer>,
 5848        position: T,
 5849        trigger: String,
 5850        push_to_history: bool,
 5851        cx: &mut Context<Self>,
 5852    ) -> Task<Result<Option<Transaction>>> {
 5853        let position = position.to_point_utf16(buffer.read(cx));
 5854        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5855    }
 5856
 5857    fn on_type_format_impl(
 5858        &mut self,
 5859        buffer: Entity<Buffer>,
 5860        position: PointUtf16,
 5861        trigger: String,
 5862        push_to_history: bool,
 5863        cx: &mut Context<Self>,
 5864    ) -> Task<Result<Option<Transaction>>> {
 5865        let options = buffer.update(cx, |buffer, cx| {
 5866            lsp_command::lsp_formatting_options(
 5867                LanguageSettings::for_buffer_at(buffer, position, cx).as_ref(),
 5868            )
 5869        });
 5870
 5871        cx.spawn(async move |this, cx| {
 5872            if let Some(waiter) =
 5873                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5874            {
 5875                waiter.await?;
 5876            }
 5877            cx.update(|cx| {
 5878                this.update(cx, |this, cx| {
 5879                    this.request_lsp(
 5880                        buffer.clone(),
 5881                        LanguageServerToQuery::FirstCapable,
 5882                        OnTypeFormatting {
 5883                            position,
 5884                            trigger,
 5885                            options,
 5886                            push_to_history,
 5887                        },
 5888                        cx,
 5889                    )
 5890                })
 5891            })?
 5892            .await
 5893        })
 5894    }
 5895
 5896    pub fn definitions(
 5897        &mut self,
 5898        buffer: &Entity<Buffer>,
 5899        position: PointUtf16,
 5900        cx: &mut Context<Self>,
 5901    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5902        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5903            let request = GetDefinitions { position };
 5904            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5905                return Task::ready(Ok(None));
 5906            }
 5907
 5908            let request_timeout = ProjectSettings::get_global(cx)
 5909                .global_lsp_settings
 5910                .get_request_timeout();
 5911
 5912            let request_task = upstream_client.request_lsp(
 5913                project_id,
 5914                None,
 5915                request_timeout,
 5916                cx.background_executor().clone(),
 5917                request.to_proto(project_id, buffer.read(cx)),
 5918            );
 5919            let buffer = buffer.clone();
 5920            cx.spawn(async move |weak_lsp_store, cx| {
 5921                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5922                    return Ok(None);
 5923                };
 5924                let Some(responses) = request_task.await? else {
 5925                    return Ok(None);
 5926                };
 5927                let actions = join_all(responses.payload.into_iter().map(|response| {
 5928                    GetDefinitions { position }.response_from_proto(
 5929                        response.response,
 5930                        lsp_store.clone(),
 5931                        buffer.clone(),
 5932                        cx.clone(),
 5933                    )
 5934                }))
 5935                .await;
 5936
 5937                Ok(Some(
 5938                    actions
 5939                        .into_iter()
 5940                        .collect::<Result<Vec<Vec<_>>>>()?
 5941                        .into_iter()
 5942                        .flatten()
 5943                        .dedup()
 5944                        .collect(),
 5945                ))
 5946            })
 5947        } else {
 5948            let definitions_task = self.request_multiple_lsp_locally(
 5949                buffer,
 5950                Some(position),
 5951                GetDefinitions { position },
 5952                cx,
 5953            );
 5954            cx.background_spawn(async move {
 5955                Ok(Some(
 5956                    definitions_task
 5957                        .await
 5958                        .into_iter()
 5959                        .flat_map(|(_, definitions)| definitions)
 5960                        .dedup()
 5961                        .collect(),
 5962                ))
 5963            })
 5964        }
 5965    }
 5966
 5967    pub fn declarations(
 5968        &mut self,
 5969        buffer: &Entity<Buffer>,
 5970        position: PointUtf16,
 5971        cx: &mut Context<Self>,
 5972    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5973        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5974            let request = GetDeclarations { position };
 5975            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5976                return Task::ready(Ok(None));
 5977            }
 5978            let request_timeout = ProjectSettings::get_global(cx)
 5979                .global_lsp_settings
 5980                .get_request_timeout();
 5981            let request_task = upstream_client.request_lsp(
 5982                project_id,
 5983                None,
 5984                request_timeout,
 5985                cx.background_executor().clone(),
 5986                request.to_proto(project_id, buffer.read(cx)),
 5987            );
 5988            let buffer = buffer.clone();
 5989            cx.spawn(async move |weak_lsp_store, cx| {
 5990                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5991                    return Ok(None);
 5992                };
 5993                let Some(responses) = request_task.await? else {
 5994                    return Ok(None);
 5995                };
 5996                let actions = join_all(responses.payload.into_iter().map(|response| {
 5997                    GetDeclarations { position }.response_from_proto(
 5998                        response.response,
 5999                        lsp_store.clone(),
 6000                        buffer.clone(),
 6001                        cx.clone(),
 6002                    )
 6003                }))
 6004                .await;
 6005
 6006                Ok(Some(
 6007                    actions
 6008                        .into_iter()
 6009                        .collect::<Result<Vec<Vec<_>>>>()?
 6010                        .into_iter()
 6011                        .flatten()
 6012                        .dedup()
 6013                        .collect(),
 6014                ))
 6015            })
 6016        } else {
 6017            let declarations_task = self.request_multiple_lsp_locally(
 6018                buffer,
 6019                Some(position),
 6020                GetDeclarations { position },
 6021                cx,
 6022            );
 6023            cx.background_spawn(async move {
 6024                Ok(Some(
 6025                    declarations_task
 6026                        .await
 6027                        .into_iter()
 6028                        .flat_map(|(_, declarations)| declarations)
 6029                        .dedup()
 6030                        .collect(),
 6031                ))
 6032            })
 6033        }
 6034    }
 6035
 6036    pub fn type_definitions(
 6037        &mut self,
 6038        buffer: &Entity<Buffer>,
 6039        position: PointUtf16,
 6040        cx: &mut Context<Self>,
 6041    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 6042        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6043            let request = GetTypeDefinitions { position };
 6044            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6045                return Task::ready(Ok(None));
 6046            }
 6047            let request_timeout = ProjectSettings::get_global(cx)
 6048                .global_lsp_settings
 6049                .get_request_timeout();
 6050            let request_task = upstream_client.request_lsp(
 6051                project_id,
 6052                None,
 6053                request_timeout,
 6054                cx.background_executor().clone(),
 6055                request.to_proto(project_id, buffer.read(cx)),
 6056            );
 6057            let buffer = buffer.clone();
 6058            cx.spawn(async move |weak_lsp_store, cx| {
 6059                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6060                    return Ok(None);
 6061                };
 6062                let Some(responses) = request_task.await? else {
 6063                    return Ok(None);
 6064                };
 6065                let actions = join_all(responses.payload.into_iter().map(|response| {
 6066                    GetTypeDefinitions { position }.response_from_proto(
 6067                        response.response,
 6068                        lsp_store.clone(),
 6069                        buffer.clone(),
 6070                        cx.clone(),
 6071                    )
 6072                }))
 6073                .await;
 6074
 6075                Ok(Some(
 6076                    actions
 6077                        .into_iter()
 6078                        .collect::<Result<Vec<Vec<_>>>>()?
 6079                        .into_iter()
 6080                        .flatten()
 6081                        .dedup()
 6082                        .collect(),
 6083                ))
 6084            })
 6085        } else {
 6086            let type_definitions_task = self.request_multiple_lsp_locally(
 6087                buffer,
 6088                Some(position),
 6089                GetTypeDefinitions { position },
 6090                cx,
 6091            );
 6092            cx.background_spawn(async move {
 6093                Ok(Some(
 6094                    type_definitions_task
 6095                        .await
 6096                        .into_iter()
 6097                        .flat_map(|(_, type_definitions)| type_definitions)
 6098                        .dedup()
 6099                        .collect(),
 6100                ))
 6101            })
 6102        }
 6103    }
 6104
 6105    pub fn implementations(
 6106        &mut self,
 6107        buffer: &Entity<Buffer>,
 6108        position: PointUtf16,
 6109        cx: &mut Context<Self>,
 6110    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 6111        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6112            let request = GetImplementations { position };
 6113            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6114                return Task::ready(Ok(None));
 6115            }
 6116
 6117            let request_timeout = ProjectSettings::get_global(cx)
 6118                .global_lsp_settings
 6119                .get_request_timeout();
 6120            let request_task = upstream_client.request_lsp(
 6121                project_id,
 6122                None,
 6123                request_timeout,
 6124                cx.background_executor().clone(),
 6125                request.to_proto(project_id, buffer.read(cx)),
 6126            );
 6127            let buffer = buffer.clone();
 6128            cx.spawn(async move |weak_lsp_store, cx| {
 6129                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6130                    return Ok(None);
 6131                };
 6132                let Some(responses) = request_task.await? else {
 6133                    return Ok(None);
 6134                };
 6135                let actions = join_all(responses.payload.into_iter().map(|response| {
 6136                    GetImplementations { position }.response_from_proto(
 6137                        response.response,
 6138                        lsp_store.clone(),
 6139                        buffer.clone(),
 6140                        cx.clone(),
 6141                    )
 6142                }))
 6143                .await;
 6144
 6145                Ok(Some(
 6146                    actions
 6147                        .into_iter()
 6148                        .collect::<Result<Vec<Vec<_>>>>()?
 6149                        .into_iter()
 6150                        .flatten()
 6151                        .dedup()
 6152                        .collect(),
 6153                ))
 6154            })
 6155        } else {
 6156            let implementations_task = self.request_multiple_lsp_locally(
 6157                buffer,
 6158                Some(position),
 6159                GetImplementations { position },
 6160                cx,
 6161            );
 6162            cx.background_spawn(async move {
 6163                Ok(Some(
 6164                    implementations_task
 6165                        .await
 6166                        .into_iter()
 6167                        .flat_map(|(_, implementations)| implementations)
 6168                        .dedup()
 6169                        .collect(),
 6170                ))
 6171            })
 6172        }
 6173    }
 6174
 6175    pub fn references(
 6176        &mut self,
 6177        buffer: &Entity<Buffer>,
 6178        position: PointUtf16,
 6179        cx: &mut Context<Self>,
 6180    ) -> Task<Result<Option<Vec<Location>>>> {
 6181        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6182            let request = GetReferences { position };
 6183            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6184                return Task::ready(Ok(None));
 6185            }
 6186
 6187            let request_timeout = ProjectSettings::get_global(cx)
 6188                .global_lsp_settings
 6189                .get_request_timeout();
 6190            let request_task = upstream_client.request_lsp(
 6191                project_id,
 6192                None,
 6193                request_timeout,
 6194                cx.background_executor().clone(),
 6195                request.to_proto(project_id, buffer.read(cx)),
 6196            );
 6197            let buffer = buffer.clone();
 6198            cx.spawn(async move |weak_lsp_store, cx| {
 6199                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6200                    return Ok(None);
 6201                };
 6202                let Some(responses) = request_task.await? else {
 6203                    return Ok(None);
 6204                };
 6205
 6206                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 6207                    GetReferences { position }.response_from_proto(
 6208                        lsp_response.response,
 6209                        lsp_store.clone(),
 6210                        buffer.clone(),
 6211                        cx.clone(),
 6212                    )
 6213                }))
 6214                .await
 6215                .into_iter()
 6216                .collect::<Result<Vec<Vec<_>>>>()?
 6217                .into_iter()
 6218                .flatten()
 6219                .dedup()
 6220                .collect();
 6221                Ok(Some(locations))
 6222            })
 6223        } else {
 6224            let references_task = self.request_multiple_lsp_locally(
 6225                buffer,
 6226                Some(position),
 6227                GetReferences { position },
 6228                cx,
 6229            );
 6230            cx.background_spawn(async move {
 6231                Ok(Some(
 6232                    references_task
 6233                        .await
 6234                        .into_iter()
 6235                        .flat_map(|(_, references)| references)
 6236                        .dedup()
 6237                        .collect(),
 6238                ))
 6239            })
 6240        }
 6241    }
 6242
 6243    pub fn code_actions(
 6244        &mut self,
 6245        buffer: &Entity<Buffer>,
 6246        range: Range<Anchor>,
 6247        kinds: Option<Vec<CodeActionKind>>,
 6248        cx: &mut Context<Self>,
 6249    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6250        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6251            let request = GetCodeActions {
 6252                range: range.clone(),
 6253                kinds: kinds.clone(),
 6254            };
 6255            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6256                return Task::ready(Ok(None));
 6257            }
 6258            let request_timeout = ProjectSettings::get_global(cx)
 6259                .global_lsp_settings
 6260                .get_request_timeout();
 6261            let request_task = upstream_client.request_lsp(
 6262                project_id,
 6263                None,
 6264                request_timeout,
 6265                cx.background_executor().clone(),
 6266                request.to_proto(project_id, buffer.read(cx)),
 6267            );
 6268            let buffer = buffer.clone();
 6269            cx.spawn(async move |weak_lsp_store, cx| {
 6270                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6271                    return Ok(None);
 6272                };
 6273                let Some(responses) = request_task.await? else {
 6274                    return Ok(None);
 6275                };
 6276                let actions = join_all(responses.payload.into_iter().map(|response| {
 6277                    GetCodeActions {
 6278                        range: range.clone(),
 6279                        kinds: kinds.clone(),
 6280                    }
 6281                    .response_from_proto(
 6282                        response.response,
 6283                        lsp_store.clone(),
 6284                        buffer.clone(),
 6285                        cx.clone(),
 6286                    )
 6287                }))
 6288                .await;
 6289
 6290                Ok(Some(
 6291                    actions
 6292                        .into_iter()
 6293                        .collect::<Result<Vec<Vec<_>>>>()?
 6294                        .into_iter()
 6295                        .flatten()
 6296                        .collect(),
 6297                ))
 6298            })
 6299        } else {
 6300            let all_actions_task = self.request_multiple_lsp_locally(
 6301                buffer,
 6302                Some(range.start),
 6303                GetCodeActions { range, kinds },
 6304                cx,
 6305            );
 6306            cx.background_spawn(async move {
 6307                Ok(Some(
 6308                    all_actions_task
 6309                        .await
 6310                        .into_iter()
 6311                        .flat_map(|(_, actions)| actions)
 6312                        .collect(),
 6313                ))
 6314            })
 6315        }
 6316    }
 6317
 6318    #[inline(never)]
 6319    pub fn completions(
 6320        &self,
 6321        buffer: &Entity<Buffer>,
 6322        position: PointUtf16,
 6323        context: CompletionContext,
 6324        cx: &mut Context<Self>,
 6325    ) -> Task<Result<Vec<CompletionResponse>>> {
 6326        let language_registry = self.languages.clone();
 6327
 6328        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6329            let snapshot = buffer.read(cx).snapshot();
 6330            let offset = position.to_offset(&snapshot);
 6331            let scope = snapshot.language_scope_at(offset);
 6332            let capable_lsps = self.all_capable_for_proto_request(
 6333                buffer,
 6334                |server_name, capabilities| {
 6335                    capabilities.completion_provider.is_some()
 6336                        && scope
 6337                            .as_ref()
 6338                            .map(|scope| scope.language_allowed(server_name))
 6339                            .unwrap_or(true)
 6340                },
 6341                cx,
 6342            );
 6343            if capable_lsps.is_empty() {
 6344                return Task::ready(Ok(Vec::new()));
 6345            }
 6346
 6347            let language = buffer.read(cx).language().cloned();
 6348
 6349            let buffer = buffer.clone();
 6350
 6351            cx.spawn(async move |this, cx| {
 6352                let requests = join_all(
 6353                    capable_lsps
 6354                        .into_iter()
 6355                        .map(|(id, server_name)| {
 6356                            let request = GetCompletions {
 6357                                position,
 6358                                context: context.clone(),
 6359                                server_id: Some(id),
 6360                            };
 6361                            let buffer = buffer.clone();
 6362                            let language = language.clone();
 6363                            let lsp_adapter = language.as_ref().and_then(|language| {
 6364                                let adapters = language_registry.lsp_adapters(&language.name());
 6365                                adapters
 6366                                    .iter()
 6367                                    .find(|adapter| adapter.name() == server_name)
 6368                                    .or_else(|| adapters.first())
 6369                                    .cloned()
 6370                            });
 6371                            let upstream_client = upstream_client.clone();
 6372                            let response = this
 6373                                .update(cx, |this, cx| {
 6374                                    this.send_lsp_proto_request(
 6375                                        buffer,
 6376                                        upstream_client,
 6377                                        project_id,
 6378                                        request,
 6379                                        cx,
 6380                                    )
 6381                                })
 6382                                .log_err();
 6383                            async move {
 6384                                let response = response?.await.log_err()?;
 6385
 6386                                let completions = populate_labels_for_completions(
 6387                                    response.completions,
 6388                                    language,
 6389                                    lsp_adapter,
 6390                                )
 6391                                .await;
 6392
 6393                                Some(CompletionResponse {
 6394                                    completions,
 6395                                    display_options: CompletionDisplayOptions::default(),
 6396                                    is_incomplete: response.is_incomplete,
 6397                                })
 6398                            }
 6399                        })
 6400                        .collect::<Vec<_>>(),
 6401                );
 6402                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6403            })
 6404        } else if let Some(local) = self.as_local() {
 6405            let snapshot = buffer.read(cx).snapshot();
 6406            let offset = position.to_offset(&snapshot);
 6407            let scope = snapshot.language_scope_at(offset);
 6408            let language = snapshot.language().cloned();
 6409            let completion_settings = LanguageSettings::for_buffer(&buffer.read(cx), cx)
 6410                .completions
 6411                .clone();
 6412            if !completion_settings.lsp {
 6413                return Task::ready(Ok(Vec::new()));
 6414            }
 6415
 6416            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6417                local
 6418                    .language_servers_for_buffer(buffer, cx)
 6419                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6420                    .filter(|(adapter, _)| {
 6421                        scope
 6422                            .as_ref()
 6423                            .map(|scope| scope.language_allowed(&adapter.name))
 6424                            .unwrap_or(true)
 6425                    })
 6426                    .map(|(_, server)| server.server_id())
 6427                    .collect()
 6428            });
 6429
 6430            let buffer = buffer.clone();
 6431            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6432            let lsp_timeout = if lsp_timeout > 0 {
 6433                Some(Duration::from_millis(lsp_timeout))
 6434            } else {
 6435                None
 6436            };
 6437            cx.spawn(async move |this,  cx| {
 6438                let mut tasks = Vec::with_capacity(server_ids.len());
 6439                this.update(cx, |lsp_store, cx| {
 6440                    for server_id in server_ids {
 6441                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6442                        let lsp_timeout = lsp_timeout
 6443                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6444                        let mut timeout = cx.background_spawn(async move {
 6445                            match lsp_timeout {
 6446                                Some(lsp_timeout) => {
 6447                                    lsp_timeout.await;
 6448                                    true
 6449                                },
 6450                                None => false,
 6451                            }
 6452                        }).fuse();
 6453                        let mut lsp_request = lsp_store.request_lsp(
 6454                            buffer.clone(),
 6455                            LanguageServerToQuery::Other(server_id),
 6456                            GetCompletions {
 6457                                position,
 6458                                context: context.clone(),
 6459                                server_id: Some(server_id),
 6460                            },
 6461                            cx,
 6462                        ).fuse();
 6463                        let new_task = cx.background_spawn(async move {
 6464                            select_biased! {
 6465                                response = lsp_request => anyhow::Ok(Some(response?)),
 6466                                timeout_happened = timeout => {
 6467                                    if timeout_happened {
 6468                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6469                                        Ok(None)
 6470                                    } else {
 6471                                        let completions = lsp_request.await?;
 6472                                        Ok(Some(completions))
 6473                                    }
 6474                                },
 6475                            }
 6476                        });
 6477                        tasks.push((lsp_adapter, new_task));
 6478                    }
 6479                })?;
 6480
 6481                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6482                    let completion_response = task.await.ok()??;
 6483                    let completions = populate_labels_for_completions(
 6484                            completion_response.completions,
 6485                            language.clone(),
 6486                            lsp_adapter,
 6487                        )
 6488                        .await;
 6489                    Some(CompletionResponse {
 6490                        completions,
 6491                        display_options: CompletionDisplayOptions::default(),
 6492                        is_incomplete: completion_response.is_incomplete,
 6493                    })
 6494                });
 6495
 6496                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6497
 6498                Ok(responses.into_iter().flatten().collect())
 6499            })
 6500        } else {
 6501            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6502        }
 6503    }
 6504
 6505    pub fn resolve_completions(
 6506        &self,
 6507        buffer: Entity<Buffer>,
 6508        completion_indices: Vec<usize>,
 6509        completions: Rc<RefCell<Box<[Completion]>>>,
 6510        cx: &mut Context<Self>,
 6511    ) -> Task<Result<bool>> {
 6512        let client = self.upstream_client();
 6513        let buffer_id = buffer.read(cx).remote_id();
 6514        let buffer_snapshot = buffer.read(cx).snapshot();
 6515
 6516        if !self.check_if_capable_for_proto_request(
 6517            &buffer,
 6518            GetCompletions::can_resolve_completions,
 6519            cx,
 6520        ) {
 6521            return Task::ready(Ok(false));
 6522        }
 6523        cx.spawn(async move |lsp_store, cx| {
 6524            let request_timeout = cx.update(|app| {
 6525                ProjectSettings::get_global(app)
 6526                    .global_lsp_settings
 6527                    .get_request_timeout()
 6528            });
 6529
 6530            let mut did_resolve = false;
 6531            if let Some((client, project_id)) = client {
 6532                for completion_index in completion_indices {
 6533                    let server_id = {
 6534                        let completion = &completions.borrow()[completion_index];
 6535                        completion.source.server_id()
 6536                    };
 6537                    if let Some(server_id) = server_id {
 6538                        if Self::resolve_completion_remote(
 6539                            project_id,
 6540                            server_id,
 6541                            buffer_id,
 6542                            completions.clone(),
 6543                            completion_index,
 6544                            client.clone(),
 6545                        )
 6546                        .await
 6547                        .log_err()
 6548                        .is_some()
 6549                        {
 6550                            did_resolve = true;
 6551                        }
 6552                    } else {
 6553                        resolve_word_completion(
 6554                            &buffer_snapshot,
 6555                            &mut completions.borrow_mut()[completion_index],
 6556                        );
 6557                    }
 6558                }
 6559            } else {
 6560                for completion_index in completion_indices {
 6561                    let server_id = {
 6562                        let completion = &completions.borrow()[completion_index];
 6563                        completion.source.server_id()
 6564                    };
 6565                    if let Some(server_id) = server_id {
 6566                        let server_and_adapter = lsp_store
 6567                            .read_with(cx, |lsp_store, _| {
 6568                                let server = lsp_store.language_server_for_id(server_id)?;
 6569                                let adapter =
 6570                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6571                                Some((server, adapter))
 6572                            })
 6573                            .ok()
 6574                            .flatten();
 6575                        let Some((server, adapter)) = server_and_adapter else {
 6576                            continue;
 6577                        };
 6578
 6579                        let resolved = Self::resolve_completion_local(
 6580                            server,
 6581                            completions.clone(),
 6582                            completion_index,
 6583                            request_timeout,
 6584                        )
 6585                        .await
 6586                        .log_err()
 6587                        .is_some();
 6588                        if resolved {
 6589                            Self::regenerate_completion_labels(
 6590                                adapter,
 6591                                &buffer_snapshot,
 6592                                completions.clone(),
 6593                                completion_index,
 6594                            )
 6595                            .await
 6596                            .log_err();
 6597                            did_resolve = true;
 6598                        }
 6599                    } else {
 6600                        resolve_word_completion(
 6601                            &buffer_snapshot,
 6602                            &mut completions.borrow_mut()[completion_index],
 6603                        );
 6604                    }
 6605                }
 6606            }
 6607
 6608            Ok(did_resolve)
 6609        })
 6610    }
 6611
 6612    async fn resolve_completion_local(
 6613        server: Arc<lsp::LanguageServer>,
 6614        completions: Rc<RefCell<Box<[Completion]>>>,
 6615        completion_index: usize,
 6616        request_timeout: Duration,
 6617    ) -> Result<()> {
 6618        let server_id = server.server_id();
 6619        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6620            return Ok(());
 6621        }
 6622
 6623        let request = {
 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                    if *resolved {
 6633                        return Ok(());
 6634                    }
 6635                    anyhow::ensure!(
 6636                        server_id == *completion_server_id,
 6637                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6638                    );
 6639                    server.request::<lsp::request::ResolveCompletionItem>(
 6640                        *lsp_completion.clone(),
 6641                        request_timeout,
 6642                    )
 6643                }
 6644                CompletionSource::BufferWord { .. }
 6645                | CompletionSource::Dap { .. }
 6646                | CompletionSource::Custom => {
 6647                    return Ok(());
 6648                }
 6649            }
 6650        };
 6651        let resolved_completion = request
 6652            .await
 6653            .into_response()
 6654            .context("resolve completion")?;
 6655
 6656        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6657        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6658
 6659        let mut completions = completions.borrow_mut();
 6660        let completion = &mut completions[completion_index];
 6661        if let CompletionSource::Lsp {
 6662            lsp_completion,
 6663            resolved,
 6664            server_id: completion_server_id,
 6665            ..
 6666        } = &mut completion.source
 6667        {
 6668            if *resolved {
 6669                return Ok(());
 6670            }
 6671            anyhow::ensure!(
 6672                server_id == *completion_server_id,
 6673                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6674            );
 6675            **lsp_completion = resolved_completion;
 6676            *resolved = true;
 6677        }
 6678        Ok(())
 6679    }
 6680
 6681    async fn regenerate_completion_labels(
 6682        adapter: Arc<CachedLspAdapter>,
 6683        snapshot: &BufferSnapshot,
 6684        completions: Rc<RefCell<Box<[Completion]>>>,
 6685        completion_index: usize,
 6686    ) -> Result<()> {
 6687        let completion_item = completions.borrow()[completion_index]
 6688            .source
 6689            .lsp_completion(true)
 6690            .map(Cow::into_owned);
 6691        if let Some(lsp_documentation) = completion_item
 6692            .as_ref()
 6693            .and_then(|completion_item| completion_item.documentation.clone())
 6694        {
 6695            let mut completions = completions.borrow_mut();
 6696            let completion = &mut completions[completion_index];
 6697            completion.documentation = Some(lsp_documentation.into());
 6698        } else {
 6699            let mut completions = completions.borrow_mut();
 6700            let completion = &mut completions[completion_index];
 6701            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6702        }
 6703
 6704        let mut new_label = match completion_item {
 6705            Some(completion_item) => {
 6706                // Some language servers always return `detail` lazily via resolve, regardless of
 6707                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6708                // See: https://github.com/yioneko/vtsls/issues/213
 6709                let language = snapshot.language();
 6710                match language {
 6711                    Some(language) => {
 6712                        adapter
 6713                            .labels_for_completions(
 6714                                std::slice::from_ref(&completion_item),
 6715                                language,
 6716                            )
 6717                            .await?
 6718                    }
 6719                    None => Vec::new(),
 6720                }
 6721                .pop()
 6722                .flatten()
 6723                .unwrap_or_else(|| {
 6724                    CodeLabel::fallback_for_completion(
 6725                        &completion_item,
 6726                        language.map(|language| language.as_ref()),
 6727                    )
 6728                })
 6729            }
 6730            None => CodeLabel::plain(
 6731                completions.borrow()[completion_index].new_text.clone(),
 6732                None,
 6733            ),
 6734        };
 6735        ensure_uniform_list_compatible_label(&mut new_label);
 6736
 6737        let mut completions = completions.borrow_mut();
 6738        let completion = &mut completions[completion_index];
 6739        if completion.label.filter_text() == new_label.filter_text() {
 6740            completion.label = new_label;
 6741        } else {
 6742            log::error!(
 6743                "Resolved completion changed display label from {} to {}. \
 6744                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6745                completion.label.text(),
 6746                new_label.text(),
 6747                completion.label.filter_text(),
 6748                new_label.filter_text()
 6749            );
 6750        }
 6751
 6752        Ok(())
 6753    }
 6754
 6755    async fn resolve_completion_remote(
 6756        project_id: u64,
 6757        server_id: LanguageServerId,
 6758        buffer_id: BufferId,
 6759        completions: Rc<RefCell<Box<[Completion]>>>,
 6760        completion_index: usize,
 6761        client: AnyProtoClient,
 6762    ) -> Result<()> {
 6763        let lsp_completion = {
 6764            let completion = &completions.borrow()[completion_index];
 6765            match &completion.source {
 6766                CompletionSource::Lsp {
 6767                    lsp_completion,
 6768                    resolved,
 6769                    server_id: completion_server_id,
 6770                    ..
 6771                } => {
 6772                    anyhow::ensure!(
 6773                        server_id == *completion_server_id,
 6774                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6775                    );
 6776                    if *resolved {
 6777                        return Ok(());
 6778                    }
 6779                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6780                }
 6781                CompletionSource::Custom
 6782                | CompletionSource::Dap { .. }
 6783                | CompletionSource::BufferWord { .. } => {
 6784                    return Ok(());
 6785                }
 6786            }
 6787        };
 6788        let request = proto::ResolveCompletionDocumentation {
 6789            project_id,
 6790            language_server_id: server_id.0 as u64,
 6791            lsp_completion,
 6792            buffer_id: buffer_id.into(),
 6793        };
 6794
 6795        let response = client
 6796            .request(request)
 6797            .await
 6798            .context("completion documentation resolve proto request")?;
 6799        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6800
 6801        let documentation = if response.documentation.is_empty() {
 6802            CompletionDocumentation::Undocumented
 6803        } else if response.documentation_is_markdown {
 6804            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6805        } else if response.documentation.lines().count() <= 1 {
 6806            CompletionDocumentation::SingleLine(response.documentation.into())
 6807        } else {
 6808            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6809        };
 6810
 6811        let mut completions = completions.borrow_mut();
 6812        let completion = &mut completions[completion_index];
 6813        completion.documentation = Some(documentation);
 6814        if let CompletionSource::Lsp {
 6815            insert_range,
 6816            lsp_completion,
 6817            resolved,
 6818            server_id: completion_server_id,
 6819            lsp_defaults: _,
 6820        } = &mut completion.source
 6821        {
 6822            let completion_insert_range = response
 6823                .old_insert_start
 6824                .and_then(deserialize_anchor)
 6825                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6826            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6827
 6828            if *resolved {
 6829                return Ok(());
 6830            }
 6831            anyhow::ensure!(
 6832                server_id == *completion_server_id,
 6833                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6834            );
 6835            **lsp_completion = resolved_lsp_completion;
 6836            *resolved = true;
 6837        }
 6838
 6839        let replace_range = response
 6840            .old_replace_start
 6841            .and_then(deserialize_anchor)
 6842            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6843        if let Some((old_replace_start, old_replace_end)) = replace_range
 6844            && !response.new_text.is_empty()
 6845        {
 6846            completion.new_text = response.new_text;
 6847            completion.replace_range = old_replace_start..old_replace_end;
 6848        }
 6849
 6850        Ok(())
 6851    }
 6852
 6853    pub fn apply_additional_edits_for_completion(
 6854        &self,
 6855        buffer_handle: Entity<Buffer>,
 6856        completions: Rc<RefCell<Box<[Completion]>>>,
 6857        completion_index: usize,
 6858        push_to_history: bool,
 6859        all_commit_ranges: Vec<Range<language::Anchor>>,
 6860        cx: &mut Context<Self>,
 6861    ) -> Task<Result<Option<Transaction>>> {
 6862        if let Some((client, project_id)) = self.upstream_client() {
 6863            let buffer = buffer_handle.read(cx);
 6864            let buffer_id = buffer.remote_id();
 6865            cx.spawn(async move |_, cx| {
 6866                let request = {
 6867                    let completion = completions.borrow()[completion_index].clone();
 6868                    proto::ApplyCompletionAdditionalEdits {
 6869                        project_id,
 6870                        buffer_id: buffer_id.into(),
 6871                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6872                            replace_range: completion.replace_range,
 6873                            new_text: completion.new_text,
 6874                            source: completion.source,
 6875                        })),
 6876                        all_commit_ranges: all_commit_ranges
 6877                            .iter()
 6878                            .cloned()
 6879                            .map(language::proto::serialize_anchor_range)
 6880                            .collect(),
 6881                    }
 6882                };
 6883
 6884                let Some(transaction) = client.request(request).await?.transaction else {
 6885                    return Ok(None);
 6886                };
 6887
 6888                let transaction = language::proto::deserialize_transaction(transaction)?;
 6889                buffer_handle
 6890                    .update(cx, |buffer, _| {
 6891                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6892                    })
 6893                    .await?;
 6894                if push_to_history {
 6895                    buffer_handle.update(cx, |buffer, _| {
 6896                        buffer.push_transaction(transaction.clone(), Instant::now());
 6897                        buffer.finalize_last_transaction();
 6898                    });
 6899                }
 6900                Ok(Some(transaction))
 6901            })
 6902        } else {
 6903            let request_timeout = ProjectSettings::get_global(cx)
 6904                .global_lsp_settings
 6905                .get_request_timeout();
 6906
 6907            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6908                let completion = &completions.borrow()[completion_index];
 6909                let server_id = completion.source.server_id()?;
 6910                Some(
 6911                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6912                        .1
 6913                        .clone(),
 6914                )
 6915            }) else {
 6916                return Task::ready(Ok(None));
 6917            };
 6918
 6919            cx.spawn(async move |this, cx| {
 6920                Self::resolve_completion_local(
 6921                    server.clone(),
 6922                    completions.clone(),
 6923                    completion_index,
 6924                    request_timeout,
 6925                )
 6926                .await
 6927                .context("resolving completion")?;
 6928                let completion = completions.borrow()[completion_index].clone();
 6929                let additional_text_edits = completion
 6930                    .source
 6931                    .lsp_completion(true)
 6932                    .as_ref()
 6933                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6934                if let Some(edits) = additional_text_edits {
 6935                    let edits = this
 6936                        .update(cx, |this, cx| {
 6937                            this.as_local_mut().unwrap().edits_from_lsp(
 6938                                &buffer_handle,
 6939                                edits,
 6940                                server.server_id(),
 6941                                None,
 6942                                cx,
 6943                            )
 6944                        })?
 6945                        .await?;
 6946
 6947                    buffer_handle.update(cx, |buffer, cx| {
 6948                        buffer.finalize_last_transaction();
 6949                        buffer.start_transaction();
 6950
 6951                        for (range, text) in edits {
 6952                            let primary = &completion.replace_range;
 6953
 6954                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6955                            // and the primary completion is just an insertion (empty range), then this is likely
 6956                            // an auto-import scenario and should not be considered overlapping
 6957                            // https://github.com/zed-industries/zed/issues/26136
 6958                            let is_file_start_auto_import = {
 6959                                let snapshot = buffer.snapshot();
 6960                                let primary_start_point = primary.start.to_point(&snapshot);
 6961                                let range_start_point = range.start.to_point(&snapshot);
 6962
 6963                                let result = primary_start_point.row == 0
 6964                                    && primary_start_point.column == 0
 6965                                    && range_start_point.row == 0
 6966                                    && range_start_point.column == 0;
 6967
 6968                                result
 6969                            };
 6970
 6971                            let has_overlap = if is_file_start_auto_import {
 6972                                false
 6973                            } else {
 6974                                all_commit_ranges.iter().any(|commit_range| {
 6975                                    let start_within =
 6976                                        commit_range.start.cmp(&range.start, buffer).is_le()
 6977                                            && commit_range.end.cmp(&range.start, buffer).is_ge();
 6978                                    let end_within =
 6979                                        range.start.cmp(&commit_range.end, buffer).is_le()
 6980                                            && range.end.cmp(&commit_range.end, buffer).is_ge();
 6981                                    start_within || end_within
 6982                                })
 6983                            };
 6984
 6985                            //Skip additional edits which overlap with the primary completion edit
 6986                            //https://github.com/zed-industries/zed/pull/1871
 6987                            if !has_overlap {
 6988                                buffer.edit([(range, text)], None, cx);
 6989                            }
 6990                        }
 6991
 6992                        let transaction = if buffer.end_transaction(cx).is_some() {
 6993                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6994                            if !push_to_history {
 6995                                buffer.forget_transaction(transaction.id);
 6996                            }
 6997                            Some(transaction)
 6998                        } else {
 6999                            None
 7000                        };
 7001                        Ok(transaction)
 7002                    })
 7003                } else {
 7004                    Ok(None)
 7005                }
 7006            })
 7007        }
 7008    }
 7009
 7010    pub fn pull_diagnostics(
 7011        &mut self,
 7012        buffer: Entity<Buffer>,
 7013        cx: &mut Context<Self>,
 7014    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 7015        let buffer_id = buffer.read(cx).remote_id();
 7016
 7017        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7018            let mut suitable_capabilities = None;
 7019            // Are we capable for proto request?
 7020            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 7021                &buffer,
 7022                |capabilities| {
 7023                    if let Some(caps) = &capabilities.diagnostic_provider {
 7024                        suitable_capabilities = Some(caps.clone());
 7025                        true
 7026                    } else {
 7027                        false
 7028                    }
 7029                },
 7030                cx,
 7031            );
 7032            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 7033            let Some(dynamic_caps) = suitable_capabilities else {
 7034                return Task::ready(Ok(None));
 7035            };
 7036            assert!(any_server_has_diagnostics_provider);
 7037
 7038            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 7039            let request = GetDocumentDiagnostics {
 7040                previous_result_id: None,
 7041                identifier,
 7042                registration_id: None,
 7043            };
 7044            let request_timeout = ProjectSettings::get_global(cx)
 7045                .global_lsp_settings
 7046                .get_request_timeout();
 7047            let request_task = client.request_lsp(
 7048                upstream_project_id,
 7049                None,
 7050                request_timeout,
 7051                cx.background_executor().clone(),
 7052                request.to_proto(upstream_project_id, buffer.read(cx)),
 7053            );
 7054            cx.background_spawn(async move {
 7055                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 7056                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 7057                // Do not attempt to further process the dummy responses here.
 7058                let _response = request_task.await?;
 7059                Ok(None)
 7060            })
 7061        } else {
 7062            let servers = buffer.update(cx, |buffer, cx| {
 7063                self.running_language_servers_for_local_buffer(buffer, cx)
 7064                    .map(|(_, server)| server.clone())
 7065                    .collect::<Vec<_>>()
 7066            });
 7067
 7068            let pull_diagnostics = servers
 7069                .into_iter()
 7070                .flat_map(|server| {
 7071                    let result = maybe!({
 7072                        let local = self.as_local()?;
 7073                        let server_id = server.server_id();
 7074                        let providers_with_identifiers = local
 7075                            .language_server_dynamic_registrations
 7076                            .get(&server_id)
 7077                            .into_iter()
 7078                            .flat_map(|registrations| registrations.diagnostics.clone())
 7079                            .collect::<Vec<_>>();
 7080                        Some(
 7081                            providers_with_identifiers
 7082                                .into_iter()
 7083                                .map(|(registration_id, dynamic_caps)| {
 7084                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 7085                                    let registration_id = registration_id.map(SharedString::from);
 7086                                    let result_id = self.result_id_for_buffer_pull(
 7087                                        server_id,
 7088                                        buffer_id,
 7089                                        &registration_id,
 7090                                        cx,
 7091                                    );
 7092                                    self.request_lsp(
 7093                                        buffer.clone(),
 7094                                        LanguageServerToQuery::Other(server_id),
 7095                                        GetDocumentDiagnostics {
 7096                                            previous_result_id: result_id,
 7097                                            registration_id,
 7098                                            identifier,
 7099                                        },
 7100                                        cx,
 7101                                    )
 7102                                })
 7103                                .collect::<Vec<_>>(),
 7104                        )
 7105                    });
 7106
 7107                    result.unwrap_or_default()
 7108                })
 7109                .collect::<Vec<_>>();
 7110
 7111            cx.background_spawn(async move {
 7112                let mut responses = Vec::new();
 7113                for diagnostics in join_all(pull_diagnostics).await {
 7114                    responses.extend(diagnostics?);
 7115                }
 7116                Ok(Some(responses))
 7117            })
 7118        }
 7119    }
 7120
 7121    pub fn applicable_inlay_chunks(
 7122        &mut self,
 7123        buffer: &Entity<Buffer>,
 7124        ranges: &[Range<text::Anchor>],
 7125        cx: &mut Context<Self>,
 7126    ) -> Vec<Range<BufferRow>> {
 7127        let buffer_snapshot = buffer.read(cx).snapshot();
 7128        let ranges = ranges
 7129            .iter()
 7130            .map(|range| range.to_point(&buffer_snapshot))
 7131            .collect::<Vec<_>>();
 7132
 7133        self.latest_lsp_data(buffer, cx)
 7134            .inlay_hints
 7135            .applicable_chunks(ranges.as_slice())
 7136            .map(|chunk| chunk.row_range())
 7137            .collect()
 7138    }
 7139
 7140    pub fn invalidate_inlay_hints<'a>(
 7141        &'a mut self,
 7142        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 7143    ) {
 7144        for buffer_id in for_buffers {
 7145            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 7146                lsp_data.inlay_hints.clear();
 7147            }
 7148        }
 7149    }
 7150
 7151    pub fn inlay_hints(
 7152        &mut self,
 7153        invalidate: InvalidationStrategy,
 7154        buffer: Entity<Buffer>,
 7155        ranges: Vec<Range<text::Anchor>>,
 7156        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 7157        cx: &mut Context<Self>,
 7158    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 7159        let next_hint_id = self.next_hint_id.clone();
 7160        let lsp_data = self.latest_lsp_data(&buffer, cx);
 7161        let query_version = lsp_data.buffer_version.clone();
 7162        let mut lsp_refresh_requested = false;
 7163        let for_server = if let InvalidationStrategy::RefreshRequested {
 7164            server_id,
 7165            request_id,
 7166        } = invalidate
 7167        {
 7168            let invalidated = lsp_data
 7169                .inlay_hints
 7170                .invalidate_for_server_refresh(server_id, request_id);
 7171            lsp_refresh_requested = invalidated;
 7172            Some(server_id)
 7173        } else {
 7174            None
 7175        };
 7176        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 7177        let known_chunks = known_chunks
 7178            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 7179            .map(|(_, known_chunks)| known_chunks)
 7180            .unwrap_or_default();
 7181
 7182        let buffer_snapshot = buffer.read(cx).snapshot();
 7183        let ranges = ranges
 7184            .iter()
 7185            .map(|range| range.to_point(&buffer_snapshot))
 7186            .collect::<Vec<_>>();
 7187
 7188        let mut hint_fetch_tasks = Vec::new();
 7189        let mut cached_inlay_hints = None;
 7190        let mut ranges_to_query = None;
 7191        let applicable_chunks = existing_inlay_hints
 7192            .applicable_chunks(ranges.as_slice())
 7193            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7194            .collect::<Vec<_>>();
 7195        if applicable_chunks.is_empty() {
 7196            return HashMap::default();
 7197        }
 7198
 7199        for row_chunk in applicable_chunks {
 7200            match (
 7201                existing_inlay_hints
 7202                    .cached_hints(&row_chunk)
 7203                    .filter(|_| !lsp_refresh_requested)
 7204                    .cloned(),
 7205                existing_inlay_hints
 7206                    .fetched_hints(&row_chunk)
 7207                    .as_ref()
 7208                    .filter(|_| !lsp_refresh_requested)
 7209                    .cloned(),
 7210            ) {
 7211                (None, None) => {
 7212                    let chunk_range = row_chunk.anchor_range();
 7213                    ranges_to_query
 7214                        .get_or_insert_with(Vec::new)
 7215                        .push((row_chunk, chunk_range));
 7216                }
 7217                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7218                (Some(cached_hints), None) => {
 7219                    for (server_id, cached_hints) in cached_hints {
 7220                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7221                            cached_inlay_hints
 7222                                .get_or_insert_with(HashMap::default)
 7223                                .entry(row_chunk.row_range())
 7224                                .or_insert_with(HashMap::default)
 7225                                .entry(server_id)
 7226                                .or_insert_with(Vec::new)
 7227                                .extend(cached_hints);
 7228                        }
 7229                    }
 7230                }
 7231                (Some(cached_hints), Some(fetched_hints)) => {
 7232                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7233                    for (server_id, cached_hints) in cached_hints {
 7234                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7235                            cached_inlay_hints
 7236                                .get_or_insert_with(HashMap::default)
 7237                                .entry(row_chunk.row_range())
 7238                                .or_insert_with(HashMap::default)
 7239                                .entry(server_id)
 7240                                .or_insert_with(Vec::new)
 7241                                .extend(cached_hints);
 7242                        }
 7243                    }
 7244                }
 7245            }
 7246        }
 7247
 7248        if hint_fetch_tasks.is_empty()
 7249            && ranges_to_query
 7250                .as_ref()
 7251                .is_none_or(|ranges| ranges.is_empty())
 7252            && let Some(cached_inlay_hints) = cached_inlay_hints
 7253        {
 7254            cached_inlay_hints
 7255                .into_iter()
 7256                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7257                .collect()
 7258        } else {
 7259            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7260                // When a server refresh was requested, other servers' cached hints
 7261                // are unaffected by the refresh and must be included in the result.
 7262                // Otherwise apply_fetched_hints (with should_invalidate()=true)
 7263                // removes all visible hints but only adds back the requesting
 7264                // server's new hints, permanently losing other servers' hints.
 7265                let other_servers_cached: CacheInlayHints = if lsp_refresh_requested {
 7266                    lsp_data
 7267                        .inlay_hints
 7268                        .cached_hints(&chunk)
 7269                        .cloned()
 7270                        .unwrap_or_default()
 7271                } else {
 7272                    HashMap::default()
 7273                };
 7274
 7275                let next_hint_id = next_hint_id.clone();
 7276                let buffer = buffer.clone();
 7277                let query_version = query_version.clone();
 7278                let new_inlay_hints = cx
 7279                    .spawn(async move |lsp_store, cx| {
 7280                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7281                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7282                        })?;
 7283                        new_fetch_task
 7284                            .await
 7285                            .and_then(|new_hints_by_server| {
 7286                                lsp_store.update(cx, |lsp_store, cx| {
 7287                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7288                                    let update_cache = lsp_data.buffer_version == query_version;
 7289                                    if new_hints_by_server.is_empty() {
 7290                                        if update_cache {
 7291                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7292                                        }
 7293                                        other_servers_cached
 7294                                    } else {
 7295                                        let mut result = other_servers_cached;
 7296                                        for (server_id, new_hints) in new_hints_by_server {
 7297                                            let new_hints = new_hints
 7298                                                .into_iter()
 7299                                                .map(|new_hint| {
 7300                                                    (
 7301                                                        InlayId::Hint(next_hint_id.fetch_add(
 7302                                                            1,
 7303                                                            atomic::Ordering::AcqRel,
 7304                                                        )),
 7305                                                        new_hint,
 7306                                                    )
 7307                                                })
 7308                                                .collect::<Vec<_>>();
 7309                                            if update_cache {
 7310                                                lsp_data.inlay_hints.insert_new_hints(
 7311                                                    chunk,
 7312                                                    server_id,
 7313                                                    new_hints.clone(),
 7314                                                );
 7315                                            }
 7316                                            result.insert(server_id, new_hints);
 7317                                        }
 7318                                        result
 7319                                    }
 7320                                })
 7321                            })
 7322                            .map_err(Arc::new)
 7323                    })
 7324                    .shared();
 7325
 7326                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7327                *fetch_task = Some(new_inlay_hints.clone());
 7328                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7329            }
 7330
 7331            cached_inlay_hints
 7332                .unwrap_or_default()
 7333                .into_iter()
 7334                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7335                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7336                    (
 7337                        chunk.row_range(),
 7338                        cx.spawn(async move |_, _| {
 7339                            hints_fetch.await.map_err(|e| {
 7340                                if e.error_code() != ErrorCode::Internal {
 7341                                    anyhow!(e.error_code())
 7342                                } else {
 7343                                    anyhow!("{e:#}")
 7344                                }
 7345                            })
 7346                        }),
 7347                    )
 7348                }))
 7349                .collect()
 7350        }
 7351    }
 7352
 7353    fn fetch_inlay_hints(
 7354        &mut self,
 7355        for_server: Option<LanguageServerId>,
 7356        buffer: &Entity<Buffer>,
 7357        range: Range<Anchor>,
 7358        cx: &mut Context<Self>,
 7359    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7360        let request = InlayHints {
 7361            range: range.clone(),
 7362        };
 7363        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7364            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7365                return Task::ready(Ok(HashMap::default()));
 7366            }
 7367            let request_timeout = ProjectSettings::get_global(cx)
 7368                .global_lsp_settings
 7369                .get_request_timeout();
 7370            let request_task = upstream_client.request_lsp(
 7371                project_id,
 7372                for_server.map(|id| id.to_proto()),
 7373                request_timeout,
 7374                cx.background_executor().clone(),
 7375                request.to_proto(project_id, buffer.read(cx)),
 7376            );
 7377            let buffer = buffer.clone();
 7378            cx.spawn(async move |weak_lsp_store, cx| {
 7379                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7380                    return Ok(HashMap::default());
 7381                };
 7382                let Some(responses) = request_task.await? else {
 7383                    return Ok(HashMap::default());
 7384                };
 7385
 7386                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7387                    let lsp_store = lsp_store.clone();
 7388                    let buffer = buffer.clone();
 7389                    let cx = cx.clone();
 7390                    let request = request.clone();
 7391                    async move {
 7392                        (
 7393                            LanguageServerId::from_proto(response.server_id),
 7394                            request
 7395                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7396                                .await,
 7397                        )
 7398                    }
 7399                }))
 7400                .await;
 7401
 7402                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7403                let mut has_errors = false;
 7404                let inlay_hints = inlay_hints
 7405                    .into_iter()
 7406                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7407                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7408                        Err(e) => {
 7409                            has_errors = true;
 7410                            log::error!("{e:#}");
 7411                            None
 7412                        }
 7413                    })
 7414                    .map(|(server_id, mut new_hints)| {
 7415                        new_hints.retain(|hint| {
 7416                            hint.position.is_valid(&buffer_snapshot)
 7417                                && range.start.is_valid(&buffer_snapshot)
 7418                                && range.end.is_valid(&buffer_snapshot)
 7419                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7420                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7421                        });
 7422                        (server_id, new_hints)
 7423                    })
 7424                    .collect::<HashMap<_, _>>();
 7425                anyhow::ensure!(
 7426                    !has_errors || !inlay_hints.is_empty(),
 7427                    "Failed to fetch inlay hints"
 7428                );
 7429                Ok(inlay_hints)
 7430            })
 7431        } else {
 7432            let inlay_hints_task = match for_server {
 7433                Some(server_id) => {
 7434                    let server_task = self.request_lsp(
 7435                        buffer.clone(),
 7436                        LanguageServerToQuery::Other(server_id),
 7437                        request,
 7438                        cx,
 7439                    );
 7440                    cx.background_spawn(async move {
 7441                        let mut responses = Vec::new();
 7442                        match server_task.await {
 7443                            Ok(response) => responses.push((server_id, response)),
 7444                            // rust-analyzer likes to error with this when its still loading up
 7445                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7446                            Err(e) => log::error!(
 7447                                "Error handling response for inlay hints request: {e:#}"
 7448                            ),
 7449                        }
 7450                        responses
 7451                    })
 7452                }
 7453                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7454            };
 7455            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7456            cx.background_spawn(async move {
 7457                Ok(inlay_hints_task
 7458                    .await
 7459                    .into_iter()
 7460                    .map(|(server_id, mut new_hints)| {
 7461                        new_hints.retain(|hint| {
 7462                            hint.position.is_valid(&buffer_snapshot)
 7463                                && range.start.is_valid(&buffer_snapshot)
 7464                                && range.end.is_valid(&buffer_snapshot)
 7465                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7466                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7467                        });
 7468                        (server_id, new_hints)
 7469                    })
 7470                    .collect())
 7471            })
 7472        }
 7473    }
 7474
 7475    fn diagnostic_registration_exists(
 7476        &self,
 7477        server_id: LanguageServerId,
 7478        registration_id: &Option<SharedString>,
 7479    ) -> bool {
 7480        let Some(local) = self.as_local() else {
 7481            return false;
 7482        };
 7483        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7484        else {
 7485            return false;
 7486        };
 7487        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7488        registrations.diagnostics.contains_key(&registration_key)
 7489    }
 7490
 7491    pub fn pull_diagnostics_for_buffer(
 7492        &mut self,
 7493        buffer: Entity<Buffer>,
 7494        cx: &mut Context<Self>,
 7495    ) -> Task<anyhow::Result<()>> {
 7496        let diagnostics = self.pull_diagnostics(buffer, cx);
 7497        cx.spawn(async move |lsp_store, cx| {
 7498            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7499                return Ok(());
 7500            };
 7501            lsp_store.update(cx, |lsp_store, cx| {
 7502                if lsp_store.as_local().is_none() {
 7503                    return;
 7504                }
 7505
 7506                let mut unchanged_buffers = HashMap::default();
 7507                let server_diagnostics_updates = diagnostics
 7508                    .into_iter()
 7509                    .filter_map(|diagnostics_set| match diagnostics_set {
 7510                        LspPullDiagnostics::Response {
 7511                            server_id,
 7512                            uri,
 7513                            diagnostics,
 7514                            registration_id,
 7515                        } => Some((server_id, uri, diagnostics, registration_id)),
 7516                        LspPullDiagnostics::Default => None,
 7517                    })
 7518                    .filter(|(server_id, _, _, registration_id)| {
 7519                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7520                    })
 7521                    .fold(
 7522                        HashMap::default(),
 7523                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7524                            let (result_id, diagnostics) = match diagnostics {
 7525                                PulledDiagnostics::Unchanged { result_id } => {
 7526                                    unchanged_buffers
 7527                                        .entry(new_registration_id.clone())
 7528                                        .or_insert_with(HashSet::default)
 7529                                        .insert(uri.clone());
 7530                                    (Some(result_id), Vec::new())
 7531                                }
 7532                                PulledDiagnostics::Changed {
 7533                                    result_id,
 7534                                    diagnostics,
 7535                                } => (result_id, diagnostics),
 7536                            };
 7537                            let disk_based_sources = Cow::Owned(
 7538                                lsp_store
 7539                                    .language_server_adapter_for_id(server_id)
 7540                                    .as_ref()
 7541                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7542                                    .unwrap_or(&[])
 7543                                    .to_vec(),
 7544                            );
 7545                            acc.entry(server_id)
 7546                                .or_insert_with(HashMap::default)
 7547                                .entry(new_registration_id.clone())
 7548                                .or_insert_with(Vec::new)
 7549                                .push(DocumentDiagnosticsUpdate {
 7550                                    server_id,
 7551                                    diagnostics: lsp::PublishDiagnosticsParams {
 7552                                        uri,
 7553                                        diagnostics,
 7554                                        version: None,
 7555                                    },
 7556                                    result_id: result_id.map(SharedString::new),
 7557                                    disk_based_sources,
 7558                                    registration_id: new_registration_id,
 7559                                });
 7560                            acc
 7561                        },
 7562                    );
 7563
 7564                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7565                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7566                        lsp_store
 7567                            .merge_lsp_diagnostics(
 7568                                DiagnosticSourceKind::Pulled,
 7569                                diagnostic_updates,
 7570                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7571                                    DiagnosticSourceKind::Pulled => {
 7572                                        old_diagnostic.registration_id != registration_id
 7573                                            || unchanged_buffers
 7574                                                .get(&old_diagnostic.registration_id)
 7575                                                .is_some_and(|unchanged_buffers| {
 7576                                                    unchanged_buffers.contains(&document_uri)
 7577                                                })
 7578                                    }
 7579                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7580                                        true
 7581                                    }
 7582                                },
 7583                                cx,
 7584                            )
 7585                            .log_err();
 7586                    }
 7587                }
 7588            })
 7589        })
 7590    }
 7591
 7592    pub fn signature_help<T: ToPointUtf16>(
 7593        &mut self,
 7594        buffer: &Entity<Buffer>,
 7595        position: T,
 7596        cx: &mut Context<Self>,
 7597    ) -> Task<Option<Vec<SignatureHelp>>> {
 7598        let position = position.to_point_utf16(buffer.read(cx));
 7599
 7600        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7601            let request = GetSignatureHelp { position };
 7602            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7603                return Task::ready(None);
 7604            }
 7605            let request_timeout = ProjectSettings::get_global(cx)
 7606                .global_lsp_settings
 7607                .get_request_timeout();
 7608            let request_task = client.request_lsp(
 7609                upstream_project_id,
 7610                None,
 7611                request_timeout,
 7612                cx.background_executor().clone(),
 7613                request.to_proto(upstream_project_id, buffer.read(cx)),
 7614            );
 7615            let buffer = buffer.clone();
 7616            cx.spawn(async move |weak_lsp_store, cx| {
 7617                let lsp_store = weak_lsp_store.upgrade()?;
 7618                let signatures = join_all(
 7619                    request_task
 7620                        .await
 7621                        .log_err()
 7622                        .flatten()
 7623                        .map(|response| response.payload)
 7624                        .unwrap_or_default()
 7625                        .into_iter()
 7626                        .map(|response| {
 7627                            let response = GetSignatureHelp { position }.response_from_proto(
 7628                                response.response,
 7629                                lsp_store.clone(),
 7630                                buffer.clone(),
 7631                                cx.clone(),
 7632                            );
 7633                            async move { response.await.log_err().flatten() }
 7634                        }),
 7635                )
 7636                .await
 7637                .into_iter()
 7638                .flatten()
 7639                .collect();
 7640                Some(signatures)
 7641            })
 7642        } else {
 7643            let all_actions_task = self.request_multiple_lsp_locally(
 7644                buffer,
 7645                Some(position),
 7646                GetSignatureHelp { position },
 7647                cx,
 7648            );
 7649            cx.background_spawn(async move {
 7650                Some(
 7651                    all_actions_task
 7652                        .await
 7653                        .into_iter()
 7654                        .flat_map(|(_, actions)| actions)
 7655                        .collect::<Vec<_>>(),
 7656                )
 7657            })
 7658        }
 7659    }
 7660
 7661    pub fn hover(
 7662        &mut self,
 7663        buffer: &Entity<Buffer>,
 7664        position: PointUtf16,
 7665        cx: &mut Context<Self>,
 7666    ) -> Task<Option<Vec<Hover>>> {
 7667        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7668            let request = GetHover { position };
 7669            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7670                return Task::ready(None);
 7671            }
 7672            let request_timeout = ProjectSettings::get_global(cx)
 7673                .global_lsp_settings
 7674                .get_request_timeout();
 7675            let request_task = client.request_lsp(
 7676                upstream_project_id,
 7677                None,
 7678                request_timeout,
 7679                cx.background_executor().clone(),
 7680                request.to_proto(upstream_project_id, buffer.read(cx)),
 7681            );
 7682            let buffer = buffer.clone();
 7683            cx.spawn(async move |weak_lsp_store, cx| {
 7684                let lsp_store = weak_lsp_store.upgrade()?;
 7685                let hovers = join_all(
 7686                    request_task
 7687                        .await
 7688                        .log_err()
 7689                        .flatten()
 7690                        .map(|response| response.payload)
 7691                        .unwrap_or_default()
 7692                        .into_iter()
 7693                        .map(|response| {
 7694                            let response = GetHover { position }.response_from_proto(
 7695                                response.response,
 7696                                lsp_store.clone(),
 7697                                buffer.clone(),
 7698                                cx.clone(),
 7699                            );
 7700                            async move {
 7701                                response
 7702                                    .await
 7703                                    .log_err()
 7704                                    .flatten()
 7705                                    .and_then(remove_empty_hover_blocks)
 7706                            }
 7707                        }),
 7708                )
 7709                .await
 7710                .into_iter()
 7711                .flatten()
 7712                .collect();
 7713                Some(hovers)
 7714            })
 7715        } else {
 7716            let all_actions_task = self.request_multiple_lsp_locally(
 7717                buffer,
 7718                Some(position),
 7719                GetHover { position },
 7720                cx,
 7721            );
 7722            cx.background_spawn(async move {
 7723                Some(
 7724                    all_actions_task
 7725                        .await
 7726                        .into_iter()
 7727                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7728                        .collect::<Vec<Hover>>(),
 7729                )
 7730            })
 7731        }
 7732    }
 7733
 7734    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7735        let language_registry = self.languages.clone();
 7736
 7737        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7738            let request = upstream_client.request(proto::GetProjectSymbols {
 7739                project_id: *project_id,
 7740                query: query.to_string(),
 7741            });
 7742            cx.foreground_executor().spawn(async move {
 7743                let response = request.await?;
 7744                let mut symbols = Vec::new();
 7745                let core_symbols = response
 7746                    .symbols
 7747                    .into_iter()
 7748                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7749                    .collect::<Vec<_>>();
 7750                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7751                    .await;
 7752                Ok(symbols)
 7753            })
 7754        } else if let Some(local) = self.as_local() {
 7755            struct WorkspaceSymbolsResult {
 7756                server_id: LanguageServerId,
 7757                lsp_adapter: Arc<CachedLspAdapter>,
 7758                worktree: WeakEntity<Worktree>,
 7759                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7760            }
 7761
 7762            let mut requests = Vec::new();
 7763            let mut requested_servers = BTreeSet::new();
 7764            let request_timeout = ProjectSettings::get_global(cx)
 7765                .global_lsp_settings
 7766                .get_request_timeout();
 7767
 7768            for (seed, state) in local.language_server_ids.iter() {
 7769                let Some(worktree_handle) = self
 7770                    .worktree_store
 7771                    .read(cx)
 7772                    .worktree_for_id(seed.worktree_id, cx)
 7773                else {
 7774                    continue;
 7775                };
 7776
 7777                let worktree = worktree_handle.read(cx);
 7778                if !worktree.is_visible() {
 7779                    continue;
 7780                }
 7781
 7782                if !requested_servers.insert(state.id) {
 7783                    continue;
 7784                }
 7785
 7786                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7787                    Some(LanguageServerState::Running {
 7788                        adapter, server, ..
 7789                    }) => (adapter.clone(), server),
 7790
 7791                    _ => continue,
 7792                };
 7793
 7794                let supports_workspace_symbol_request =
 7795                    match server.capabilities().workspace_symbol_provider {
 7796                        Some(OneOf::Left(supported)) => supported,
 7797                        Some(OneOf::Right(_)) => true,
 7798                        None => false,
 7799                    };
 7800
 7801                if !supports_workspace_symbol_request {
 7802                    continue;
 7803                }
 7804
 7805                let worktree_handle = worktree_handle.clone();
 7806                let server_id = server.server_id();
 7807                requests.push(
 7808                    server
 7809                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7810                            lsp::WorkspaceSymbolParams {
 7811                                query: query.to_string(),
 7812                                ..Default::default()
 7813                            },
 7814                            request_timeout,
 7815                        )
 7816                        .map(move |response| {
 7817                            let lsp_symbols = response
 7818                                .into_response()
 7819                                .context("workspace symbols request")
 7820                                .log_err()
 7821                                .flatten()
 7822                                .map(|symbol_response| match symbol_response {
 7823                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7824                                        flat_responses
 7825                                            .into_iter()
 7826                                            .map(|lsp_symbol| {
 7827                                                (
 7828                                                    lsp_symbol.name,
 7829                                                    lsp_symbol.kind,
 7830                                                    lsp_symbol.location,
 7831                                                    lsp_symbol.container_name,
 7832                                                )
 7833                                            })
 7834                                            .collect::<Vec<_>>()
 7835                                    }
 7836                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7837                                        nested_responses
 7838                                            .into_iter()
 7839                                            .filter_map(|lsp_symbol| {
 7840                                                let location = match lsp_symbol.location {
 7841                                                    OneOf::Left(location) => location,
 7842                                                    OneOf::Right(_) => {
 7843                                                        log::error!(
 7844                                                            "Unexpected: client capabilities \
 7845                                                            forbid symbol resolutions in \
 7846                                                            workspace.symbol.resolveSupport"
 7847                                                        );
 7848                                                        return None;
 7849                                                    }
 7850                                                };
 7851                                                Some((
 7852                                                    lsp_symbol.name,
 7853                                                    lsp_symbol.kind,
 7854                                                    location,
 7855                                                    lsp_symbol.container_name,
 7856                                                ))
 7857                                            })
 7858                                            .collect::<Vec<_>>()
 7859                                    }
 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(
 7887                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7888                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7889                                    let source_worktree = result.worktree.upgrade()?;
 7890                                    let source_worktree_id = source_worktree.read(cx).id();
 7891
 7892                                    let path = if let Some((tree, rel_path)) =
 7893                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7894                                    {
 7895                                        let worktree_id = tree.read(cx).id();
 7896                                        SymbolLocation::InProject(ProjectPath {
 7897                                            worktree_id,
 7898                                            path: rel_path,
 7899                                        })
 7900                                    } else {
 7901                                        SymbolLocation::OutsideProject {
 7902                                            signature: this.symbol_signature(&abs_path),
 7903                                            abs_path: abs_path.into(),
 7904                                        }
 7905                                    };
 7906
 7907                                    Some(CoreSymbol {
 7908                                        source_language_server_id: result.server_id,
 7909                                        language_server_name: result.lsp_adapter.name.clone(),
 7910                                        source_worktree_id,
 7911                                        path,
 7912                                        kind: symbol_kind,
 7913                                        name: collapse_newlines(&symbol_name, ""),
 7914                                        range: range_from_lsp(symbol_location.range),
 7915                                        container_name: container_name
 7916                                            .map(|c| collapse_newlines(&c, "")),
 7917                                    })
 7918                                },
 7919                            )
 7920                            .collect::<Vec<_>>()
 7921                    });
 7922
 7923                    populate_labels_for_symbols(
 7924                        core_symbols,
 7925                        &language_registry,
 7926                        Some(result.lsp_adapter),
 7927                        &mut symbols,
 7928                    )
 7929                    .await;
 7930                }
 7931
 7932                Ok(symbols)
 7933            })
 7934        } else {
 7935            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7936        }
 7937    }
 7938
 7939    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7940        let mut summary = DiagnosticSummary::default();
 7941        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7942            summary.error_count += path_summary.error_count;
 7943            summary.warning_count += path_summary.warning_count;
 7944        }
 7945        summary
 7946    }
 7947
 7948    /// Returns the diagnostic summary for a specific project path.
 7949    pub fn diagnostic_summary_for_path(
 7950        &self,
 7951        project_path: &ProjectPath,
 7952        _: &App,
 7953    ) -> DiagnosticSummary {
 7954        if let Some(summaries) = self
 7955            .diagnostic_summaries
 7956            .get(&project_path.worktree_id)
 7957            .and_then(|map| map.get(&project_path.path))
 7958        {
 7959            let (error_count, warning_count) = summaries.iter().fold(
 7960                (0, 0),
 7961                |(error_count, warning_count), (_language_server_id, summary)| {
 7962                    (
 7963                        error_count + summary.error_count,
 7964                        warning_count + summary.warning_count,
 7965                    )
 7966                },
 7967            );
 7968
 7969            DiagnosticSummary {
 7970                error_count,
 7971                warning_count,
 7972            }
 7973        } else {
 7974            DiagnosticSummary::default()
 7975        }
 7976    }
 7977
 7978    pub fn diagnostic_summaries<'a>(
 7979        &'a self,
 7980        include_ignored: bool,
 7981        cx: &'a App,
 7982    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7983        self.worktree_store
 7984            .read(cx)
 7985            .visible_worktrees(cx)
 7986            .filter_map(|worktree| {
 7987                let worktree = worktree.read(cx);
 7988                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7989            })
 7990            .flat_map(move |(worktree, summaries)| {
 7991                let worktree_id = worktree.id();
 7992                summaries
 7993                    .iter()
 7994                    .filter(move |(path, _)| {
 7995                        include_ignored
 7996                            || worktree
 7997                                .entry_for_path(path.as_ref())
 7998                                .is_some_and(|entry| !entry.is_ignored)
 7999                    })
 8000                    .flat_map(move |(path, summaries)| {
 8001                        summaries.iter().map(move |(server_id, summary)| {
 8002                            (
 8003                                ProjectPath {
 8004                                    worktree_id,
 8005                                    path: path.clone(),
 8006                                },
 8007                                *server_id,
 8008                                *summary,
 8009                            )
 8010                        })
 8011                    })
 8012            })
 8013    }
 8014
 8015    pub fn on_buffer_edited(
 8016        &mut self,
 8017        buffer: Entity<Buffer>,
 8018        cx: &mut Context<Self>,
 8019    ) -> Option<()> {
 8020        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 8021            Some(
 8022                self.as_local()?
 8023                    .language_servers_for_buffer(buffer, cx)
 8024                    .map(|i| i.1.clone())
 8025                    .collect(),
 8026            )
 8027        })?;
 8028
 8029        let buffer = buffer.read(cx);
 8030        let file = File::from_dyn(buffer.file())?;
 8031        let abs_path = file.as_local()?.abs_path(cx);
 8032        let uri = lsp::Uri::from_file_path(&abs_path)
 8033            .ok()
 8034            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 8035            .log_err()?;
 8036        let next_snapshot = buffer.text_snapshot();
 8037        for language_server in language_servers {
 8038            let language_server = language_server.clone();
 8039
 8040            let buffer_snapshots = self
 8041                .as_local_mut()?
 8042                .buffer_snapshots
 8043                .get_mut(&buffer.remote_id())
 8044                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 8045            let previous_snapshot = buffer_snapshots.last()?;
 8046
 8047            let build_incremental_change = || {
 8048                buffer
 8049                    .edits_since::<Dimensions<PointUtf16, usize>>(
 8050                        previous_snapshot.snapshot.version(),
 8051                    )
 8052                    .map(|edit| {
 8053                        let edit_start = edit.new.start.0;
 8054                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 8055                        let new_text = next_snapshot
 8056                            .text_for_range(edit.new.start.1..edit.new.end.1)
 8057                            .collect();
 8058                        lsp::TextDocumentContentChangeEvent {
 8059                            range: Some(lsp::Range::new(
 8060                                point_to_lsp(edit_start),
 8061                                point_to_lsp(edit_end),
 8062                            )),
 8063                            range_length: None,
 8064                            text: new_text,
 8065                        }
 8066                    })
 8067                    .collect()
 8068            };
 8069
 8070            let document_sync_kind = language_server
 8071                .capabilities()
 8072                .text_document_sync
 8073                .as_ref()
 8074                .and_then(|sync| match sync {
 8075                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 8076                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 8077                });
 8078
 8079            let content_changes: Vec<_> = match document_sync_kind {
 8080                Some(lsp::TextDocumentSyncKind::FULL) => {
 8081                    vec![lsp::TextDocumentContentChangeEvent {
 8082                        range: None,
 8083                        range_length: None,
 8084                        text: next_snapshot.text(),
 8085                    }]
 8086                }
 8087                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8088                _ => {
 8089                    #[cfg(any(test, feature = "test-support"))]
 8090                    {
 8091                        build_incremental_change()
 8092                    }
 8093
 8094                    #[cfg(not(any(test, feature = "test-support")))]
 8095                    {
 8096                        continue;
 8097                    }
 8098                }
 8099            };
 8100
 8101            let next_version = previous_snapshot.version + 1;
 8102            buffer_snapshots.push(LspBufferSnapshot {
 8103                version: next_version,
 8104                snapshot: next_snapshot.clone(),
 8105            });
 8106
 8107            language_server
 8108                .notify::<lsp::notification::DidChangeTextDocument>(
 8109                    lsp::DidChangeTextDocumentParams {
 8110                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8111                            uri.clone(),
 8112                            next_version,
 8113                        ),
 8114                        content_changes,
 8115                    },
 8116                )
 8117                .ok();
 8118            self.pull_workspace_diagnostics(language_server.server_id());
 8119        }
 8120
 8121        None
 8122    }
 8123
 8124    pub fn on_buffer_saved(
 8125        &mut self,
 8126        buffer: Entity<Buffer>,
 8127        cx: &mut Context<Self>,
 8128    ) -> Option<()> {
 8129        let file = File::from_dyn(buffer.read(cx).file())?;
 8130        let worktree_id = file.worktree_id(cx);
 8131        let abs_path = file.as_local()?.abs_path(cx);
 8132        let text_document = lsp::TextDocumentIdentifier {
 8133            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8134        };
 8135        let local = self.as_local()?;
 8136
 8137        for server in local.language_servers_for_worktree(worktree_id) {
 8138            if let Some(include_text) = include_text(server.as_ref()) {
 8139                let text = if include_text {
 8140                    Some(buffer.read(cx).text())
 8141                } else {
 8142                    None
 8143                };
 8144                server
 8145                    .notify::<lsp::notification::DidSaveTextDocument>(
 8146                        lsp::DidSaveTextDocumentParams {
 8147                            text_document: text_document.clone(),
 8148                            text,
 8149                        },
 8150                    )
 8151                    .ok();
 8152            }
 8153        }
 8154
 8155        let language_servers = buffer.update(cx, |buffer, cx| {
 8156            local.language_server_ids_for_buffer(buffer, cx)
 8157        });
 8158        for language_server_id in language_servers {
 8159            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8160        }
 8161
 8162        None
 8163    }
 8164
 8165    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8166        maybe!(async move {
 8167            let mut refreshed_servers = HashSet::default();
 8168            let servers = lsp_store
 8169                .update(cx, |lsp_store, cx| {
 8170                    let local = lsp_store.as_local()?;
 8171
 8172                    let servers = local
 8173                        .language_server_ids
 8174                        .iter()
 8175                        .filter_map(|(seed, state)| {
 8176                            let worktree = lsp_store
 8177                                .worktree_store
 8178                                .read(cx)
 8179                                .worktree_for_id(seed.worktree_id, cx);
 8180                            let delegate: Arc<dyn LspAdapterDelegate> =
 8181                                worktree.map(|worktree| {
 8182                                    LocalLspAdapterDelegate::new(
 8183                                        local.languages.clone(),
 8184                                        &local.environment,
 8185                                        cx.weak_entity(),
 8186                                        &worktree,
 8187                                        local.http_client.clone(),
 8188                                        local.fs.clone(),
 8189                                        cx,
 8190                                    )
 8191                                })?;
 8192                            let server_id = state.id;
 8193
 8194                            let states = local.language_servers.get(&server_id)?;
 8195
 8196                            match states {
 8197                                LanguageServerState::Starting { .. } => None,
 8198                                LanguageServerState::Running {
 8199                                    adapter, server, ..
 8200                                } => {
 8201                                    let adapter = adapter.clone();
 8202                                    let server = server.clone();
 8203                                    refreshed_servers.insert(server.name());
 8204                                    let toolchain = seed.toolchain.clone();
 8205                                    Some(cx.spawn(async move |_, cx| {
 8206                                        let settings =
 8207                                            LocalLspStore::workspace_configuration_for_adapter(
 8208                                                adapter.adapter.clone(),
 8209                                                &delegate,
 8210                                                toolchain,
 8211                                                None,
 8212                                                cx,
 8213                                            )
 8214                                            .await
 8215                                            .ok()?;
 8216                                        server
 8217                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8218                                                lsp::DidChangeConfigurationParams { settings },
 8219                                            )
 8220                                            .ok()?;
 8221                                        Some(())
 8222                                    }))
 8223                                }
 8224                            }
 8225                        })
 8226                        .collect::<Vec<_>>();
 8227
 8228                    Some(servers)
 8229                })
 8230                .ok()
 8231                .flatten()?;
 8232
 8233            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8234            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8235            // to stop and unregister its language server wrapper.
 8236            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8237            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8238            let _: Vec<Option<()>> = join_all(servers).await;
 8239
 8240            Some(())
 8241        })
 8242        .await;
 8243    }
 8244
 8245    fn maintain_workspace_config(
 8246        external_refresh_requests: watch::Receiver<()>,
 8247        cx: &mut Context<Self>,
 8248    ) -> Task<Result<()>> {
 8249        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8250        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8251
 8252        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8253            *settings_changed_tx.borrow_mut() = ();
 8254        });
 8255
 8256        let mut joint_future =
 8257            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8258        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8259        // - 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).
 8260        // - 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.
 8261        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8262        // - 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,
 8263        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8264        cx.spawn(async move |this, cx| {
 8265            while let Some(()) = joint_future.next().await {
 8266                this.update(cx, |this, cx| {
 8267                    this.refresh_server_tree(cx);
 8268                })
 8269                .ok();
 8270
 8271                Self::refresh_workspace_configurations(&this, cx).await;
 8272            }
 8273
 8274            drop(settings_observation);
 8275            anyhow::Ok(())
 8276        })
 8277    }
 8278
 8279    pub fn running_language_servers_for_local_buffer<'a>(
 8280        &'a self,
 8281        buffer: &Buffer,
 8282        cx: &mut App,
 8283    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8284        let local = self.as_local();
 8285        let language_server_ids = local
 8286            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8287            .unwrap_or_default();
 8288
 8289        language_server_ids
 8290            .into_iter()
 8291            .filter_map(
 8292                move |server_id| match local?.language_servers.get(&server_id)? {
 8293                    LanguageServerState::Running {
 8294                        adapter, server, ..
 8295                    } => Some((adapter, server)),
 8296                    _ => None,
 8297                },
 8298            )
 8299    }
 8300
 8301    pub fn language_servers_for_local_buffer(
 8302        &self,
 8303        buffer: &Buffer,
 8304        cx: &mut App,
 8305    ) -> Vec<LanguageServerId> {
 8306        let local = self.as_local();
 8307        local
 8308            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8309            .unwrap_or_default()
 8310    }
 8311
 8312    pub fn language_server_for_local_buffer<'a>(
 8313        &'a self,
 8314        buffer: &'a Buffer,
 8315        server_id: LanguageServerId,
 8316        cx: &'a mut App,
 8317    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8318        self.as_local()?
 8319            .language_servers_for_buffer(buffer, cx)
 8320            .find(|(_, s)| s.server_id() == server_id)
 8321    }
 8322
 8323    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8324        self.diagnostic_summaries.remove(&id_to_remove);
 8325        if let Some(local) = self.as_local_mut() {
 8326            let to_remove = local.remove_worktree(id_to_remove, cx);
 8327            for server in to_remove {
 8328                self.language_server_statuses.remove(&server);
 8329            }
 8330        }
 8331    }
 8332
 8333    fn invalidate_diagnostic_summaries_for_removed_entries(
 8334        &mut self,
 8335        worktree_id: WorktreeId,
 8336        changes: &UpdatedEntriesSet,
 8337        cx: &mut Context<Self>,
 8338    ) {
 8339        let Some(summaries_for_tree) = self.diagnostic_summaries.get_mut(&worktree_id) else {
 8340            return;
 8341        };
 8342
 8343        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
 8344        let mut cleared_server_ids: HashSet<LanguageServerId> = HashSet::default();
 8345        let downstream = self.downstream_client.clone();
 8346
 8347        for (path, _, _) in changes
 8348            .iter()
 8349            .filter(|(_, _, change)| *change == PathChange::Removed)
 8350        {
 8351            if let Some(summaries_by_server_id) = summaries_for_tree.remove(path) {
 8352                for (server_id, _) in &summaries_by_server_id {
 8353                    cleared_server_ids.insert(*server_id);
 8354                    if let Some((client, project_id)) = &downstream {
 8355                        client
 8356                            .send(proto::UpdateDiagnosticSummary {
 8357                                project_id: *project_id,
 8358                                worktree_id: worktree_id.to_proto(),
 8359                                summary: Some(proto::DiagnosticSummary {
 8360                                    path: path.as_ref().to_proto(),
 8361                                    language_server_id: server_id.0 as u64,
 8362                                    error_count: 0,
 8363                                    warning_count: 0,
 8364                                }),
 8365                                more_summaries: Vec::new(),
 8366                            })
 8367                            .ok();
 8368                    }
 8369                }
 8370                cleared_paths.push(ProjectPath {
 8371                    worktree_id,
 8372                    path: path.clone(),
 8373                });
 8374            }
 8375        }
 8376
 8377        if !cleared_paths.is_empty() {
 8378            for server_id in cleared_server_ids {
 8379                cx.emit(LspStoreEvent::DiagnosticsUpdated {
 8380                    server_id,
 8381                    paths: cleared_paths.clone(),
 8382                });
 8383            }
 8384        }
 8385    }
 8386
 8387    pub fn shared(
 8388        &mut self,
 8389        project_id: u64,
 8390        downstream_client: AnyProtoClient,
 8391        _: &mut Context<Self>,
 8392    ) {
 8393        self.downstream_client = Some((downstream_client.clone(), project_id));
 8394
 8395        for (server_id, status) in &self.language_server_statuses {
 8396            if let Some(server) = self.language_server_for_id(*server_id) {
 8397                downstream_client
 8398                    .send(proto::StartLanguageServer {
 8399                        project_id,
 8400                        server: Some(proto::LanguageServer {
 8401                            id: server_id.to_proto(),
 8402                            name: status.name.to_string(),
 8403                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8404                        }),
 8405                        capabilities: serde_json::to_string(&server.capabilities())
 8406                            .expect("serializing server LSP capabilities"),
 8407                    })
 8408                    .log_err();
 8409            }
 8410        }
 8411    }
 8412
 8413    pub fn disconnected_from_host(&mut self) {
 8414        self.downstream_client.take();
 8415    }
 8416
 8417    pub fn disconnected_from_ssh_remote(&mut self) {
 8418        if let LspStoreMode::Remote(RemoteLspStore {
 8419            upstream_client, ..
 8420        }) = &mut self.mode
 8421        {
 8422            upstream_client.take();
 8423        }
 8424    }
 8425
 8426    pub(crate) fn set_language_server_statuses_from_proto(
 8427        &mut self,
 8428        project: WeakEntity<Project>,
 8429        language_servers: Vec<proto::LanguageServer>,
 8430        server_capabilities: Vec<String>,
 8431        cx: &mut Context<Self>,
 8432    ) {
 8433        let lsp_logs = cx
 8434            .try_global::<GlobalLogStore>()
 8435            .map(|lsp_store| lsp_store.0.clone());
 8436
 8437        self.language_server_statuses = language_servers
 8438            .into_iter()
 8439            .zip(server_capabilities)
 8440            .map(|(server, server_capabilities)| {
 8441                let server_id = LanguageServerId(server.id as usize);
 8442                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8443                    self.lsp_server_capabilities
 8444                        .insert(server_id, server_capabilities);
 8445                }
 8446
 8447                let name = LanguageServerName::from_proto(server.name);
 8448                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8449
 8450                if let Some(lsp_logs) = &lsp_logs {
 8451                    lsp_logs.update(cx, |lsp_logs, cx| {
 8452                        lsp_logs.add_language_server(
 8453                            // Only remote clients get their language servers set from proto
 8454                            LanguageServerKind::Remote {
 8455                                project: project.clone(),
 8456                            },
 8457                            server_id,
 8458                            Some(name.clone()),
 8459                            worktree,
 8460                            None,
 8461                            cx,
 8462                        );
 8463                    });
 8464                }
 8465
 8466                (
 8467                    server_id,
 8468                    LanguageServerStatus {
 8469                        name,
 8470                        server_version: None,
 8471                        server_readable_version: None,
 8472                        pending_work: Default::default(),
 8473                        has_pending_diagnostic_updates: false,
 8474                        progress_tokens: Default::default(),
 8475                        worktree,
 8476                        binary: None,
 8477                        configuration: None,
 8478                        workspace_folders: BTreeSet::new(),
 8479                        process_id: None,
 8480                    },
 8481                )
 8482            })
 8483            .collect();
 8484    }
 8485
 8486    #[cfg(feature = "test-support")]
 8487    pub fn update_diagnostic_entries(
 8488        &mut self,
 8489        server_id: LanguageServerId,
 8490        abs_path: PathBuf,
 8491        result_id: Option<SharedString>,
 8492        version: Option<i32>,
 8493        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8494        cx: &mut Context<Self>,
 8495    ) -> anyhow::Result<()> {
 8496        self.merge_diagnostic_entries(
 8497            vec![DocumentDiagnosticsUpdate {
 8498                diagnostics: DocumentDiagnostics {
 8499                    diagnostics,
 8500                    document_abs_path: abs_path,
 8501                    version,
 8502                },
 8503                result_id,
 8504                server_id,
 8505                disk_based_sources: Cow::Borrowed(&[]),
 8506                registration_id: None,
 8507            }],
 8508            |_, _, _| false,
 8509            cx,
 8510        )?;
 8511        Ok(())
 8512    }
 8513
 8514    pub fn merge_diagnostic_entries<'a>(
 8515        &mut self,
 8516        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8517        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8518        cx: &mut Context<Self>,
 8519    ) -> anyhow::Result<()> {
 8520        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8521        let mut updated_diagnostics_paths = HashMap::default();
 8522        for mut update in diagnostic_updates {
 8523            let abs_path = &update.diagnostics.document_abs_path;
 8524            let server_id = update.server_id;
 8525            let Some((worktree, relative_path)) =
 8526                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8527            else {
 8528                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8529                return Ok(());
 8530            };
 8531
 8532            let worktree_id = worktree.read(cx).id();
 8533            let project_path = ProjectPath {
 8534                worktree_id,
 8535                path: relative_path,
 8536            };
 8537
 8538            let document_uri = lsp::Uri::from_file_path(abs_path)
 8539                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8540            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8541                let snapshot = buffer_handle.read(cx).snapshot();
 8542                let buffer = buffer_handle.read(cx);
 8543                let reused_diagnostics = buffer
 8544                    .buffer_diagnostics(Some(server_id))
 8545                    .iter()
 8546                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8547                    .map(|v| {
 8548                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8549                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8550                        DiagnosticEntry {
 8551                            range: start..end,
 8552                            diagnostic: v.diagnostic.clone(),
 8553                        }
 8554                    })
 8555                    .collect::<Vec<_>>();
 8556
 8557                self.as_local_mut()
 8558                    .context("cannot merge diagnostics on a remote LspStore")?
 8559                    .update_buffer_diagnostics(
 8560                        &buffer_handle,
 8561                        server_id,
 8562                        Some(update.registration_id),
 8563                        update.result_id,
 8564                        update.diagnostics.version,
 8565                        update.diagnostics.diagnostics.clone(),
 8566                        reused_diagnostics.clone(),
 8567                        cx,
 8568                    )?;
 8569
 8570                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8571            } else if let Some(local) = self.as_local() {
 8572                let reused_diagnostics = local
 8573                    .diagnostics
 8574                    .get(&worktree_id)
 8575                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8576                    .and_then(|diagnostics_by_server_id| {
 8577                        diagnostics_by_server_id
 8578                            .binary_search_by_key(&server_id, |e| e.0)
 8579                            .ok()
 8580                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8581                    })
 8582                    .into_iter()
 8583                    .flatten()
 8584                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8585
 8586                update
 8587                    .diagnostics
 8588                    .diagnostics
 8589                    .extend(reused_diagnostics.cloned());
 8590            }
 8591
 8592            let updated = worktree.update(cx, |worktree, cx| {
 8593                self.update_worktree_diagnostics(
 8594                    worktree.id(),
 8595                    server_id,
 8596                    project_path.path.clone(),
 8597                    update.diagnostics.diagnostics,
 8598                    cx,
 8599                )
 8600            })?;
 8601            match updated {
 8602                ControlFlow::Continue(new_summary) => {
 8603                    if let Some((project_id, new_summary)) = new_summary {
 8604                        match &mut diagnostics_summary {
 8605                            Some(diagnostics_summary) => {
 8606                                diagnostics_summary
 8607                                    .more_summaries
 8608                                    .push(proto::DiagnosticSummary {
 8609                                        path: project_path.path.as_ref().to_proto(),
 8610                                        language_server_id: server_id.0 as u64,
 8611                                        error_count: new_summary.error_count,
 8612                                        warning_count: new_summary.warning_count,
 8613                                    })
 8614                            }
 8615                            None => {
 8616                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8617                                    project_id,
 8618                                    worktree_id: worktree_id.to_proto(),
 8619                                    summary: Some(proto::DiagnosticSummary {
 8620                                        path: project_path.path.as_ref().to_proto(),
 8621                                        language_server_id: server_id.0 as u64,
 8622                                        error_count: new_summary.error_count,
 8623                                        warning_count: new_summary.warning_count,
 8624                                    }),
 8625                                    more_summaries: Vec::new(),
 8626                                })
 8627                            }
 8628                        }
 8629                    }
 8630                    updated_diagnostics_paths
 8631                        .entry(server_id)
 8632                        .or_insert_with(Vec::new)
 8633                        .push(project_path);
 8634                }
 8635                ControlFlow::Break(()) => {}
 8636            }
 8637        }
 8638
 8639        if let Some((diagnostics_summary, (downstream_client, _))) =
 8640            diagnostics_summary.zip(self.downstream_client.as_ref())
 8641        {
 8642            downstream_client.send(diagnostics_summary).log_err();
 8643        }
 8644        for (server_id, paths) in updated_diagnostics_paths {
 8645            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8646        }
 8647        Ok(())
 8648    }
 8649
 8650    fn update_worktree_diagnostics(
 8651        &mut self,
 8652        worktree_id: WorktreeId,
 8653        server_id: LanguageServerId,
 8654        path_in_worktree: Arc<RelPath>,
 8655        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8656        _: &mut Context<Worktree>,
 8657    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8658        let local = match &mut self.mode {
 8659            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8660            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8661        };
 8662
 8663        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8664        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8665        let summaries_by_server_id = summaries_for_tree
 8666            .entry(path_in_worktree.clone())
 8667            .or_default();
 8668
 8669        let old_summary = summaries_by_server_id
 8670            .remove(&server_id)
 8671            .unwrap_or_default();
 8672
 8673        let new_summary = DiagnosticSummary::new(&diagnostics);
 8674        if diagnostics.is_empty() {
 8675            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8676            {
 8677                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8678                    diagnostics_by_server_id.remove(ix);
 8679                }
 8680                if diagnostics_by_server_id.is_empty() {
 8681                    diagnostics_for_tree.remove(&path_in_worktree);
 8682                }
 8683            }
 8684        } else {
 8685            summaries_by_server_id.insert(server_id, new_summary);
 8686            let diagnostics_by_server_id = diagnostics_for_tree
 8687                .entry(path_in_worktree.clone())
 8688                .or_default();
 8689            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8690                Ok(ix) => {
 8691                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8692                }
 8693                Err(ix) => {
 8694                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8695                }
 8696            }
 8697        }
 8698
 8699        if !old_summary.is_empty() || !new_summary.is_empty() {
 8700            if let Some((_, project_id)) = &self.downstream_client {
 8701                Ok(ControlFlow::Continue(Some((
 8702                    *project_id,
 8703                    proto::DiagnosticSummary {
 8704                        path: path_in_worktree.to_proto(),
 8705                        language_server_id: server_id.0 as u64,
 8706                        error_count: new_summary.error_count as u32,
 8707                        warning_count: new_summary.warning_count as u32,
 8708                    },
 8709                ))))
 8710            } else {
 8711                Ok(ControlFlow::Continue(None))
 8712            }
 8713        } else {
 8714            Ok(ControlFlow::Break(()))
 8715        }
 8716    }
 8717
 8718    pub fn open_buffer_for_symbol(
 8719        &mut self,
 8720        symbol: &Symbol,
 8721        cx: &mut Context<Self>,
 8722    ) -> Task<Result<Entity<Buffer>>> {
 8723        if let Some((client, project_id)) = self.upstream_client() {
 8724            let request = client.request(proto::OpenBufferForSymbol {
 8725                project_id,
 8726                symbol: Some(Self::serialize_symbol(symbol)),
 8727            });
 8728            cx.spawn(async move |this, cx| {
 8729                let response = request.await?;
 8730                let buffer_id = BufferId::new(response.buffer_id)?;
 8731                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8732                    .await
 8733            })
 8734        } else if let Some(local) = self.as_local() {
 8735            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8736                seed.worktree_id == symbol.source_worktree_id
 8737                    && state.id == symbol.source_language_server_id
 8738                    && symbol.language_server_name == seed.name
 8739            });
 8740            if !is_valid {
 8741                return Task::ready(Err(anyhow!(
 8742                    "language server for worktree and language not found"
 8743                )));
 8744            };
 8745
 8746            let symbol_abs_path = match &symbol.path {
 8747                SymbolLocation::InProject(project_path) => self
 8748                    .worktree_store
 8749                    .read(cx)
 8750                    .absolutize(&project_path, cx)
 8751                    .context("no such worktree"),
 8752                SymbolLocation::OutsideProject {
 8753                    abs_path,
 8754                    signature: _,
 8755                } => Ok(abs_path.to_path_buf()),
 8756            };
 8757            let symbol_abs_path = match symbol_abs_path {
 8758                Ok(abs_path) => abs_path,
 8759                Err(err) => return Task::ready(Err(err)),
 8760            };
 8761            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8762                uri
 8763            } else {
 8764                return Task::ready(Err(anyhow!("invalid symbol path")));
 8765            };
 8766
 8767            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8768        } else {
 8769            Task::ready(Err(anyhow!("no upstream client or local store")))
 8770        }
 8771    }
 8772
 8773    pub(crate) fn open_local_buffer_via_lsp(
 8774        &mut self,
 8775        abs_path: lsp::Uri,
 8776        language_server_id: LanguageServerId,
 8777        cx: &mut Context<Self>,
 8778    ) -> Task<Result<Entity<Buffer>>> {
 8779        let path_style = self.worktree_store.read(cx).path_style();
 8780        cx.spawn(async move |lsp_store, cx| {
 8781            // Escape percent-encoded string.
 8782            let current_scheme = abs_path.scheme().to_owned();
 8783            // Uri is immutable, so we can't modify the scheme
 8784
 8785            let abs_path = abs_path
 8786                .to_file_path_ext(path_style)
 8787                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8788            let p = abs_path.clone();
 8789            let yarn_worktree = lsp_store
 8790                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8791                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8792                        cx.spawn(async move |this, cx| {
 8793                            let t = this
 8794                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8795                                .ok()?;
 8796                            t.await
 8797                        })
 8798                    }),
 8799                    None => Task::ready(None),
 8800                })?
 8801                .await;
 8802            let (worktree_root_target, known_relative_path) =
 8803                if let Some((zip_root, relative_path)) = yarn_worktree {
 8804                    (zip_root, Some(relative_path))
 8805                } else {
 8806                    (Arc::<Path>::from(abs_path.as_path()), None)
 8807                };
 8808            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8809                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8810                    worktree_store.find_worktree(&worktree_root_target, cx)
 8811                })
 8812            })?;
 8813            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8814                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8815                (result.0, relative_path, None)
 8816            } else {
 8817                let worktree = lsp_store
 8818                    .update(cx, |lsp_store, cx| {
 8819                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8820                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8821                        })
 8822                    })?
 8823                    .await?;
 8824                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8825                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8826                    lsp_store
 8827                        .update(cx, |lsp_store, cx| {
 8828                            if let Some(local) = lsp_store.as_local_mut() {
 8829                                local.register_language_server_for_invisible_worktree(
 8830                                    &worktree,
 8831                                    language_server_id,
 8832                                    cx,
 8833                                )
 8834                            }
 8835                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8836                                Some(status) => status.worktree,
 8837                                None => None,
 8838                            }
 8839                        })
 8840                        .ok()
 8841                        .flatten()
 8842                        .zip(Some(worktree_root.clone()))
 8843                } else {
 8844                    None
 8845                };
 8846                let relative_path = if let Some(known_path) = known_relative_path {
 8847                    known_path
 8848                } else {
 8849                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8850                        .into_arc()
 8851                };
 8852                (worktree, relative_path, source_ws)
 8853            };
 8854            let project_path = ProjectPath {
 8855                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8856                path: relative_path,
 8857            };
 8858            let buffer = lsp_store
 8859                .update(cx, |lsp_store, cx| {
 8860                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8861                        buffer_store.open_buffer(project_path, cx)
 8862                    })
 8863                })?
 8864                .await?;
 8865            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8866            if let Some((source_ws, worktree_root)) = source_ws {
 8867                buffer.update(cx, |buffer, cx| {
 8868                    let settings = WorktreeSettings::get(
 8869                        Some(
 8870                            (&ProjectPath {
 8871                                worktree_id: source_ws,
 8872                                path: Arc::from(RelPath::empty()),
 8873                            })
 8874                                .into(),
 8875                        ),
 8876                        cx,
 8877                    );
 8878                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8879                    if is_read_only {
 8880                        buffer.set_capability(Capability::ReadOnly, cx);
 8881                    }
 8882                });
 8883            }
 8884            Ok(buffer)
 8885        })
 8886    }
 8887
 8888    fn local_lsp_servers_for_buffer(
 8889        &self,
 8890        buffer: &Entity<Buffer>,
 8891        cx: &mut Context<Self>,
 8892    ) -> Vec<LanguageServerId> {
 8893        let Some(local) = self.as_local() else {
 8894            return Vec::new();
 8895        };
 8896
 8897        let snapshot = buffer.read(cx).snapshot();
 8898
 8899        buffer.update(cx, |buffer, cx| {
 8900            local
 8901                .language_servers_for_buffer(buffer, cx)
 8902                .map(|(_, server)| server.server_id())
 8903                .filter(|server_id| {
 8904                    self.as_local().is_none_or(|local| {
 8905                        local
 8906                            .buffers_opened_in_servers
 8907                            .get(&snapshot.remote_id())
 8908                            .is_some_and(|servers| servers.contains(server_id))
 8909                    })
 8910                })
 8911                .collect()
 8912        })
 8913    }
 8914
 8915    fn request_multiple_lsp_locally<P, R>(
 8916        &mut self,
 8917        buffer: &Entity<Buffer>,
 8918        position: Option<P>,
 8919        request: R,
 8920        cx: &mut Context<Self>,
 8921    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8922    where
 8923        P: ToOffset,
 8924        R: LspCommand + Clone,
 8925        <R::LspRequest as lsp::request::Request>::Result: Send,
 8926        <R::LspRequest as lsp::request::Request>::Params: Send,
 8927    {
 8928        let Some(local) = self.as_local() else {
 8929            return Task::ready(Vec::new());
 8930        };
 8931
 8932        let snapshot = buffer.read(cx).snapshot();
 8933        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8934
 8935        let server_ids = buffer.update(cx, |buffer, cx| {
 8936            local
 8937                .language_servers_for_buffer(buffer, cx)
 8938                .filter(|(adapter, _)| {
 8939                    scope
 8940                        .as_ref()
 8941                        .map(|scope| scope.language_allowed(&adapter.name))
 8942                        .unwrap_or(true)
 8943                })
 8944                .map(|(_, server)| server.server_id())
 8945                .filter(|server_id| {
 8946                    self.as_local().is_none_or(|local| {
 8947                        local
 8948                            .buffers_opened_in_servers
 8949                            .get(&snapshot.remote_id())
 8950                            .is_some_and(|servers| servers.contains(server_id))
 8951                    })
 8952                })
 8953                .collect::<Vec<_>>()
 8954        });
 8955
 8956        let mut response_results = server_ids
 8957            .into_iter()
 8958            .map(|server_id| {
 8959                let task = self.request_lsp(
 8960                    buffer.clone(),
 8961                    LanguageServerToQuery::Other(server_id),
 8962                    request.clone(),
 8963                    cx,
 8964                );
 8965                async move { (server_id, task.await) }
 8966            })
 8967            .collect::<FuturesUnordered<_>>();
 8968
 8969        cx.background_spawn(async move {
 8970            let mut responses = Vec::with_capacity(response_results.len());
 8971            while let Some((server_id, response_result)) = response_results.next().await {
 8972                match response_result {
 8973                    Ok(response) => responses.push((server_id, response)),
 8974                    // rust-analyzer likes to error with this when its still loading up
 8975                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8976                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8977                }
 8978            }
 8979            responses
 8980        })
 8981    }
 8982
 8983    async fn handle_lsp_get_completions(
 8984        this: Entity<Self>,
 8985        envelope: TypedEnvelope<proto::GetCompletions>,
 8986        mut cx: AsyncApp,
 8987    ) -> Result<proto::GetCompletionsResponse> {
 8988        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8989
 8990        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8991        let buffer_handle = this.update(&mut cx, |this, cx| {
 8992            this.buffer_store.read(cx).get_existing(buffer_id)
 8993        })?;
 8994        let request = GetCompletions::from_proto(
 8995            envelope.payload,
 8996            this.clone(),
 8997            buffer_handle.clone(),
 8998            cx.clone(),
 8999        )
 9000        .await?;
 9001
 9002        let server_to_query = match request.server_id {
 9003            Some(server_id) => LanguageServerToQuery::Other(server_id),
 9004            None => LanguageServerToQuery::FirstCapable,
 9005        };
 9006
 9007        let response = this
 9008            .update(&mut cx, |this, cx| {
 9009                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 9010            })
 9011            .await?;
 9012        this.update(&mut cx, |this, cx| {
 9013            Ok(GetCompletions::response_to_proto(
 9014                response,
 9015                this,
 9016                sender_id,
 9017                &buffer_handle.read(cx).version(),
 9018                cx,
 9019            ))
 9020        })
 9021    }
 9022
 9023    async fn handle_lsp_command<T: LspCommand>(
 9024        this: Entity<Self>,
 9025        envelope: TypedEnvelope<T::ProtoRequest>,
 9026        mut cx: AsyncApp,
 9027    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 9028    where
 9029        <T::LspRequest as lsp::request::Request>::Params: Send,
 9030        <T::LspRequest as lsp::request::Request>::Result: Send,
 9031    {
 9032        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9033        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 9034        let buffer_handle = this.update(&mut cx, |this, cx| {
 9035            this.buffer_store.read(cx).get_existing(buffer_id)
 9036        })?;
 9037        let request = T::from_proto(
 9038            envelope.payload,
 9039            this.clone(),
 9040            buffer_handle.clone(),
 9041            cx.clone(),
 9042        )
 9043        .await?;
 9044        let response = this
 9045            .update(&mut cx, |this, cx| {
 9046                this.request_lsp(
 9047                    buffer_handle.clone(),
 9048                    LanguageServerToQuery::FirstCapable,
 9049                    request,
 9050                    cx,
 9051                )
 9052            })
 9053            .await?;
 9054        this.update(&mut cx, |this, cx| {
 9055            Ok(T::response_to_proto(
 9056                response,
 9057                this,
 9058                sender_id,
 9059                &buffer_handle.read(cx).version(),
 9060                cx,
 9061            ))
 9062        })
 9063    }
 9064
 9065    async fn handle_lsp_query(
 9066        lsp_store: Entity<Self>,
 9067        envelope: TypedEnvelope<proto::LspQuery>,
 9068        mut cx: AsyncApp,
 9069    ) -> Result<proto::Ack> {
 9070        use proto::lsp_query::Request;
 9071        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9072        let lsp_query = envelope.payload;
 9073        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 9074        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 9075        match lsp_query.request.context("invalid LSP query request")? {
 9076            Request::GetReferences(get_references) => {
 9077                let position = get_references.position.clone().and_then(deserialize_anchor);
 9078                Self::query_lsp_locally::<GetReferences>(
 9079                    lsp_store,
 9080                    server_id,
 9081                    sender_id,
 9082                    lsp_request_id,
 9083                    get_references,
 9084                    position,
 9085                    &mut cx,
 9086                )
 9087                .await?;
 9088            }
 9089            Request::GetDocumentColor(get_document_color) => {
 9090                Self::query_lsp_locally::<GetDocumentColor>(
 9091                    lsp_store,
 9092                    server_id,
 9093                    sender_id,
 9094                    lsp_request_id,
 9095                    get_document_color,
 9096                    None,
 9097                    &mut cx,
 9098                )
 9099                .await?;
 9100            }
 9101            Request::GetFoldingRanges(get_folding_ranges) => {
 9102                Self::query_lsp_locally::<GetFoldingRanges>(
 9103                    lsp_store,
 9104                    server_id,
 9105                    sender_id,
 9106                    lsp_request_id,
 9107                    get_folding_ranges,
 9108                    None,
 9109                    &mut cx,
 9110                )
 9111                .await?;
 9112            }
 9113            Request::GetDocumentSymbols(get_document_symbols) => {
 9114                Self::query_lsp_locally::<GetDocumentSymbols>(
 9115                    lsp_store,
 9116                    server_id,
 9117                    sender_id,
 9118                    lsp_request_id,
 9119                    get_document_symbols,
 9120                    None,
 9121                    &mut cx,
 9122                )
 9123                .await?;
 9124            }
 9125            Request::GetHover(get_hover) => {
 9126                let position = get_hover.position.clone().and_then(deserialize_anchor);
 9127                Self::query_lsp_locally::<GetHover>(
 9128                    lsp_store,
 9129                    server_id,
 9130                    sender_id,
 9131                    lsp_request_id,
 9132                    get_hover,
 9133                    position,
 9134                    &mut cx,
 9135                )
 9136                .await?;
 9137            }
 9138            Request::GetCodeActions(get_code_actions) => {
 9139                Self::query_lsp_locally::<GetCodeActions>(
 9140                    lsp_store,
 9141                    server_id,
 9142                    sender_id,
 9143                    lsp_request_id,
 9144                    get_code_actions,
 9145                    None,
 9146                    &mut cx,
 9147                )
 9148                .await?;
 9149            }
 9150            Request::GetSignatureHelp(get_signature_help) => {
 9151                let position = get_signature_help
 9152                    .position
 9153                    .clone()
 9154                    .and_then(deserialize_anchor);
 9155                Self::query_lsp_locally::<GetSignatureHelp>(
 9156                    lsp_store,
 9157                    server_id,
 9158                    sender_id,
 9159                    lsp_request_id,
 9160                    get_signature_help,
 9161                    position,
 9162                    &mut cx,
 9163                )
 9164                .await?;
 9165            }
 9166            Request::GetCodeLens(get_code_lens) => {
 9167                Self::query_lsp_locally::<GetCodeLens>(
 9168                    lsp_store,
 9169                    server_id,
 9170                    sender_id,
 9171                    lsp_request_id,
 9172                    get_code_lens,
 9173                    None,
 9174                    &mut cx,
 9175                )
 9176                .await?;
 9177            }
 9178            Request::GetDefinition(get_definition) => {
 9179                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9180                Self::query_lsp_locally::<GetDefinitions>(
 9181                    lsp_store,
 9182                    server_id,
 9183                    sender_id,
 9184                    lsp_request_id,
 9185                    get_definition,
 9186                    position,
 9187                    &mut cx,
 9188                )
 9189                .await?;
 9190            }
 9191            Request::GetDeclaration(get_declaration) => {
 9192                let position = get_declaration
 9193                    .position
 9194                    .clone()
 9195                    .and_then(deserialize_anchor);
 9196                Self::query_lsp_locally::<GetDeclarations>(
 9197                    lsp_store,
 9198                    server_id,
 9199                    sender_id,
 9200                    lsp_request_id,
 9201                    get_declaration,
 9202                    position,
 9203                    &mut cx,
 9204                )
 9205                .await?;
 9206            }
 9207            Request::GetTypeDefinition(get_type_definition) => {
 9208                let position = get_type_definition
 9209                    .position
 9210                    .clone()
 9211                    .and_then(deserialize_anchor);
 9212                Self::query_lsp_locally::<GetTypeDefinitions>(
 9213                    lsp_store,
 9214                    server_id,
 9215                    sender_id,
 9216                    lsp_request_id,
 9217                    get_type_definition,
 9218                    position,
 9219                    &mut cx,
 9220                )
 9221                .await?;
 9222            }
 9223            Request::GetImplementation(get_implementation) => {
 9224                let position = get_implementation
 9225                    .position
 9226                    .clone()
 9227                    .and_then(deserialize_anchor);
 9228                Self::query_lsp_locally::<GetImplementations>(
 9229                    lsp_store,
 9230                    server_id,
 9231                    sender_id,
 9232                    lsp_request_id,
 9233                    get_implementation,
 9234                    position,
 9235                    &mut cx,
 9236                )
 9237                .await?;
 9238            }
 9239            Request::InlayHints(inlay_hints) => {
 9240                let query_start = inlay_hints
 9241                    .start
 9242                    .clone()
 9243                    .and_then(deserialize_anchor)
 9244                    .context("invalid inlay hints range start")?;
 9245                let query_end = inlay_hints
 9246                    .end
 9247                    .clone()
 9248                    .and_then(deserialize_anchor)
 9249                    .context("invalid inlay hints range end")?;
 9250                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9251                    &lsp_store,
 9252                    server_id,
 9253                    lsp_request_id,
 9254                    &inlay_hints,
 9255                    query_start..query_end,
 9256                    &mut cx,
 9257                )
 9258                .await
 9259                .context("preparing inlay hints request")?;
 9260                Self::query_lsp_locally::<InlayHints>(
 9261                    lsp_store,
 9262                    server_id,
 9263                    sender_id,
 9264                    lsp_request_id,
 9265                    inlay_hints,
 9266                    None,
 9267                    &mut cx,
 9268                )
 9269                .await
 9270                .context("querying for inlay hints")?
 9271            }
 9272            //////////////////////////////
 9273            // Below are LSP queries that need to fetch more data,
 9274            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 9275            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9276                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 9277                    &lsp_store,
 9278                    &get_document_diagnostics,
 9279                    &mut cx,
 9280                )
 9281                .await?;
 9282                lsp_store.update(&mut cx, |lsp_store, cx| {
 9283                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9284                    let key = LspKey {
 9285                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9286                        server_queried: server_id,
 9287                    };
 9288                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9289                    ) {
 9290                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9291                            lsp_requests.clear();
 9292                        };
 9293                    }
 9294
 9295                    lsp_data.lsp_requests.entry(key).or_default().insert(
 9296                        lsp_request_id,
 9297                        cx.spawn(async move |lsp_store, cx| {
 9298                            let diagnostics_pull = lsp_store
 9299                                .update(cx, |lsp_store, cx| {
 9300                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9301                                })
 9302                                .ok();
 9303                            if let Some(diagnostics_pull) = diagnostics_pull {
 9304                                match diagnostics_pull.await {
 9305                                    Ok(()) => {}
 9306                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9307                                };
 9308                            }
 9309                        }),
 9310                    );
 9311                });
 9312            }
 9313            Request::SemanticTokens(semantic_tokens) => {
 9314                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9315                    &lsp_store,
 9316                    &semantic_tokens,
 9317                    &mut cx,
 9318                )
 9319                .await?;
 9320                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9321                lsp_store.update(&mut cx, |lsp_store, cx| {
 9322                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9323                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9324                        let key = LspKey {
 9325                            request_type: TypeId::of::<SemanticTokensFull>(),
 9326                            server_queried: server_id,
 9327                        };
 9328                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9329                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9330                                lsp_requests.clear();
 9331                            };
 9332                        }
 9333
 9334                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9335                            lsp_request_id,
 9336                            cx.spawn(async move |lsp_store, cx| {
 9337                                let tokens_fetch = lsp_store
 9338                                    .update(cx, |lsp_store, cx| {
 9339                                        lsp_store
 9340                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9341                                    })
 9342                                    .ok();
 9343                                if let Some(tokens_fetch) = tokens_fetch {
 9344                                    let new_tokens = tokens_fetch.await;
 9345                                    if let Some(new_tokens) = new_tokens {
 9346                                        lsp_store
 9347                                            .update(cx, |lsp_store, cx| {
 9348                                                let response = new_tokens
 9349                                                    .into_iter()
 9350                                                    .map(|(server_id, response)| {
 9351                                                        (
 9352                                                            server_id.to_proto(),
 9353                                                            SemanticTokensFull::response_to_proto(
 9354                                                                response,
 9355                                                                lsp_store,
 9356                                                                sender_id,
 9357                                                                &buffer_version,
 9358                                                                cx,
 9359                                                            ),
 9360                                                        )
 9361                                                    })
 9362                                                    .collect::<HashMap<_, _>>();
 9363                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9364                                                    project_id,
 9365                                                    lsp_request_id,
 9366                                                    response,
 9367                                                ) {
 9368                                                    Ok(()) => {}
 9369                                                    Err(e) => {
 9370                                                        log::error!(
 9371                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9372                                                        )
 9373                                                    }
 9374                                                }
 9375                                            })
 9376                                            .ok();
 9377                                    }
 9378                                }
 9379                            }),
 9380                        );
 9381                    }
 9382                });
 9383            }
 9384        }
 9385        Ok(proto::Ack {})
 9386    }
 9387
 9388    async fn handle_lsp_query_response(
 9389        lsp_store: Entity<Self>,
 9390        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9391        cx: AsyncApp,
 9392    ) -> Result<()> {
 9393        lsp_store.read_with(&cx, |lsp_store, _| {
 9394            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9395                upstream_client.handle_lsp_response(envelope.clone());
 9396            }
 9397        });
 9398        Ok(())
 9399    }
 9400
 9401    async fn handle_apply_code_action(
 9402        this: Entity<Self>,
 9403        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9404        mut cx: AsyncApp,
 9405    ) -> Result<proto::ApplyCodeActionResponse> {
 9406        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9407        let action =
 9408            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9409        let apply_code_action = this.update(&mut cx, |this, cx| {
 9410            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9411            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9412            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9413        })?;
 9414
 9415        let project_transaction = apply_code_action.await?;
 9416        let project_transaction = this.update(&mut cx, |this, cx| {
 9417            this.buffer_store.update(cx, |buffer_store, cx| {
 9418                buffer_store.serialize_project_transaction_for_peer(
 9419                    project_transaction,
 9420                    sender_id,
 9421                    cx,
 9422                )
 9423            })
 9424        });
 9425        Ok(proto::ApplyCodeActionResponse {
 9426            transaction: Some(project_transaction),
 9427        })
 9428    }
 9429
 9430    async fn handle_register_buffer_with_language_servers(
 9431        this: Entity<Self>,
 9432        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9433        mut cx: AsyncApp,
 9434    ) -> Result<proto::Ack> {
 9435        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9436        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9437        this.update(&mut cx, |this, cx| {
 9438            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9439                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9440                    project_id: upstream_project_id,
 9441                    buffer_id: buffer_id.to_proto(),
 9442                    only_servers: envelope.payload.only_servers,
 9443                });
 9444            }
 9445
 9446            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9447                anyhow::bail!("buffer is not open");
 9448            };
 9449
 9450            let handle = this.register_buffer_with_language_servers(
 9451                &buffer,
 9452                envelope
 9453                    .payload
 9454                    .only_servers
 9455                    .into_iter()
 9456                    .filter_map(|selector| {
 9457                        Some(match selector.selector? {
 9458                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9459                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9460                            }
 9461                            proto::language_server_selector::Selector::Name(name) => {
 9462                                LanguageServerSelector::Name(LanguageServerName(
 9463                                    SharedString::from(name),
 9464                                ))
 9465                            }
 9466                        })
 9467                    })
 9468                    .collect(),
 9469                false,
 9470                cx,
 9471            );
 9472            // Pull diagnostics for the buffer even if it was already registered.
 9473            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9474            // but it's unclear if we need it.
 9475            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9476                .detach();
 9477            this.buffer_store().update(cx, |buffer_store, _| {
 9478                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9479            });
 9480
 9481            Ok(())
 9482        })?;
 9483        Ok(proto::Ack {})
 9484    }
 9485
 9486    async fn handle_rename_project_entry(
 9487        this: Entity<Self>,
 9488        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9489        mut cx: AsyncApp,
 9490    ) -> Result<proto::ProjectEntryResponse> {
 9491        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9492        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9493        let new_path =
 9494            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9495
 9496        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9497            .update(&mut cx, |this, cx| {
 9498                let (worktree, entry) = this
 9499                    .worktree_store
 9500                    .read(cx)
 9501                    .worktree_and_entry_for_id(entry_id, cx)?;
 9502                let new_worktree = this
 9503                    .worktree_store
 9504                    .read(cx)
 9505                    .worktree_for_id(new_worktree_id, cx)?;
 9506                Some((
 9507                    this.worktree_store.clone(),
 9508                    worktree,
 9509                    new_worktree,
 9510                    entry.clone(),
 9511                ))
 9512            })
 9513            .context("worktree not found")?;
 9514        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9515            (worktree.absolutize(&old_entry.path), worktree.id())
 9516        });
 9517        let new_abs_path =
 9518            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9519
 9520        let _transaction = Self::will_rename_entry(
 9521            this.downgrade(),
 9522            old_worktree_id,
 9523            &old_abs_path,
 9524            &new_abs_path,
 9525            old_entry.is_dir(),
 9526            cx.clone(),
 9527        )
 9528        .await;
 9529        let response = WorktreeStore::handle_rename_project_entry(
 9530            worktree_store,
 9531            envelope.payload,
 9532            cx.clone(),
 9533        )
 9534        .await;
 9535        this.read_with(&cx, |this, _| {
 9536            this.did_rename_entry(
 9537                old_worktree_id,
 9538                &old_abs_path,
 9539                &new_abs_path,
 9540                old_entry.is_dir(),
 9541            );
 9542        });
 9543        response
 9544    }
 9545
 9546    async fn handle_update_diagnostic_summary(
 9547        this: Entity<Self>,
 9548        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9549        mut cx: AsyncApp,
 9550    ) -> Result<()> {
 9551        this.update(&mut cx, |lsp_store, cx| {
 9552            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9553            let mut updated_diagnostics_paths = HashMap::default();
 9554            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9555            for message_summary in envelope
 9556                .payload
 9557                .summary
 9558                .into_iter()
 9559                .chain(envelope.payload.more_summaries)
 9560            {
 9561                let project_path = ProjectPath {
 9562                    worktree_id,
 9563                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9564                };
 9565                let path = project_path.path.clone();
 9566                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9567                let summary = DiagnosticSummary {
 9568                    error_count: message_summary.error_count as usize,
 9569                    warning_count: message_summary.warning_count as usize,
 9570                };
 9571
 9572                if summary.is_empty() {
 9573                    if let Some(worktree_summaries) =
 9574                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9575                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9576                    {
 9577                        summaries.remove(&server_id);
 9578                        if summaries.is_empty() {
 9579                            worktree_summaries.remove(&path);
 9580                        }
 9581                    }
 9582                } else {
 9583                    lsp_store
 9584                        .diagnostic_summaries
 9585                        .entry(worktree_id)
 9586                        .or_default()
 9587                        .entry(path)
 9588                        .or_default()
 9589                        .insert(server_id, summary);
 9590                }
 9591
 9592                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9593                    match &mut diagnostics_summary {
 9594                        Some(diagnostics_summary) => {
 9595                            diagnostics_summary
 9596                                .more_summaries
 9597                                .push(proto::DiagnosticSummary {
 9598                                    path: project_path.path.as_ref().to_proto(),
 9599                                    language_server_id: server_id.0 as u64,
 9600                                    error_count: summary.error_count as u32,
 9601                                    warning_count: summary.warning_count as u32,
 9602                                })
 9603                        }
 9604                        None => {
 9605                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9606                                project_id: *project_id,
 9607                                worktree_id: worktree_id.to_proto(),
 9608                                summary: Some(proto::DiagnosticSummary {
 9609                                    path: project_path.path.as_ref().to_proto(),
 9610                                    language_server_id: server_id.0 as u64,
 9611                                    error_count: summary.error_count as u32,
 9612                                    warning_count: summary.warning_count as u32,
 9613                                }),
 9614                                more_summaries: Vec::new(),
 9615                            })
 9616                        }
 9617                    }
 9618                }
 9619                updated_diagnostics_paths
 9620                    .entry(server_id)
 9621                    .or_insert_with(Vec::new)
 9622                    .push(project_path);
 9623            }
 9624
 9625            if let Some((diagnostics_summary, (downstream_client, _))) =
 9626                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9627            {
 9628                downstream_client.send(diagnostics_summary).log_err();
 9629            }
 9630            for (server_id, paths) in updated_diagnostics_paths {
 9631                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9632            }
 9633            Ok(())
 9634        })
 9635    }
 9636
 9637    async fn handle_start_language_server(
 9638        lsp_store: Entity<Self>,
 9639        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9640        mut cx: AsyncApp,
 9641    ) -> Result<()> {
 9642        let server = envelope.payload.server.context("invalid server")?;
 9643        let server_capabilities =
 9644            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9645                .with_context(|| {
 9646                    format!(
 9647                        "incorrect server capabilities {}",
 9648                        envelope.payload.capabilities
 9649                    )
 9650                })?;
 9651        lsp_store.update(&mut cx, |lsp_store, cx| {
 9652            let server_id = LanguageServerId(server.id as usize);
 9653            let server_name = LanguageServerName::from_proto(server.name.clone());
 9654            lsp_store
 9655                .lsp_server_capabilities
 9656                .insert(server_id, server_capabilities);
 9657            lsp_store.language_server_statuses.insert(
 9658                server_id,
 9659                LanguageServerStatus {
 9660                    name: server_name.clone(),
 9661                    server_version: None,
 9662                    server_readable_version: None,
 9663                    pending_work: Default::default(),
 9664                    has_pending_diagnostic_updates: false,
 9665                    progress_tokens: Default::default(),
 9666                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9667                    binary: None,
 9668                    configuration: None,
 9669                    workspace_folders: BTreeSet::new(),
 9670                    process_id: None,
 9671                },
 9672            );
 9673            cx.emit(LspStoreEvent::LanguageServerAdded(
 9674                server_id,
 9675                server_name,
 9676                server.worktree_id.map(WorktreeId::from_proto),
 9677            ));
 9678            cx.notify();
 9679        });
 9680        Ok(())
 9681    }
 9682
 9683    async fn handle_update_language_server(
 9684        lsp_store: Entity<Self>,
 9685        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9686        mut cx: AsyncApp,
 9687    ) -> Result<()> {
 9688        lsp_store.update(&mut cx, |lsp_store, cx| {
 9689            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9690
 9691            match envelope.payload.variant.context("invalid variant")? {
 9692                proto::update_language_server::Variant::WorkStart(payload) => {
 9693                    lsp_store.on_lsp_work_start(
 9694                        language_server_id,
 9695                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9696                            .context("invalid progress token value")?,
 9697                        LanguageServerProgress {
 9698                            title: payload.title,
 9699                            is_disk_based_diagnostics_progress: false,
 9700                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9701                            message: payload.message,
 9702                            percentage: payload.percentage.map(|p| p as usize),
 9703                            last_update_at: cx.background_executor().now(),
 9704                        },
 9705                        cx,
 9706                    );
 9707                }
 9708                proto::update_language_server::Variant::WorkProgress(payload) => {
 9709                    lsp_store.on_lsp_work_progress(
 9710                        language_server_id,
 9711                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9712                            .context("invalid progress token value")?,
 9713                        LanguageServerProgress {
 9714                            title: None,
 9715                            is_disk_based_diagnostics_progress: false,
 9716                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9717                            message: payload.message,
 9718                            percentage: payload.percentage.map(|p| p as usize),
 9719                            last_update_at: cx.background_executor().now(),
 9720                        },
 9721                        cx,
 9722                    );
 9723                }
 9724
 9725                proto::update_language_server::Variant::WorkEnd(payload) => {
 9726                    lsp_store.on_lsp_work_end(
 9727                        language_server_id,
 9728                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9729                            .context("invalid progress token value")?,
 9730                        cx,
 9731                    );
 9732                }
 9733
 9734                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9735                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9736                }
 9737
 9738                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9739                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9740                }
 9741
 9742                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9743                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9744                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9745                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9746                        language_server_id,
 9747                        name: envelope
 9748                            .payload
 9749                            .server_name
 9750                            .map(SharedString::new)
 9751                            .map(LanguageServerName),
 9752                        message: non_lsp,
 9753                    });
 9754                }
 9755            }
 9756
 9757            Ok(())
 9758        })
 9759    }
 9760
 9761    async fn handle_language_server_log(
 9762        this: Entity<Self>,
 9763        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9764        mut cx: AsyncApp,
 9765    ) -> Result<()> {
 9766        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9767        let log_type = envelope
 9768            .payload
 9769            .log_type
 9770            .map(LanguageServerLogType::from_proto)
 9771            .context("invalid language server log type")?;
 9772
 9773        let message = envelope.payload.message;
 9774
 9775        this.update(&mut cx, |_, cx| {
 9776            cx.emit(LspStoreEvent::LanguageServerLog(
 9777                language_server_id,
 9778                log_type,
 9779                message,
 9780            ));
 9781        });
 9782        Ok(())
 9783    }
 9784
 9785    async fn handle_lsp_ext_cancel_flycheck(
 9786        lsp_store: Entity<Self>,
 9787        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9788        cx: AsyncApp,
 9789    ) -> Result<proto::Ack> {
 9790        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9791        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9792            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9793                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9794            } else {
 9795                None
 9796            }
 9797        });
 9798        if let Some(task) = task {
 9799            task.context("handling lsp ext cancel flycheck")?;
 9800        }
 9801
 9802        Ok(proto::Ack {})
 9803    }
 9804
 9805    async fn handle_lsp_ext_run_flycheck(
 9806        lsp_store: Entity<Self>,
 9807        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9808        mut cx: AsyncApp,
 9809    ) -> Result<proto::Ack> {
 9810        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9811        lsp_store.update(&mut cx, |lsp_store, cx| {
 9812            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9813                let text_document = if envelope.payload.current_file_only {
 9814                    let buffer_id = envelope
 9815                        .payload
 9816                        .buffer_id
 9817                        .map(|id| BufferId::new(id))
 9818                        .transpose()?;
 9819                    buffer_id
 9820                        .and_then(|buffer_id| {
 9821                            lsp_store
 9822                                .buffer_store()
 9823                                .read(cx)
 9824                                .get(buffer_id)
 9825                                .and_then(|buffer| {
 9826                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9827                                })
 9828                                .map(|path| make_text_document_identifier(&path))
 9829                        })
 9830                        .transpose()?
 9831                } else {
 9832                    None
 9833                };
 9834                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9835                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9836                )?;
 9837            }
 9838            anyhow::Ok(())
 9839        })?;
 9840
 9841        Ok(proto::Ack {})
 9842    }
 9843
 9844    async fn handle_lsp_ext_clear_flycheck(
 9845        lsp_store: Entity<Self>,
 9846        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9847        cx: AsyncApp,
 9848    ) -> Result<proto::Ack> {
 9849        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9850        lsp_store.read_with(&cx, |lsp_store, _| {
 9851            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9852                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9853            } else {
 9854                None
 9855            }
 9856        });
 9857
 9858        Ok(proto::Ack {})
 9859    }
 9860
 9861    pub fn disk_based_diagnostics_started(
 9862        &mut self,
 9863        language_server_id: LanguageServerId,
 9864        cx: &mut Context<Self>,
 9865    ) {
 9866        if let Some(language_server_status) =
 9867            self.language_server_statuses.get_mut(&language_server_id)
 9868        {
 9869            language_server_status.has_pending_diagnostic_updates = true;
 9870        }
 9871
 9872        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9873        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9874            language_server_id,
 9875            name: self
 9876                .language_server_adapter_for_id(language_server_id)
 9877                .map(|adapter| adapter.name()),
 9878            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9879                Default::default(),
 9880            ),
 9881        })
 9882    }
 9883
 9884    pub fn disk_based_diagnostics_finished(
 9885        &mut self,
 9886        language_server_id: LanguageServerId,
 9887        cx: &mut Context<Self>,
 9888    ) {
 9889        if let Some(language_server_status) =
 9890            self.language_server_statuses.get_mut(&language_server_id)
 9891        {
 9892            language_server_status.has_pending_diagnostic_updates = false;
 9893        }
 9894
 9895        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9896        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9897            language_server_id,
 9898            name: self
 9899                .language_server_adapter_for_id(language_server_id)
 9900                .map(|adapter| adapter.name()),
 9901            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9902                Default::default(),
 9903            ),
 9904        })
 9905    }
 9906
 9907    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9908    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9909    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9910    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9911    // the language server might take some time to publish diagnostics.
 9912    fn simulate_disk_based_diagnostics_events_if_needed(
 9913        &mut self,
 9914        language_server_id: LanguageServerId,
 9915        cx: &mut Context<Self>,
 9916    ) {
 9917        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9918
 9919        let Some(LanguageServerState::Running {
 9920            simulate_disk_based_diagnostics_completion,
 9921            adapter,
 9922            ..
 9923        }) = self
 9924            .as_local_mut()
 9925            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9926        else {
 9927            return;
 9928        };
 9929
 9930        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9931            return;
 9932        }
 9933
 9934        let prev_task =
 9935            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9936                cx.background_executor()
 9937                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9938                    .await;
 9939
 9940                this.update(cx, |this, cx| {
 9941                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9942
 9943                    if let Some(LanguageServerState::Running {
 9944                        simulate_disk_based_diagnostics_completion,
 9945                        ..
 9946                    }) = this.as_local_mut().and_then(|local_store| {
 9947                        local_store.language_servers.get_mut(&language_server_id)
 9948                    }) {
 9949                        *simulate_disk_based_diagnostics_completion = None;
 9950                    }
 9951                })
 9952                .ok();
 9953            }));
 9954
 9955        if prev_task.is_none() {
 9956            self.disk_based_diagnostics_started(language_server_id, cx);
 9957        }
 9958    }
 9959
 9960    pub fn language_server_statuses(
 9961        &self,
 9962    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9963        self.language_server_statuses
 9964            .iter()
 9965            .map(|(key, value)| (*key, value))
 9966    }
 9967
 9968    pub(super) fn did_rename_entry(
 9969        &self,
 9970        worktree_id: WorktreeId,
 9971        old_path: &Path,
 9972        new_path: &Path,
 9973        is_dir: bool,
 9974    ) {
 9975        maybe!({
 9976            let local_store = self.as_local()?;
 9977
 9978            let old_uri = lsp::Uri::from_file_path(old_path)
 9979                .ok()
 9980                .map(|uri| uri.to_string())?;
 9981            let new_uri = lsp::Uri::from_file_path(new_path)
 9982                .ok()
 9983                .map(|uri| uri.to_string())?;
 9984
 9985            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9986                let Some(filter) = local_store
 9987                    .language_server_paths_watched_for_rename
 9988                    .get(&language_server.server_id())
 9989                else {
 9990                    continue;
 9991                };
 9992
 9993                if filter.should_send_did_rename(&old_uri, is_dir) {
 9994                    language_server
 9995                        .notify::<DidRenameFiles>(RenameFilesParams {
 9996                            files: vec![FileRename {
 9997                                old_uri: old_uri.clone(),
 9998                                new_uri: new_uri.clone(),
 9999                            }],
10000                        })
10001                        .ok();
10002                }
10003            }
10004            Some(())
10005        });
10006    }
10007
10008    pub(super) fn will_rename_entry(
10009        this: WeakEntity<Self>,
10010        worktree_id: WorktreeId,
10011        old_path: &Path,
10012        new_path: &Path,
10013        is_dir: bool,
10014        cx: AsyncApp,
10015    ) -> Task<ProjectTransaction> {
10016        let old_uri = lsp::Uri::from_file_path(old_path)
10017            .ok()
10018            .map(|uri| uri.to_string());
10019        let new_uri = lsp::Uri::from_file_path(new_path)
10020            .ok()
10021            .map(|uri| uri.to_string());
10022        cx.spawn(async move |cx| {
10023            let mut tasks = vec![];
10024            this.update(cx, |this, cx| {
10025                let local_store = this.as_local()?;
10026                let old_uri = old_uri?;
10027                let new_uri = new_uri?;
10028                for language_server in local_store.language_servers_for_worktree(worktree_id) {
10029                    let Some(filter) = local_store
10030                        .language_server_paths_watched_for_rename
10031                        .get(&language_server.server_id())
10032                    else {
10033                        continue;
10034                    };
10035
10036                    if !filter.should_send_will_rename(&old_uri, is_dir) {
10037                        continue;
10038                    }
10039                    let request_timeout = ProjectSettings::get_global(cx)
10040                        .global_lsp_settings
10041                        .get_request_timeout();
10042
10043                    let apply_edit = cx.spawn({
10044                        let old_uri = old_uri.clone();
10045                        let new_uri = new_uri.clone();
10046                        let language_server = language_server.clone();
10047                        async move |this, cx| {
10048                            let edit = language_server
10049                                .request::<WillRenameFiles>(
10050                                    RenameFilesParams {
10051                                        files: vec![FileRename { old_uri, new_uri }],
10052                                    },
10053                                    request_timeout,
10054                                )
10055                                .await
10056                                .into_response()
10057                                .context("will rename files")
10058                                .log_err()
10059                                .flatten()?;
10060
10061                            LocalLspStore::deserialize_workspace_edit(
10062                                this.upgrade()?,
10063                                edit,
10064                                false,
10065                                language_server.clone(),
10066                                cx,
10067                            )
10068                            .await
10069                            .ok()
10070                        }
10071                    });
10072                    tasks.push(apply_edit);
10073                }
10074                Some(())
10075            })
10076            .ok()
10077            .flatten();
10078            let mut merged_transaction = ProjectTransaction::default();
10079            for task in tasks {
10080                // Await on tasks sequentially so that the order of application of edits is deterministic
10081                // (at least with regards to the order of registration of language servers)
10082                if let Some(transaction) = task.await {
10083                    for (buffer, buffer_transaction) in transaction.0 {
10084                        merged_transaction.0.insert(buffer, buffer_transaction);
10085                    }
10086                }
10087            }
10088            merged_transaction
10089        })
10090    }
10091
10092    fn lsp_notify_abs_paths_changed(
10093        &mut self,
10094        server_id: LanguageServerId,
10095        changes: Vec<PathEvent>,
10096    ) {
10097        maybe!({
10098            let server = self.language_server_for_id(server_id)?;
10099            let changes = changes
10100                .into_iter()
10101                .filter_map(|event| {
10102                    let typ = match event.kind? {
10103                        PathEventKind::Created => lsp::FileChangeType::CREATED,
10104                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
10105                        PathEventKind::Changed | PathEventKind::Rescan => {
10106                            lsp::FileChangeType::CHANGED
10107                        }
10108                    };
10109                    Some(lsp::FileEvent {
10110                        uri: file_path_to_lsp_url(&event.path).log_err()?,
10111                        typ,
10112                    })
10113                })
10114                .collect::<Vec<_>>();
10115            if !changes.is_empty() {
10116                server
10117                    .notify::<lsp::notification::DidChangeWatchedFiles>(
10118                        lsp::DidChangeWatchedFilesParams { changes },
10119                    )
10120                    .ok();
10121            }
10122            Some(())
10123        });
10124    }
10125
10126    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
10127        self.as_local()?.language_server_for_id(id)
10128    }
10129
10130    fn on_lsp_progress(
10131        &mut self,
10132        progress_params: lsp::ProgressParams,
10133        language_server_id: LanguageServerId,
10134        disk_based_diagnostics_progress_token: Option<String>,
10135        cx: &mut Context<Self>,
10136    ) {
10137        match progress_params.value {
10138            lsp::ProgressParamsValue::WorkDone(progress) => {
10139                self.handle_work_done_progress(
10140                    progress,
10141                    language_server_id,
10142                    disk_based_diagnostics_progress_token,
10143                    ProgressToken::from_lsp(progress_params.token),
10144                    cx,
10145                );
10146            }
10147            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
10148                let registration_id = match progress_params.token {
10149                    lsp::NumberOrString::Number(_) => None,
10150                    lsp::NumberOrString::String(token) => token
10151                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
10152                        .map(|(_, id)| id.to_owned()),
10153                };
10154                if let Some(LanguageServerState::Running {
10155                    workspace_diagnostics_refresh_tasks,
10156                    ..
10157                }) = self
10158                    .as_local_mut()
10159                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
10160                    && let Some(workspace_diagnostics) =
10161                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
10162                {
10163                    workspace_diagnostics.progress_tx.try_send(()).ok();
10164                    self.apply_workspace_diagnostic_report(
10165                        language_server_id,
10166                        report,
10167                        registration_id.map(SharedString::from),
10168                        cx,
10169                    )
10170                }
10171            }
10172        }
10173    }
10174
10175    fn handle_work_done_progress(
10176        &mut self,
10177        progress: lsp::WorkDoneProgress,
10178        language_server_id: LanguageServerId,
10179        disk_based_diagnostics_progress_token: Option<String>,
10180        token: ProgressToken,
10181        cx: &mut Context<Self>,
10182    ) {
10183        let language_server_status =
10184            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10185                status
10186            } else {
10187                return;
10188            };
10189
10190        if !language_server_status.progress_tokens.contains(&token) {
10191            return;
10192        }
10193
10194        let is_disk_based_diagnostics_progress =
10195            if let (Some(disk_based_token), ProgressToken::String(token)) =
10196                (&disk_based_diagnostics_progress_token, &token)
10197            {
10198                token.starts_with(disk_based_token)
10199            } else {
10200                false
10201            };
10202
10203        match progress {
10204            lsp::WorkDoneProgress::Begin(report) => {
10205                if is_disk_based_diagnostics_progress {
10206                    self.disk_based_diagnostics_started(language_server_id, cx);
10207                }
10208                self.on_lsp_work_start(
10209                    language_server_id,
10210                    token.clone(),
10211                    LanguageServerProgress {
10212                        title: Some(report.title),
10213                        is_disk_based_diagnostics_progress,
10214                        is_cancellable: report.cancellable.unwrap_or(false),
10215                        message: report.message.clone(),
10216                        percentage: report.percentage.map(|p| p as usize),
10217                        last_update_at: cx.background_executor().now(),
10218                    },
10219                    cx,
10220                );
10221            }
10222            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10223                language_server_id,
10224                token,
10225                LanguageServerProgress {
10226                    title: None,
10227                    is_disk_based_diagnostics_progress,
10228                    is_cancellable: report.cancellable.unwrap_or(false),
10229                    message: report.message,
10230                    percentage: report.percentage.map(|p| p as usize),
10231                    last_update_at: cx.background_executor().now(),
10232                },
10233                cx,
10234            ),
10235            lsp::WorkDoneProgress::End(_) => {
10236                language_server_status.progress_tokens.remove(&token);
10237                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10238                if is_disk_based_diagnostics_progress {
10239                    self.disk_based_diagnostics_finished(language_server_id, cx);
10240                }
10241            }
10242        }
10243    }
10244
10245    fn on_lsp_work_start(
10246        &mut self,
10247        language_server_id: LanguageServerId,
10248        token: ProgressToken,
10249        progress: LanguageServerProgress,
10250        cx: &mut Context<Self>,
10251    ) {
10252        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10253            status.pending_work.insert(token.clone(), progress.clone());
10254            cx.notify();
10255        }
10256        cx.emit(LspStoreEvent::LanguageServerUpdate {
10257            language_server_id,
10258            name: self
10259                .language_server_adapter_for_id(language_server_id)
10260                .map(|adapter| adapter.name()),
10261            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10262                token: Some(token.to_proto()),
10263                title: progress.title,
10264                message: progress.message,
10265                percentage: progress.percentage.map(|p| p as u32),
10266                is_cancellable: Some(progress.is_cancellable),
10267            }),
10268        })
10269    }
10270
10271    fn on_lsp_work_progress(
10272        &mut self,
10273        language_server_id: LanguageServerId,
10274        token: ProgressToken,
10275        progress: LanguageServerProgress,
10276        cx: &mut Context<Self>,
10277    ) {
10278        let mut did_update = false;
10279        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10280            match status.pending_work.entry(token.clone()) {
10281                btree_map::Entry::Vacant(entry) => {
10282                    entry.insert(progress.clone());
10283                    did_update = true;
10284                }
10285                btree_map::Entry::Occupied(mut entry) => {
10286                    let entry = entry.get_mut();
10287                    if (progress.last_update_at - entry.last_update_at)
10288                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10289                    {
10290                        entry.last_update_at = progress.last_update_at;
10291                        if progress.message.is_some() {
10292                            entry.message = progress.message.clone();
10293                        }
10294                        if progress.percentage.is_some() {
10295                            entry.percentage = progress.percentage;
10296                        }
10297                        if progress.is_cancellable != entry.is_cancellable {
10298                            entry.is_cancellable = progress.is_cancellable;
10299                        }
10300                        did_update = true;
10301                    }
10302                }
10303            }
10304        }
10305
10306        if did_update {
10307            cx.emit(LspStoreEvent::LanguageServerUpdate {
10308                language_server_id,
10309                name: self
10310                    .language_server_adapter_for_id(language_server_id)
10311                    .map(|adapter| adapter.name()),
10312                message: proto::update_language_server::Variant::WorkProgress(
10313                    proto::LspWorkProgress {
10314                        token: Some(token.to_proto()),
10315                        message: progress.message,
10316                        percentage: progress.percentage.map(|p| p as u32),
10317                        is_cancellable: Some(progress.is_cancellable),
10318                    },
10319                ),
10320            })
10321        }
10322    }
10323
10324    fn on_lsp_work_end(
10325        &mut self,
10326        language_server_id: LanguageServerId,
10327        token: ProgressToken,
10328        cx: &mut Context<Self>,
10329    ) {
10330        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10331            if let Some(work) = status.pending_work.remove(&token)
10332                && !work.is_disk_based_diagnostics_progress
10333            {
10334                cx.emit(LspStoreEvent::RefreshInlayHints {
10335                    server_id: language_server_id,
10336                    request_id: None,
10337                });
10338            }
10339            cx.notify();
10340        }
10341
10342        cx.emit(LspStoreEvent::LanguageServerUpdate {
10343            language_server_id,
10344            name: self
10345                .language_server_adapter_for_id(language_server_id)
10346                .map(|adapter| adapter.name()),
10347            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10348                token: Some(token.to_proto()),
10349            }),
10350        })
10351    }
10352
10353    pub async fn handle_resolve_completion_documentation(
10354        this: Entity<Self>,
10355        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10356        mut cx: AsyncApp,
10357    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10358        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10359
10360        let completion = this
10361            .read_with(&cx, |this, cx| {
10362                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10363                let server = this
10364                    .language_server_for_id(id)
10365                    .with_context(|| format!("No language server {id}"))?;
10366
10367                let request_timeout = ProjectSettings::get_global(cx)
10368                    .global_lsp_settings
10369                    .get_request_timeout();
10370
10371                anyhow::Ok(cx.background_spawn(async move {
10372                    let can_resolve = server
10373                        .capabilities()
10374                        .completion_provider
10375                        .as_ref()
10376                        .and_then(|options| options.resolve_provider)
10377                        .unwrap_or(false);
10378                    if can_resolve {
10379                        server
10380                            .request::<lsp::request::ResolveCompletionItem>(
10381                                lsp_completion,
10382                                request_timeout,
10383                            )
10384                            .await
10385                            .into_response()
10386                            .context("resolve completion item")
10387                    } else {
10388                        anyhow::Ok(lsp_completion)
10389                    }
10390                }))
10391            })?
10392            .await?;
10393
10394        let mut documentation_is_markdown = false;
10395        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10396        let documentation = match completion.documentation {
10397            Some(lsp::Documentation::String(text)) => text,
10398
10399            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10400                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10401                value
10402            }
10403
10404            _ => String::new(),
10405        };
10406
10407        // If we have a new buffer_id, that means we're talking to a new client
10408        // and want to check for new text_edits in the completion too.
10409        let mut old_replace_start = None;
10410        let mut old_replace_end = None;
10411        let mut old_insert_start = None;
10412        let mut old_insert_end = None;
10413        let mut new_text = String::default();
10414        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10415            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10416                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10417                anyhow::Ok(buffer.read(cx).snapshot())
10418            })?;
10419
10420            if let Some(text_edit) = completion.text_edit.as_ref() {
10421                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10422
10423                if let Some(mut edit) = edit {
10424                    LineEnding::normalize(&mut edit.new_text);
10425
10426                    new_text = edit.new_text;
10427                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10428                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10429                    if let Some(insert_range) = edit.insert_range {
10430                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10431                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10432                    }
10433                }
10434            }
10435        }
10436
10437        Ok(proto::ResolveCompletionDocumentationResponse {
10438            documentation,
10439            documentation_is_markdown,
10440            old_replace_start,
10441            old_replace_end,
10442            new_text,
10443            lsp_completion,
10444            old_insert_start,
10445            old_insert_end,
10446        })
10447    }
10448
10449    async fn handle_on_type_formatting(
10450        this: Entity<Self>,
10451        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10452        mut cx: AsyncApp,
10453    ) -> Result<proto::OnTypeFormattingResponse> {
10454        let on_type_formatting = this.update(&mut cx, |this, cx| {
10455            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10456            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10457            let position = envelope
10458                .payload
10459                .position
10460                .and_then(deserialize_anchor)
10461                .context("invalid position")?;
10462            anyhow::Ok(this.apply_on_type_formatting(
10463                buffer,
10464                position,
10465                envelope.payload.trigger.clone(),
10466                cx,
10467            ))
10468        })?;
10469
10470        let transaction = on_type_formatting
10471            .await?
10472            .as_ref()
10473            .map(language::proto::serialize_transaction);
10474        Ok(proto::OnTypeFormattingResponse { transaction })
10475    }
10476
10477    async fn handle_pull_workspace_diagnostics(
10478        lsp_store: Entity<Self>,
10479        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10480        mut cx: AsyncApp,
10481    ) -> Result<proto::Ack> {
10482        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10483        lsp_store.update(&mut cx, |lsp_store, _| {
10484            lsp_store.pull_workspace_diagnostics(server_id);
10485        });
10486        Ok(proto::Ack {})
10487    }
10488
10489    async fn handle_open_buffer_for_symbol(
10490        this: Entity<Self>,
10491        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10492        mut cx: AsyncApp,
10493    ) -> Result<proto::OpenBufferForSymbolResponse> {
10494        let peer_id = envelope.original_sender_id().unwrap_or_default();
10495        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10496        let symbol = Self::deserialize_symbol(symbol)?;
10497        this.read_with(&cx, |this, _| {
10498            if let SymbolLocation::OutsideProject {
10499                abs_path,
10500                signature,
10501            } = &symbol.path
10502            {
10503                let new_signature = this.symbol_signature(&abs_path);
10504                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10505            }
10506            Ok(())
10507        })?;
10508        let buffer = this
10509            .update(&mut cx, |this, cx| {
10510                this.open_buffer_for_symbol(
10511                    &Symbol {
10512                        language_server_name: symbol.language_server_name,
10513                        source_worktree_id: symbol.source_worktree_id,
10514                        source_language_server_id: symbol.source_language_server_id,
10515                        path: symbol.path,
10516                        name: symbol.name,
10517                        kind: symbol.kind,
10518                        range: symbol.range,
10519                        label: CodeLabel::default(),
10520                        container_name: symbol.container_name,
10521                    },
10522                    cx,
10523                )
10524            })
10525            .await?;
10526
10527        this.update(&mut cx, |this, cx| {
10528            let is_private = buffer
10529                .read(cx)
10530                .file()
10531                .map(|f| f.is_private())
10532                .unwrap_or_default();
10533            if is_private {
10534                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10535            } else {
10536                this.buffer_store
10537                    .update(cx, |buffer_store, cx| {
10538                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10539                    })
10540                    .detach_and_log_err(cx);
10541                let buffer_id = buffer.read(cx).remote_id().to_proto();
10542                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10543            }
10544        })
10545    }
10546
10547    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10548        let mut hasher = Sha256::new();
10549        hasher.update(abs_path.to_string_lossy().as_bytes());
10550        hasher.update(self.nonce.to_be_bytes());
10551        hasher.finalize().as_slice().try_into().unwrap()
10552    }
10553
10554    pub async fn handle_get_project_symbols(
10555        this: Entity<Self>,
10556        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10557        mut cx: AsyncApp,
10558    ) -> Result<proto::GetProjectSymbolsResponse> {
10559        let symbols = this
10560            .update(&mut cx, |this, cx| {
10561                this.symbols(&envelope.payload.query, cx)
10562            })
10563            .await?;
10564
10565        Ok(proto::GetProjectSymbolsResponse {
10566            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10567        })
10568    }
10569
10570    pub async fn handle_restart_language_servers(
10571        this: Entity<Self>,
10572        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10573        mut cx: AsyncApp,
10574    ) -> Result<proto::Ack> {
10575        this.update(&mut cx, |lsp_store, cx| {
10576            let buffers =
10577                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10578            lsp_store.restart_language_servers_for_buffers(
10579                buffers,
10580                envelope
10581                    .payload
10582                    .only_servers
10583                    .into_iter()
10584                    .filter_map(|selector| {
10585                        Some(match selector.selector? {
10586                            proto::language_server_selector::Selector::ServerId(server_id) => {
10587                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10588                            }
10589                            proto::language_server_selector::Selector::Name(name) => {
10590                                LanguageServerSelector::Name(LanguageServerName(
10591                                    SharedString::from(name),
10592                                ))
10593                            }
10594                        })
10595                    })
10596                    .collect(),
10597                cx,
10598            );
10599        });
10600
10601        Ok(proto::Ack {})
10602    }
10603
10604    pub async fn handle_stop_language_servers(
10605        lsp_store: Entity<Self>,
10606        envelope: TypedEnvelope<proto::StopLanguageServers>,
10607        mut cx: AsyncApp,
10608    ) -> Result<proto::Ack> {
10609        lsp_store.update(&mut cx, |lsp_store, cx| {
10610            if envelope.payload.all
10611                && envelope.payload.also_servers.is_empty()
10612                && envelope.payload.buffer_ids.is_empty()
10613            {
10614                lsp_store.stop_all_language_servers(cx);
10615            } else {
10616                let buffers =
10617                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10618                lsp_store
10619                    .stop_language_servers_for_buffers(
10620                        buffers,
10621                        envelope
10622                            .payload
10623                            .also_servers
10624                            .into_iter()
10625                            .filter_map(|selector| {
10626                                Some(match selector.selector? {
10627                                    proto::language_server_selector::Selector::ServerId(
10628                                        server_id,
10629                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10630                                        server_id,
10631                                    )),
10632                                    proto::language_server_selector::Selector::Name(name) => {
10633                                        LanguageServerSelector::Name(LanguageServerName(
10634                                            SharedString::from(name),
10635                                        ))
10636                                    }
10637                                })
10638                            })
10639                            .collect(),
10640                        cx,
10641                    )
10642                    .detach_and_log_err(cx);
10643            }
10644        });
10645
10646        Ok(proto::Ack {})
10647    }
10648
10649    pub async fn handle_cancel_language_server_work(
10650        lsp_store: Entity<Self>,
10651        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10652        mut cx: AsyncApp,
10653    ) -> Result<proto::Ack> {
10654        lsp_store.update(&mut cx, |lsp_store, cx| {
10655            if let Some(work) = envelope.payload.work {
10656                match work {
10657                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10658                        let buffers =
10659                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10660                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10661                    }
10662                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10663                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10664                        let token = work
10665                            .token
10666                            .map(|token| {
10667                                ProgressToken::from_proto(token)
10668                                    .context("invalid work progress token")
10669                            })
10670                            .transpose()?;
10671                        lsp_store.cancel_language_server_work(server_id, token, cx);
10672                    }
10673                }
10674            }
10675            anyhow::Ok(())
10676        })?;
10677
10678        Ok(proto::Ack {})
10679    }
10680
10681    fn buffer_ids_to_buffers(
10682        &mut self,
10683        buffer_ids: impl Iterator<Item = u64>,
10684        cx: &mut Context<Self>,
10685    ) -> Vec<Entity<Buffer>> {
10686        buffer_ids
10687            .into_iter()
10688            .flat_map(|buffer_id| {
10689                self.buffer_store
10690                    .read(cx)
10691                    .get(BufferId::new(buffer_id).log_err()?)
10692            })
10693            .collect::<Vec<_>>()
10694    }
10695
10696    async fn handle_apply_additional_edits_for_completion(
10697        this: Entity<Self>,
10698        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10699        mut cx: AsyncApp,
10700    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10701        let (buffer, completion, all_commit_ranges) = this.update(&mut cx, |this, cx| {
10702            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10703            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10704            let completion = Self::deserialize_completion(
10705                envelope.payload.completion.context("invalid completion")?,
10706            )?;
10707            let all_commit_ranges = envelope
10708                .payload
10709                .all_commit_ranges
10710                .into_iter()
10711                .map(language::proto::deserialize_anchor_range)
10712                .collect::<Result<Vec<_>, _>>()?;
10713            anyhow::Ok((buffer, completion, all_commit_ranges))
10714        })?;
10715
10716        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10717            this.apply_additional_edits_for_completion(
10718                buffer,
10719                Rc::new(RefCell::new(Box::new([Completion {
10720                    replace_range: completion.replace_range,
10721                    new_text: completion.new_text,
10722                    source: completion.source,
10723                    documentation: None,
10724                    label: CodeLabel::default(),
10725                    match_start: None,
10726                    snippet_deduplication_key: None,
10727                    insert_text_mode: None,
10728                    icon_path: None,
10729                    confirm: None,
10730                }]))),
10731                0,
10732                false,
10733                all_commit_ranges,
10734                cx,
10735            )
10736        });
10737
10738        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10739            transaction: apply_additional_edits
10740                .await?
10741                .as_ref()
10742                .map(language::proto::serialize_transaction),
10743        })
10744    }
10745
10746    pub fn last_formatting_failure(&self) -> Option<&str> {
10747        self.last_formatting_failure.as_deref()
10748    }
10749
10750    pub fn reset_last_formatting_failure(&mut self) {
10751        self.last_formatting_failure = None;
10752    }
10753
10754    pub fn environment_for_buffer(
10755        &self,
10756        buffer: &Entity<Buffer>,
10757        cx: &mut Context<Self>,
10758    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10759        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10760            environment.update(cx, |env, cx| {
10761                env.buffer_environment(buffer, &self.worktree_store, cx)
10762            })
10763        } else {
10764            Task::ready(None).shared()
10765        }
10766    }
10767
10768    pub fn format(
10769        &mut self,
10770        buffers: HashSet<Entity<Buffer>>,
10771        target: LspFormatTarget,
10772        push_to_history: bool,
10773        trigger: FormatTrigger,
10774        cx: &mut Context<Self>,
10775    ) -> Task<anyhow::Result<ProjectTransaction>> {
10776        let logger = zlog::scoped!("format");
10777        if self.as_local().is_some() {
10778            zlog::trace!(logger => "Formatting locally");
10779            let logger = zlog::scoped!(logger => "local");
10780            let buffers = buffers
10781                .into_iter()
10782                .map(|buffer_handle| {
10783                    let buffer = buffer_handle.read(cx);
10784                    let buffer_abs_path = File::from_dyn(buffer.file())
10785                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10786
10787                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10788                })
10789                .collect::<Vec<_>>();
10790
10791            cx.spawn(async move |lsp_store, cx| {
10792                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10793
10794                for (handle, abs_path, id) in buffers {
10795                    let env = lsp_store
10796                        .update(cx, |lsp_store, cx| {
10797                            lsp_store.environment_for_buffer(&handle, cx)
10798                        })?
10799                        .await;
10800
10801                    let ranges = match &target {
10802                        LspFormatTarget::Buffers => None,
10803                        LspFormatTarget::Ranges(ranges) => {
10804                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10805                        }
10806                    };
10807
10808                    formattable_buffers.push(FormattableBuffer {
10809                        handle,
10810                        abs_path,
10811                        env,
10812                        ranges,
10813                    });
10814                }
10815                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10816
10817                let format_timer = zlog::time!(logger => "Formatting buffers");
10818                let result = LocalLspStore::format_locally(
10819                    lsp_store.clone(),
10820                    formattable_buffers,
10821                    push_to_history,
10822                    trigger,
10823                    logger,
10824                    cx,
10825                )
10826                .await;
10827                format_timer.end();
10828
10829                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10830
10831                lsp_store.update(cx, |lsp_store, _| {
10832                    lsp_store.update_last_formatting_failure(&result);
10833                })?;
10834
10835                result
10836            })
10837        } else if let Some((client, project_id)) = self.upstream_client() {
10838            zlog::trace!(logger => "Formatting remotely");
10839            let logger = zlog::scoped!(logger => "remote");
10840
10841            let buffer_ranges = match &target {
10842                LspFormatTarget::Buffers => Vec::new(),
10843                LspFormatTarget::Ranges(ranges) => ranges
10844                    .iter()
10845                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10846                        buffer_id: buffer_id.to_proto(),
10847                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10848                    })
10849                    .collect(),
10850            };
10851
10852            let buffer_store = self.buffer_store();
10853            cx.spawn(async move |lsp_store, cx| {
10854                zlog::trace!(logger => "Sending remote format request");
10855                let request_timer = zlog::time!(logger => "remote format request");
10856                let result = client
10857                    .request(proto::FormatBuffers {
10858                        project_id,
10859                        trigger: trigger as i32,
10860                        buffer_ids: buffers
10861                            .iter()
10862                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10863                            .collect(),
10864                        buffer_ranges,
10865                    })
10866                    .await
10867                    .and_then(|result| result.transaction.context("missing transaction"));
10868                request_timer.end();
10869
10870                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10871
10872                lsp_store.update(cx, |lsp_store, _| {
10873                    lsp_store.update_last_formatting_failure(&result);
10874                })?;
10875
10876                let transaction_response = result?;
10877                let _timer = zlog::time!(logger => "deserializing project transaction");
10878                buffer_store
10879                    .update(cx, |buffer_store, cx| {
10880                        buffer_store.deserialize_project_transaction(
10881                            transaction_response,
10882                            push_to_history,
10883                            cx,
10884                        )
10885                    })
10886                    .await
10887            })
10888        } else {
10889            zlog::trace!(logger => "Not formatting");
10890            Task::ready(Ok(ProjectTransaction::default()))
10891        }
10892    }
10893
10894    async fn handle_format_buffers(
10895        this: Entity<Self>,
10896        envelope: TypedEnvelope<proto::FormatBuffers>,
10897        mut cx: AsyncApp,
10898    ) -> Result<proto::FormatBuffersResponse> {
10899        let sender_id = envelope.original_sender_id().unwrap_or_default();
10900        let format = this.update(&mut cx, |this, cx| {
10901            let mut buffers = HashSet::default();
10902            for buffer_id in &envelope.payload.buffer_ids {
10903                let buffer_id = BufferId::new(*buffer_id)?;
10904                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10905            }
10906
10907            let target = if envelope.payload.buffer_ranges.is_empty() {
10908                LspFormatTarget::Buffers
10909            } else {
10910                let mut ranges_map = BTreeMap::new();
10911                for buffer_range in &envelope.payload.buffer_ranges {
10912                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10913                    let ranges: Result<Vec<_>> = buffer_range
10914                        .ranges
10915                        .iter()
10916                        .map(|range| {
10917                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10918                        })
10919                        .collect();
10920                    ranges_map.insert(buffer_id, ranges?);
10921                }
10922                LspFormatTarget::Ranges(ranges_map)
10923            };
10924
10925            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10926            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10927        })?;
10928
10929        let project_transaction = format.await?;
10930        let project_transaction = this.update(&mut cx, |this, cx| {
10931            this.buffer_store.update(cx, |buffer_store, cx| {
10932                buffer_store.serialize_project_transaction_for_peer(
10933                    project_transaction,
10934                    sender_id,
10935                    cx,
10936                )
10937            })
10938        });
10939        Ok(proto::FormatBuffersResponse {
10940            transaction: Some(project_transaction),
10941        })
10942    }
10943
10944    async fn handle_apply_code_action_kind(
10945        this: Entity<Self>,
10946        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10947        mut cx: AsyncApp,
10948    ) -> Result<proto::ApplyCodeActionKindResponse> {
10949        let sender_id = envelope.original_sender_id().unwrap_or_default();
10950        let format = this.update(&mut cx, |this, cx| {
10951            let mut buffers = HashSet::default();
10952            for buffer_id in &envelope.payload.buffer_ids {
10953                let buffer_id = BufferId::new(*buffer_id)?;
10954                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10955            }
10956            let kind = match envelope.payload.kind.as_str() {
10957                "" => CodeActionKind::EMPTY,
10958                "quickfix" => CodeActionKind::QUICKFIX,
10959                "refactor" => CodeActionKind::REFACTOR,
10960                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10961                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10962                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10963                "source" => CodeActionKind::SOURCE,
10964                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10965                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10966                _ => anyhow::bail!(
10967                    "Invalid code action kind {}",
10968                    envelope.payload.kind.as_str()
10969                ),
10970            };
10971            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10972        })?;
10973
10974        let project_transaction = format.await?;
10975        let project_transaction = this.update(&mut cx, |this, cx| {
10976            this.buffer_store.update(cx, |buffer_store, cx| {
10977                buffer_store.serialize_project_transaction_for_peer(
10978                    project_transaction,
10979                    sender_id,
10980                    cx,
10981                )
10982            })
10983        });
10984        Ok(proto::ApplyCodeActionKindResponse {
10985            transaction: Some(project_transaction),
10986        })
10987    }
10988
10989    async fn shutdown_language_server(
10990        server_state: Option<LanguageServerState>,
10991        name: LanguageServerName,
10992        cx: &mut AsyncApp,
10993    ) {
10994        let server = match server_state {
10995            Some(LanguageServerState::Starting { startup, .. }) => {
10996                let mut timer = cx
10997                    .background_executor()
10998                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10999                    .fuse();
11000
11001                select! {
11002                    server = startup.fuse() => server,
11003                    () = timer => {
11004                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
11005                        None
11006                    },
11007                }
11008            }
11009
11010            Some(LanguageServerState::Running { server, .. }) => Some(server),
11011
11012            None => None,
11013        };
11014
11015        let Some(server) = server else { return };
11016        if let Some(shutdown) = server.shutdown() {
11017            shutdown.await;
11018        }
11019    }
11020
11021    // Returns a list of all of the worktrees which no longer have a language server and the root path
11022    // for the stopped server
11023    fn stop_local_language_server(
11024        &mut self,
11025        server_id: LanguageServerId,
11026        cx: &mut Context<Self>,
11027    ) -> Task<()> {
11028        let local = match &mut self.mode {
11029            LspStoreMode::Local(local) => local,
11030            _ => {
11031                return Task::ready(());
11032            }
11033        };
11034
11035        // Remove this server ID from all entries in the given worktree.
11036        local
11037            .language_server_ids
11038            .retain(|_, state| state.id != server_id);
11039        self.buffer_store.update(cx, |buffer_store, cx| {
11040            for buffer in buffer_store.buffers() {
11041                buffer.update(cx, |buffer, cx| {
11042                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
11043                    buffer.set_completion_triggers(server_id, Default::default(), cx);
11044                });
11045            }
11046        });
11047
11048        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
11049        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
11050            summaries.retain(|path, summaries_by_server_id| {
11051                if summaries_by_server_id.remove(&server_id).is_some() {
11052                    if let Some((client, project_id)) = self.downstream_client.clone() {
11053                        client
11054                            .send(proto::UpdateDiagnosticSummary {
11055                                project_id,
11056                                worktree_id: worktree_id.to_proto(),
11057                                summary: Some(proto::DiagnosticSummary {
11058                                    path: path.as_ref().to_proto(),
11059                                    language_server_id: server_id.0 as u64,
11060                                    error_count: 0,
11061                                    warning_count: 0,
11062                                }),
11063                                more_summaries: Vec::new(),
11064                            })
11065                            .log_err();
11066                    }
11067                    cleared_paths.push(ProjectPath {
11068                        worktree_id: *worktree_id,
11069                        path: path.clone(),
11070                    });
11071                    !summaries_by_server_id.is_empty()
11072                } else {
11073                    true
11074                }
11075            });
11076        }
11077        if !cleared_paths.is_empty() {
11078            cx.emit(LspStoreEvent::DiagnosticsUpdated {
11079                server_id,
11080                paths: cleared_paths,
11081            });
11082        }
11083
11084        let local = self.as_local_mut().unwrap();
11085        for diagnostics in local.diagnostics.values_mut() {
11086            diagnostics.retain(|_, diagnostics_by_server_id| {
11087                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
11088                    diagnostics_by_server_id.remove(ix);
11089                    !diagnostics_by_server_id.is_empty()
11090                } else {
11091                    true
11092                }
11093            });
11094        }
11095        local.language_server_watched_paths.remove(&server_id);
11096
11097        let server_state = local.language_servers.remove(&server_id);
11098        self.cleanup_lsp_data(server_id);
11099        let name = self
11100            .language_server_statuses
11101            .remove(&server_id)
11102            .map(|status| status.name)
11103            .or_else(|| {
11104                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
11105                    Some(adapter.name())
11106                } else {
11107                    None
11108                }
11109            });
11110
11111        if let Some(name) = name {
11112            log::info!("stopping language server {name}");
11113            self.languages
11114                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
11115            cx.notify();
11116
11117            return cx.spawn(async move |lsp_store, cx| {
11118                Self::shutdown_language_server(server_state, name.clone(), cx).await;
11119                lsp_store
11120                    .update(cx, |lsp_store, cx| {
11121                        lsp_store
11122                            .languages
11123                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
11124                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11125                        cx.notify();
11126                    })
11127                    .ok();
11128            });
11129        }
11130
11131        if server_state.is_some() {
11132            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11133        }
11134        Task::ready(())
11135    }
11136
11137    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
11138        self.shutdown_all_language_servers(cx).detach();
11139    }
11140
11141    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
11142        if let Some((client, project_id)) = self.upstream_client() {
11143            let request = client.request(proto::StopLanguageServers {
11144                project_id,
11145                buffer_ids: Vec::new(),
11146                also_servers: Vec::new(),
11147                all: true,
11148            });
11149            cx.background_spawn(async move {
11150                request.await.ok();
11151            })
11152        } else {
11153            let Some(local) = self.as_local_mut() else {
11154                return Task::ready(());
11155            };
11156            let language_servers_to_stop = local
11157                .language_server_ids
11158                .values()
11159                .map(|state| state.id)
11160                .collect();
11161            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11162            let tasks = language_servers_to_stop
11163                .into_iter()
11164                .map(|server| self.stop_local_language_server(server, cx))
11165                .collect::<Vec<_>>();
11166            cx.background_spawn(async move {
11167                futures::future::join_all(tasks).await;
11168            })
11169        }
11170    }
11171
11172    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
11173        let buffers = self.buffer_store.read(cx).buffers().collect();
11174        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
11175    }
11176
11177    pub fn restart_language_servers_for_buffers(
11178        &mut self,
11179        buffers: Vec<Entity<Buffer>>,
11180        only_restart_servers: HashSet<LanguageServerSelector>,
11181        cx: &mut Context<Self>,
11182    ) {
11183        if let Some((client, project_id)) = self.upstream_client() {
11184            let request = client.request(proto::RestartLanguageServers {
11185                project_id,
11186                buffer_ids: buffers
11187                    .into_iter()
11188                    .map(|b| b.read(cx).remote_id().to_proto())
11189                    .collect(),
11190                only_servers: only_restart_servers
11191                    .into_iter()
11192                    .map(|selector| {
11193                        let selector = match selector {
11194                            LanguageServerSelector::Id(language_server_id) => {
11195                                proto::language_server_selector::Selector::ServerId(
11196                                    language_server_id.to_proto(),
11197                                )
11198                            }
11199                            LanguageServerSelector::Name(language_server_name) => {
11200                                proto::language_server_selector::Selector::Name(
11201                                    language_server_name.to_string(),
11202                                )
11203                            }
11204                        };
11205                        proto::LanguageServerSelector {
11206                            selector: Some(selector),
11207                        }
11208                    })
11209                    .collect(),
11210                all: false,
11211            });
11212            cx.background_spawn(request).detach_and_log_err(cx);
11213        } else {
11214            let stop_task = if only_restart_servers.is_empty() {
11215                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11216            } else {
11217                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11218            };
11219            cx.spawn(async move |lsp_store, cx| {
11220                stop_task.await;
11221                lsp_store.update(cx, |lsp_store, cx| {
11222                    for buffer in buffers {
11223                        lsp_store.register_buffer_with_language_servers(
11224                            &buffer,
11225                            only_restart_servers.clone(),
11226                            true,
11227                            cx,
11228                        );
11229                    }
11230                })
11231            })
11232            .detach();
11233        }
11234    }
11235
11236    pub fn stop_language_servers_for_buffers(
11237        &mut self,
11238        buffers: Vec<Entity<Buffer>>,
11239        also_stop_servers: HashSet<LanguageServerSelector>,
11240        cx: &mut Context<Self>,
11241    ) -> Task<Result<()>> {
11242        if let Some((client, project_id)) = self.upstream_client() {
11243            let request = client.request(proto::StopLanguageServers {
11244                project_id,
11245                buffer_ids: buffers
11246                    .into_iter()
11247                    .map(|b| b.read(cx).remote_id().to_proto())
11248                    .collect(),
11249                also_servers: also_stop_servers
11250                    .into_iter()
11251                    .map(|selector| {
11252                        let selector = match selector {
11253                            LanguageServerSelector::Id(language_server_id) => {
11254                                proto::language_server_selector::Selector::ServerId(
11255                                    language_server_id.to_proto(),
11256                                )
11257                            }
11258                            LanguageServerSelector::Name(language_server_name) => {
11259                                proto::language_server_selector::Selector::Name(
11260                                    language_server_name.to_string(),
11261                                )
11262                            }
11263                        };
11264                        proto::LanguageServerSelector {
11265                            selector: Some(selector),
11266                        }
11267                    })
11268                    .collect(),
11269                all: false,
11270            });
11271            cx.background_spawn(async move {
11272                let _ = request.await?;
11273                Ok(())
11274            })
11275        } else {
11276            let task =
11277                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11278            cx.background_spawn(async move {
11279                task.await;
11280                Ok(())
11281            })
11282        }
11283    }
11284
11285    fn stop_local_language_servers_for_buffers(
11286        &mut self,
11287        buffers: &[Entity<Buffer>],
11288        also_stop_servers: HashSet<LanguageServerSelector>,
11289        cx: &mut Context<Self>,
11290    ) -> Task<()> {
11291        let Some(local) = self.as_local_mut() else {
11292            return Task::ready(());
11293        };
11294        let mut language_server_names_to_stop = BTreeSet::default();
11295        let mut language_servers_to_stop = also_stop_servers
11296            .into_iter()
11297            .flat_map(|selector| match selector {
11298                LanguageServerSelector::Id(id) => Some(id),
11299                LanguageServerSelector::Name(name) => {
11300                    language_server_names_to_stop.insert(name);
11301                    None
11302                }
11303            })
11304            .collect::<BTreeSet<_>>();
11305
11306        let mut covered_worktrees = HashSet::default();
11307        for buffer in buffers {
11308            buffer.update(cx, |buffer, cx| {
11309                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11310                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11311                    && covered_worktrees.insert(worktree_id)
11312                {
11313                    language_server_names_to_stop.retain(|name| {
11314                        let old_ids_count = language_servers_to_stop.len();
11315                        let all_language_servers_with_this_name = local
11316                            .language_server_ids
11317                            .iter()
11318                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11319                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11320                        old_ids_count == language_servers_to_stop.len()
11321                    });
11322                }
11323            });
11324        }
11325        for name in language_server_names_to_stop {
11326            language_servers_to_stop.extend(
11327                local
11328                    .language_server_ids
11329                    .iter()
11330                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11331            );
11332        }
11333
11334        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11335        let tasks = language_servers_to_stop
11336            .into_iter()
11337            .map(|server| self.stop_local_language_server(server, cx))
11338            .collect::<Vec<_>>();
11339
11340        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11341    }
11342
11343    #[cfg(any(test, feature = "test-support"))]
11344    pub fn update_diagnostics(
11345        &mut self,
11346        server_id: LanguageServerId,
11347        diagnostics: lsp::PublishDiagnosticsParams,
11348        result_id: Option<SharedString>,
11349        source_kind: DiagnosticSourceKind,
11350        disk_based_sources: &[String],
11351        cx: &mut Context<Self>,
11352    ) -> Result<()> {
11353        self.merge_lsp_diagnostics(
11354            source_kind,
11355            vec![DocumentDiagnosticsUpdate {
11356                diagnostics,
11357                result_id,
11358                server_id,
11359                disk_based_sources: Cow::Borrowed(disk_based_sources),
11360                registration_id: None,
11361            }],
11362            |_, _, _| false,
11363            cx,
11364        )
11365    }
11366
11367    pub fn merge_lsp_diagnostics(
11368        &mut self,
11369        source_kind: DiagnosticSourceKind,
11370        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11371        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11372        cx: &mut Context<Self>,
11373    ) -> Result<()> {
11374        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11375        let updates = lsp_diagnostics
11376            .into_iter()
11377            .filter_map(|update| {
11378                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11379                Some(DocumentDiagnosticsUpdate {
11380                    diagnostics: self.lsp_to_document_diagnostics(
11381                        abs_path,
11382                        source_kind,
11383                        update.server_id,
11384                        update.diagnostics,
11385                        &update.disk_based_sources,
11386                        update.registration_id.clone(),
11387                    ),
11388                    result_id: update.result_id,
11389                    server_id: update.server_id,
11390                    disk_based_sources: update.disk_based_sources,
11391                    registration_id: update.registration_id,
11392                })
11393            })
11394            .collect();
11395        self.merge_diagnostic_entries(updates, merge, cx)?;
11396        Ok(())
11397    }
11398
11399    fn lsp_to_document_diagnostics(
11400        &mut self,
11401        document_abs_path: PathBuf,
11402        source_kind: DiagnosticSourceKind,
11403        server_id: LanguageServerId,
11404        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11405        disk_based_sources: &[String],
11406        registration_id: Option<SharedString>,
11407    ) -> DocumentDiagnostics {
11408        let mut diagnostics = Vec::default();
11409        let mut primary_diagnostic_group_ids = HashMap::default();
11410        let mut sources_by_group_id = HashMap::default();
11411        let mut supporting_diagnostics = HashMap::default();
11412
11413        let adapter = self.language_server_adapter_for_id(server_id);
11414
11415        // Ensure that primary diagnostics are always the most severe
11416        lsp_diagnostics
11417            .diagnostics
11418            .sort_by_key(|item| item.severity);
11419
11420        for diagnostic in &lsp_diagnostics.diagnostics {
11421            let source = diagnostic.source.as_ref();
11422            let range = range_from_lsp(diagnostic.range);
11423            let is_supporting = diagnostic
11424                .related_information
11425                .as_ref()
11426                .is_some_and(|infos| {
11427                    infos.iter().any(|info| {
11428                        primary_diagnostic_group_ids.contains_key(&(
11429                            source,
11430                            diagnostic.code.clone(),
11431                            range_from_lsp(info.location.range),
11432                        ))
11433                    })
11434                });
11435
11436            let is_unnecessary = diagnostic
11437                .tags
11438                .as_ref()
11439                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11440
11441            let underline = self
11442                .language_server_adapter_for_id(server_id)
11443                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11444
11445            if is_supporting {
11446                supporting_diagnostics.insert(
11447                    (source, diagnostic.code.clone(), range),
11448                    (diagnostic.severity, is_unnecessary),
11449                );
11450            } else {
11451                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11452                let is_disk_based =
11453                    source.is_some_and(|source| disk_based_sources.contains(source));
11454
11455                sources_by_group_id.insert(group_id, source);
11456                primary_diagnostic_group_ids
11457                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11458
11459                diagnostics.push(DiagnosticEntry {
11460                    range,
11461                    diagnostic: Diagnostic {
11462                        source: diagnostic.source.clone(),
11463                        source_kind,
11464                        code: diagnostic.code.clone(),
11465                        code_description: diagnostic
11466                            .code_description
11467                            .as_ref()
11468                            .and_then(|d| d.href.clone()),
11469                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11470                        markdown: adapter.as_ref().and_then(|adapter| {
11471                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11472                        }),
11473                        message: diagnostic.message.trim().to_string(),
11474                        group_id,
11475                        is_primary: true,
11476                        is_disk_based,
11477                        is_unnecessary,
11478                        underline,
11479                        data: diagnostic.data.clone(),
11480                        registration_id: registration_id.clone(),
11481                    },
11482                });
11483                if let Some(infos) = &diagnostic.related_information {
11484                    for info in infos {
11485                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11486                            let range = range_from_lsp(info.location.range);
11487                            diagnostics.push(DiagnosticEntry {
11488                                range,
11489                                diagnostic: Diagnostic {
11490                                    source: diagnostic.source.clone(),
11491                                    source_kind,
11492                                    code: diagnostic.code.clone(),
11493                                    code_description: diagnostic
11494                                        .code_description
11495                                        .as_ref()
11496                                        .and_then(|d| d.href.clone()),
11497                                    severity: DiagnosticSeverity::INFORMATION,
11498                                    markdown: adapter.as_ref().and_then(|adapter| {
11499                                        adapter.diagnostic_message_to_markdown(&info.message)
11500                                    }),
11501                                    message: info.message.trim().to_string(),
11502                                    group_id,
11503                                    is_primary: false,
11504                                    is_disk_based,
11505                                    is_unnecessary: false,
11506                                    underline,
11507                                    data: diagnostic.data.clone(),
11508                                    registration_id: registration_id.clone(),
11509                                },
11510                            });
11511                        }
11512                    }
11513                }
11514            }
11515        }
11516
11517        for entry in &mut diagnostics {
11518            let diagnostic = &mut entry.diagnostic;
11519            if !diagnostic.is_primary {
11520                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11521                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11522                    source,
11523                    diagnostic.code.clone(),
11524                    entry.range.clone(),
11525                )) {
11526                    if let Some(severity) = severity {
11527                        diagnostic.severity = severity;
11528                    }
11529                    diagnostic.is_unnecessary = is_unnecessary;
11530                }
11531            }
11532        }
11533
11534        DocumentDiagnostics {
11535            diagnostics,
11536            document_abs_path,
11537            version: lsp_diagnostics.version,
11538        }
11539    }
11540
11541    fn insert_newly_running_language_server(
11542        &mut self,
11543        adapter: Arc<CachedLspAdapter>,
11544        language_server: Arc<LanguageServer>,
11545        server_id: LanguageServerId,
11546        key: LanguageServerSeed,
11547        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11548        cx: &mut Context<Self>,
11549    ) {
11550        let Some(local) = self.as_local_mut() else {
11551            return;
11552        };
11553        // If the language server for this key doesn't match the server id, don't store the
11554        // server. Which will cause it to be dropped, killing the process
11555        if local
11556            .language_server_ids
11557            .get(&key)
11558            .map(|state| state.id != server_id)
11559            .unwrap_or(false)
11560        {
11561            return;
11562        }
11563
11564        // Update language_servers collection with Running variant of LanguageServerState
11565        // indicating that the server is up and running and ready
11566        let workspace_folders = workspace_folders.lock().clone();
11567        language_server.set_workspace_folders(workspace_folders);
11568
11569        let workspace_diagnostics_refresh_tasks = language_server
11570            .capabilities()
11571            .diagnostic_provider
11572            .and_then(|provider| {
11573                local
11574                    .language_server_dynamic_registrations
11575                    .entry(server_id)
11576                    .or_default()
11577                    .diagnostics
11578                    .entry(None)
11579                    .or_insert(provider.clone());
11580                let workspace_refresher =
11581                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11582
11583                Some((None, workspace_refresher))
11584            })
11585            .into_iter()
11586            .collect();
11587        local.language_servers.insert(
11588            server_id,
11589            LanguageServerState::Running {
11590                workspace_diagnostics_refresh_tasks,
11591                adapter: adapter.clone(),
11592                server: language_server.clone(),
11593                simulate_disk_based_diagnostics_completion: None,
11594            },
11595        );
11596        local
11597            .languages
11598            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11599        if let Some(file_ops_caps) = language_server
11600            .capabilities()
11601            .workspace
11602            .as_ref()
11603            .and_then(|ws| ws.file_operations.as_ref())
11604        {
11605            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11606            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11607            if did_rename_caps.or(will_rename_caps).is_some() {
11608                let watcher = RenamePathsWatchedForServer::default()
11609                    .with_did_rename_patterns(did_rename_caps)
11610                    .with_will_rename_patterns(will_rename_caps);
11611                local
11612                    .language_server_paths_watched_for_rename
11613                    .insert(server_id, watcher);
11614            }
11615        }
11616
11617        self.language_server_statuses.insert(
11618            server_id,
11619            LanguageServerStatus {
11620                name: language_server.name(),
11621                server_version: language_server.version(),
11622                server_readable_version: language_server.readable_version(),
11623                pending_work: Default::default(),
11624                has_pending_diagnostic_updates: false,
11625                progress_tokens: Default::default(),
11626                worktree: Some(key.worktree_id),
11627                binary: Some(language_server.binary().clone()),
11628                configuration: Some(language_server.configuration().clone()),
11629                workspace_folders: language_server.workspace_folders(),
11630                process_id: language_server.process_id(),
11631            },
11632        );
11633
11634        cx.emit(LspStoreEvent::LanguageServerAdded(
11635            server_id,
11636            language_server.name(),
11637            Some(key.worktree_id),
11638        ));
11639
11640        let server_capabilities = language_server.capabilities();
11641        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11642            downstream_client
11643                .send(proto::StartLanguageServer {
11644                    project_id: *project_id,
11645                    server: Some(proto::LanguageServer {
11646                        id: server_id.to_proto(),
11647                        name: language_server.name().to_string(),
11648                        worktree_id: Some(key.worktree_id.to_proto()),
11649                    }),
11650                    capabilities: serde_json::to_string(&server_capabilities)
11651                        .expect("serializing server LSP capabilities"),
11652                })
11653                .log_err();
11654        }
11655        self.lsp_server_capabilities
11656            .insert(server_id, server_capabilities);
11657
11658        // Tell the language server about every open buffer in the worktree that matches the language.
11659        // Also check for buffers in worktrees that reused this server
11660        let mut worktrees_using_server = vec![key.worktree_id];
11661        if let Some(local) = self.as_local() {
11662            // Find all worktrees that have this server in their language server tree
11663            for (worktree_id, servers) in &local.lsp_tree.instances {
11664                if *worktree_id != key.worktree_id {
11665                    for server_map in servers.roots.values() {
11666                        if server_map
11667                            .values()
11668                            .any(|(node, _)| node.id() == Some(server_id))
11669                        {
11670                            worktrees_using_server.push(*worktree_id);
11671                        }
11672                    }
11673                }
11674            }
11675        }
11676
11677        let mut buffer_paths_registered = Vec::new();
11678        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11679            let mut lsp_adapters = HashMap::default();
11680            for buffer_handle in buffer_store.buffers() {
11681                let buffer = buffer_handle.read(cx);
11682                let file = match File::from_dyn(buffer.file()) {
11683                    Some(file) => file,
11684                    None => continue,
11685                };
11686                let language = match buffer.language() {
11687                    Some(language) => language,
11688                    None => continue,
11689                };
11690
11691                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11692                    || !lsp_adapters
11693                        .entry(language.name())
11694                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11695                        .iter()
11696                        .any(|a| a.name == key.name)
11697                {
11698                    continue;
11699                }
11700                // didOpen
11701                let file = match file.as_local() {
11702                    Some(file) => file,
11703                    None => continue,
11704                };
11705
11706                let local = self.as_local_mut().unwrap();
11707
11708                let buffer_id = buffer.remote_id();
11709                if local.registered_buffers.contains_key(&buffer_id) {
11710                    let abs_path = file.abs_path(cx);
11711                    let uri = match lsp::Uri::from_file_path(&abs_path) {
11712                        Ok(uri) => uri,
11713                        Err(()) => {
11714                            log::error!("failed to convert path to URI: {:?}", abs_path);
11715                            continue;
11716                        }
11717                    };
11718
11719                    let versions = local
11720                        .buffer_snapshots
11721                        .entry(buffer_id)
11722                        .or_default()
11723                        .entry(server_id)
11724                        .and_modify(|_| {
11725                            assert!(
11726                            false,
11727                            "There should not be an existing snapshot for a newly inserted buffer"
11728                        )
11729                        })
11730                        .or_insert_with(|| {
11731                            vec![LspBufferSnapshot {
11732                                version: 0,
11733                                snapshot: buffer.text_snapshot(),
11734                            }]
11735                        });
11736
11737                    let snapshot = versions.last().unwrap();
11738                    let version = snapshot.version;
11739                    let initial_snapshot = &snapshot.snapshot;
11740                    language_server.register_buffer(
11741                        uri,
11742                        adapter.language_id(&language.name()),
11743                        version,
11744                        initial_snapshot.text(),
11745                    );
11746                    buffer_paths_registered.push((buffer_id, abs_path));
11747                    local
11748                        .buffers_opened_in_servers
11749                        .entry(buffer_id)
11750                        .or_default()
11751                        .insert(server_id);
11752                }
11753                buffer_handle.update(cx, |buffer, cx| {
11754                    buffer.set_completion_triggers(
11755                        server_id,
11756                        language_server
11757                            .capabilities()
11758                            .completion_provider
11759                            .as_ref()
11760                            .and_then(|provider| {
11761                                provider
11762                                    .trigger_characters
11763                                    .as_ref()
11764                                    .map(|characters| characters.iter().cloned().collect())
11765                            })
11766                            .unwrap_or_default(),
11767                        cx,
11768                    )
11769                });
11770            }
11771        });
11772
11773        for (buffer_id, abs_path) in buffer_paths_registered {
11774            cx.emit(LspStoreEvent::LanguageServerUpdate {
11775                language_server_id: server_id,
11776                name: Some(adapter.name()),
11777                message: proto::update_language_server::Variant::RegisteredForBuffer(
11778                    proto::RegisteredForBuffer {
11779                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11780                        buffer_id: buffer_id.to_proto(),
11781                    },
11782                ),
11783            });
11784        }
11785
11786        cx.notify();
11787    }
11788
11789    pub fn language_servers_running_disk_based_diagnostics(
11790        &self,
11791    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11792        self.language_server_statuses
11793            .iter()
11794            .filter_map(|(id, status)| {
11795                if status.has_pending_diagnostic_updates {
11796                    Some(*id)
11797                } else {
11798                    None
11799                }
11800            })
11801    }
11802
11803    pub(crate) fn cancel_language_server_work_for_buffers(
11804        &mut self,
11805        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11806        cx: &mut Context<Self>,
11807    ) {
11808        if let Some((client, project_id)) = self.upstream_client() {
11809            let request = client.request(proto::CancelLanguageServerWork {
11810                project_id,
11811                work: Some(proto::cancel_language_server_work::Work::Buffers(
11812                    proto::cancel_language_server_work::Buffers {
11813                        buffer_ids: buffers
11814                            .into_iter()
11815                            .map(|b| b.read(cx).remote_id().to_proto())
11816                            .collect(),
11817                    },
11818                )),
11819            });
11820            cx.background_spawn(request).detach_and_log_err(cx);
11821        } else if let Some(local) = self.as_local() {
11822            let servers = buffers
11823                .into_iter()
11824                .flat_map(|buffer| {
11825                    buffer.update(cx, |buffer, cx| {
11826                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11827                    })
11828                })
11829                .collect::<HashSet<_>>();
11830            for server_id in servers {
11831                self.cancel_language_server_work(server_id, None, cx);
11832            }
11833        }
11834    }
11835
11836    pub(crate) fn cancel_language_server_work(
11837        &mut self,
11838        server_id: LanguageServerId,
11839        token_to_cancel: Option<ProgressToken>,
11840        cx: &mut Context<Self>,
11841    ) {
11842        if let Some(local) = self.as_local() {
11843            let status = self.language_server_statuses.get(&server_id);
11844            let server = local.language_servers.get(&server_id);
11845            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11846            {
11847                for (token, progress) in &status.pending_work {
11848                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11849                        && token != token_to_cancel
11850                    {
11851                        continue;
11852                    }
11853                    if progress.is_cancellable {
11854                        server
11855                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11856                                WorkDoneProgressCancelParams {
11857                                    token: token.to_lsp(),
11858                                },
11859                            )
11860                            .ok();
11861                    }
11862                }
11863            }
11864        } else if let Some((client, project_id)) = self.upstream_client() {
11865            let request = client.request(proto::CancelLanguageServerWork {
11866                project_id,
11867                work: Some(
11868                    proto::cancel_language_server_work::Work::LanguageServerWork(
11869                        proto::cancel_language_server_work::LanguageServerWork {
11870                            language_server_id: server_id.to_proto(),
11871                            token: token_to_cancel.map(|token| token.to_proto()),
11872                        },
11873                    ),
11874                ),
11875            });
11876            cx.background_spawn(request).detach_and_log_err(cx);
11877        }
11878    }
11879
11880    fn register_supplementary_language_server(
11881        &mut self,
11882        id: LanguageServerId,
11883        name: LanguageServerName,
11884        server: Arc<LanguageServer>,
11885        cx: &mut Context<Self>,
11886    ) {
11887        if let Some(local) = self.as_local_mut() {
11888            local
11889                .supplementary_language_servers
11890                .insert(id, (name.clone(), server));
11891            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11892        }
11893    }
11894
11895    fn unregister_supplementary_language_server(
11896        &mut self,
11897        id: LanguageServerId,
11898        cx: &mut Context<Self>,
11899    ) {
11900        if let Some(local) = self.as_local_mut() {
11901            local.supplementary_language_servers.remove(&id);
11902            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11903        }
11904    }
11905
11906    pub(crate) fn supplementary_language_servers(
11907        &self,
11908    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11909        self.as_local().into_iter().flat_map(|local| {
11910            local
11911                .supplementary_language_servers
11912                .iter()
11913                .map(|(id, (name, _))| (*id, name.clone()))
11914        })
11915    }
11916
11917    pub fn language_server_adapter_for_id(
11918        &self,
11919        id: LanguageServerId,
11920    ) -> Option<Arc<CachedLspAdapter>> {
11921        self.as_local()
11922            .and_then(|local| local.language_servers.get(&id))
11923            .and_then(|language_server_state| match language_server_state {
11924                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11925                _ => None,
11926            })
11927    }
11928
11929    pub(super) fn update_local_worktree_language_servers(
11930        &mut self,
11931        worktree_handle: &Entity<Worktree>,
11932        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11933        cx: &mut Context<Self>,
11934    ) {
11935        if changes.is_empty() {
11936            return;
11937        }
11938
11939        let Some(local) = self.as_local() else { return };
11940
11941        local.prettier_store.update(cx, |prettier_store, cx| {
11942            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11943        });
11944
11945        let worktree_id = worktree_handle.read(cx).id();
11946        let mut language_server_ids = local
11947            .language_server_ids
11948            .iter()
11949            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11950            .collect::<Vec<_>>();
11951        language_server_ids.sort();
11952        language_server_ids.dedup();
11953
11954        // let abs_path = worktree_handle.read(cx).abs_path();
11955        for server_id in &language_server_ids {
11956            if let Some(LanguageServerState::Running { server, .. }) =
11957                local.language_servers.get(server_id)
11958                && let Some(watched_paths) = local
11959                    .language_server_watched_paths
11960                    .get(server_id)
11961                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11962            {
11963                let params = lsp::DidChangeWatchedFilesParams {
11964                    changes: changes
11965                        .iter()
11966                        .filter_map(|(path, _, change)| {
11967                            if !watched_paths.is_match(path.as_std_path()) {
11968                                return None;
11969                            }
11970                            let typ = match change {
11971                                PathChange::Loaded => return None,
11972                                PathChange::Added => lsp::FileChangeType::CREATED,
11973                                PathChange::Removed => lsp::FileChangeType::DELETED,
11974                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11975                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11976                            };
11977                            let uri = lsp::Uri::from_file_path(
11978                                worktree_handle.read(cx).absolutize(&path),
11979                            )
11980                            .ok()?;
11981                            Some(lsp::FileEvent { uri, typ })
11982                        })
11983                        .collect(),
11984                };
11985                if !params.changes.is_empty() {
11986                    server
11987                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11988                        .ok();
11989                }
11990            }
11991        }
11992        for (path, _, _) in changes {
11993            if let Some(file_name) = path.file_name()
11994                && local.watched_manifest_filenames.contains(file_name)
11995            {
11996                self.request_workspace_config_refresh();
11997                break;
11998            }
11999        }
12000    }
12001
12002    pub fn wait_for_remote_buffer(
12003        &mut self,
12004        id: BufferId,
12005        cx: &mut Context<Self>,
12006    ) -> Task<Result<Entity<Buffer>>> {
12007        self.buffer_store.update(cx, |buffer_store, cx| {
12008            buffer_store.wait_for_remote_buffer(id, cx)
12009        })
12010    }
12011
12012    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
12013        let mut result = proto::Symbol {
12014            language_server_name: symbol.language_server_name.0.to_string(),
12015            source_worktree_id: symbol.source_worktree_id.to_proto(),
12016            language_server_id: symbol.source_language_server_id.to_proto(),
12017            name: symbol.name.clone(),
12018            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
12019            start: Some(proto::PointUtf16 {
12020                row: symbol.range.start.0.row,
12021                column: symbol.range.start.0.column,
12022            }),
12023            end: Some(proto::PointUtf16 {
12024                row: symbol.range.end.0.row,
12025                column: symbol.range.end.0.column,
12026            }),
12027            worktree_id: Default::default(),
12028            path: Default::default(),
12029            signature: Default::default(),
12030            container_name: symbol.container_name.clone(),
12031        };
12032        match &symbol.path {
12033            SymbolLocation::InProject(path) => {
12034                result.worktree_id = path.worktree_id.to_proto();
12035                result.path = path.path.to_proto();
12036            }
12037            SymbolLocation::OutsideProject {
12038                abs_path,
12039                signature,
12040            } => {
12041                result.path = abs_path.to_string_lossy().into_owned();
12042                result.signature = signature.to_vec();
12043            }
12044        }
12045        result
12046    }
12047
12048    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
12049        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
12050        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
12051        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
12052
12053        let path = if serialized_symbol.signature.is_empty() {
12054            SymbolLocation::InProject(ProjectPath {
12055                worktree_id,
12056                path: RelPath::from_proto(&serialized_symbol.path)
12057                    .context("invalid symbol path")?,
12058            })
12059        } else {
12060            SymbolLocation::OutsideProject {
12061                abs_path: Path::new(&serialized_symbol.path).into(),
12062                signature: serialized_symbol
12063                    .signature
12064                    .try_into()
12065                    .map_err(|_| anyhow!("invalid signature"))?,
12066            }
12067        };
12068
12069        let start = serialized_symbol.start.context("invalid start")?;
12070        let end = serialized_symbol.end.context("invalid end")?;
12071        Ok(CoreSymbol {
12072            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
12073            source_worktree_id,
12074            source_language_server_id: LanguageServerId::from_proto(
12075                serialized_symbol.language_server_id,
12076            ),
12077            path,
12078            name: serialized_symbol.name,
12079            range: Unclipped(PointUtf16::new(start.row, start.column))
12080                ..Unclipped(PointUtf16::new(end.row, end.column)),
12081            kind,
12082            container_name: serialized_symbol.container_name,
12083        })
12084    }
12085
12086    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
12087        let mut serialized_completion = proto::Completion {
12088            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
12089            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
12090            new_text: completion.new_text.clone(),
12091            ..proto::Completion::default()
12092        };
12093        match &completion.source {
12094            CompletionSource::Lsp {
12095                insert_range,
12096                server_id,
12097                lsp_completion,
12098                lsp_defaults,
12099                resolved,
12100            } => {
12101                let (old_insert_start, old_insert_end) = insert_range
12102                    .as_ref()
12103                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
12104                    .unzip();
12105
12106                serialized_completion.old_insert_start = old_insert_start;
12107                serialized_completion.old_insert_end = old_insert_end;
12108                serialized_completion.source = proto::completion::Source::Lsp as i32;
12109                serialized_completion.server_id = server_id.0 as u64;
12110                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
12111                serialized_completion.lsp_defaults = lsp_defaults
12112                    .as_deref()
12113                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
12114                serialized_completion.resolved = *resolved;
12115            }
12116            CompletionSource::BufferWord {
12117                word_range,
12118                resolved,
12119            } => {
12120                serialized_completion.source = proto::completion::Source::BufferWord as i32;
12121                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
12122                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
12123                serialized_completion.resolved = *resolved;
12124            }
12125            CompletionSource::Custom => {
12126                serialized_completion.source = proto::completion::Source::Custom as i32;
12127                serialized_completion.resolved = true;
12128            }
12129            CompletionSource::Dap { sort_text } => {
12130                serialized_completion.source = proto::completion::Source::Dap as i32;
12131                serialized_completion.sort_text = Some(sort_text.clone());
12132            }
12133        }
12134
12135        serialized_completion
12136    }
12137
12138    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
12139        let old_replace_start = completion
12140            .old_replace_start
12141            .and_then(deserialize_anchor)
12142            .context("invalid old start")?;
12143        let old_replace_end = completion
12144            .old_replace_end
12145            .and_then(deserialize_anchor)
12146            .context("invalid old end")?;
12147        let insert_range = {
12148            match completion.old_insert_start.zip(completion.old_insert_end) {
12149                Some((start, end)) => {
12150                    let start = deserialize_anchor(start).context("invalid insert old start")?;
12151                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12152                    Some(start..end)
12153                }
12154                None => None,
12155            }
12156        };
12157        Ok(CoreCompletion {
12158            replace_range: old_replace_start..old_replace_end,
12159            new_text: completion.new_text,
12160            source: match proto::completion::Source::from_i32(completion.source) {
12161                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12162                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12163                    insert_range,
12164                    server_id: LanguageServerId::from_proto(completion.server_id),
12165                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12166                    lsp_defaults: completion
12167                        .lsp_defaults
12168                        .as_deref()
12169                        .map(serde_json::from_slice)
12170                        .transpose()?,
12171                    resolved: completion.resolved,
12172                },
12173                Some(proto::completion::Source::BufferWord) => {
12174                    let word_range = completion
12175                        .buffer_word_start
12176                        .and_then(deserialize_anchor)
12177                        .context("invalid buffer word start")?
12178                        ..completion
12179                            .buffer_word_end
12180                            .and_then(deserialize_anchor)
12181                            .context("invalid buffer word end")?;
12182                    CompletionSource::BufferWord {
12183                        word_range,
12184                        resolved: completion.resolved,
12185                    }
12186                }
12187                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12188                    sort_text: completion
12189                        .sort_text
12190                        .context("expected sort text to exist")?,
12191                },
12192                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12193            },
12194        })
12195    }
12196
12197    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12198        let (kind, lsp_action) = match &action.lsp_action {
12199            LspAction::Action(code_action) => (
12200                proto::code_action::Kind::Action as i32,
12201                serde_json::to_vec(code_action).unwrap(),
12202            ),
12203            LspAction::Command(command) => (
12204                proto::code_action::Kind::Command as i32,
12205                serde_json::to_vec(command).unwrap(),
12206            ),
12207            LspAction::CodeLens(code_lens) => (
12208                proto::code_action::Kind::CodeLens as i32,
12209                serde_json::to_vec(code_lens).unwrap(),
12210            ),
12211        };
12212
12213        proto::CodeAction {
12214            server_id: action.server_id.0 as u64,
12215            start: Some(serialize_anchor(&action.range.start)),
12216            end: Some(serialize_anchor(&action.range.end)),
12217            lsp_action,
12218            kind,
12219            resolved: action.resolved,
12220        }
12221    }
12222
12223    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12224        let start = action
12225            .start
12226            .and_then(deserialize_anchor)
12227            .context("invalid start")?;
12228        let end = action
12229            .end
12230            .and_then(deserialize_anchor)
12231            .context("invalid end")?;
12232        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12233            Some(proto::code_action::Kind::Action) => {
12234                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12235            }
12236            Some(proto::code_action::Kind::Command) => {
12237                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12238            }
12239            Some(proto::code_action::Kind::CodeLens) => {
12240                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12241            }
12242            None => anyhow::bail!("Unknown action kind {}", action.kind),
12243        };
12244        Ok(CodeAction {
12245            server_id: LanguageServerId(action.server_id as usize),
12246            range: start..end,
12247            resolved: action.resolved,
12248            lsp_action,
12249        })
12250    }
12251
12252    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12253        match &formatting_result {
12254            Ok(_) => self.last_formatting_failure = None,
12255            Err(error) => {
12256                let error_string = format!("{error:#}");
12257                log::error!("Formatting failed: {error_string}");
12258                self.last_formatting_failure
12259                    .replace(error_string.lines().join(" "));
12260            }
12261        }
12262    }
12263
12264    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12265        self.lsp_server_capabilities.remove(&for_server);
12266        self.semantic_token_config.remove_server_data(for_server);
12267        for lsp_data in self.lsp_data.values_mut() {
12268            lsp_data.remove_server_data(for_server);
12269        }
12270        if let Some(local) = self.as_local_mut() {
12271            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12272            local
12273                .workspace_pull_diagnostics_result_ids
12274                .remove(&for_server);
12275            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12276                buffer_servers.remove(&for_server);
12277            }
12278        }
12279    }
12280
12281    pub fn result_id_for_buffer_pull(
12282        &self,
12283        server_id: LanguageServerId,
12284        buffer_id: BufferId,
12285        registration_id: &Option<SharedString>,
12286        cx: &App,
12287    ) -> Option<SharedString> {
12288        let abs_path = self
12289            .buffer_store
12290            .read(cx)
12291            .get(buffer_id)
12292            .and_then(|b| File::from_dyn(b.read(cx).file()))
12293            .map(|f| f.abs_path(cx))?;
12294        self.as_local()?
12295            .buffer_pull_diagnostics_result_ids
12296            .get(&server_id)?
12297            .get(registration_id)?
12298            .get(&abs_path)?
12299            .clone()
12300    }
12301
12302    /// Gets all result_ids for a workspace diagnostics pull request.
12303    /// 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.
12304    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12305    pub fn result_ids_for_workspace_refresh(
12306        &self,
12307        server_id: LanguageServerId,
12308        registration_id: &Option<SharedString>,
12309    ) -> HashMap<PathBuf, SharedString> {
12310        let Some(local) = self.as_local() else {
12311            return HashMap::default();
12312        };
12313        local
12314            .workspace_pull_diagnostics_result_ids
12315            .get(&server_id)
12316            .into_iter()
12317            .filter_map(|diagnostics| diagnostics.get(registration_id))
12318            .flatten()
12319            .filter_map(|(abs_path, result_id)| {
12320                let result_id = local
12321                    .buffer_pull_diagnostics_result_ids
12322                    .get(&server_id)
12323                    .and_then(|buffer_ids_result_ids| {
12324                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12325                    })
12326                    .cloned()
12327                    .flatten()
12328                    .or_else(|| result_id.clone())?;
12329                Some((abs_path.clone(), result_id))
12330            })
12331            .collect()
12332    }
12333
12334    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12335        if let Some(LanguageServerState::Running {
12336            workspace_diagnostics_refresh_tasks,
12337            ..
12338        }) = self
12339            .as_local_mut()
12340            .and_then(|local| local.language_servers.get_mut(&server_id))
12341        {
12342            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12343                diagnostics.refresh_tx.try_send(()).ok();
12344            }
12345        }
12346    }
12347
12348    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12349    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12350    /// which requires refreshing both workspace and document diagnostics.
12351    pub fn pull_document_diagnostics_for_server(
12352        &mut self,
12353        server_id: LanguageServerId,
12354        source_buffer_id: Option<BufferId>,
12355        cx: &mut Context<Self>,
12356    ) -> Shared<Task<()>> {
12357        let Some(local) = self.as_local_mut() else {
12358            return Task::ready(()).shared();
12359        };
12360        let mut buffers_to_refresh = HashSet::default();
12361        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12362            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12363                buffers_to_refresh.insert(*buffer_id);
12364            }
12365        }
12366
12367        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12368    }
12369
12370    pub fn pull_document_diagnostics_for_buffer_edit(
12371        &mut self,
12372        buffer_id: BufferId,
12373        cx: &mut Context<Self>,
12374    ) {
12375        let Some(local) = self.as_local_mut() else {
12376            return;
12377        };
12378        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12379        else {
12380            return;
12381        };
12382        for server_id in languages_servers {
12383            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12384        }
12385    }
12386
12387    fn apply_workspace_diagnostic_report(
12388        &mut self,
12389        server_id: LanguageServerId,
12390        report: lsp::WorkspaceDiagnosticReportResult,
12391        registration_id: Option<SharedString>,
12392        cx: &mut Context<Self>,
12393    ) {
12394        let mut workspace_diagnostics =
12395            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12396                report,
12397                server_id,
12398                registration_id,
12399            );
12400        workspace_diagnostics.retain(|d| match &d.diagnostics {
12401            LspPullDiagnostics::Response {
12402                server_id,
12403                registration_id,
12404                ..
12405            } => self.diagnostic_registration_exists(*server_id, registration_id),
12406            LspPullDiagnostics::Default => false,
12407        });
12408        let mut unchanged_buffers = HashMap::default();
12409        let workspace_diagnostics_updates = workspace_diagnostics
12410            .into_iter()
12411            .filter_map(
12412                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12413                    LspPullDiagnostics::Response {
12414                        server_id,
12415                        uri,
12416                        diagnostics,
12417                        registration_id,
12418                    } => Some((
12419                        server_id,
12420                        uri,
12421                        diagnostics,
12422                        workspace_diagnostics.version,
12423                        registration_id,
12424                    )),
12425                    LspPullDiagnostics::Default => None,
12426                },
12427            )
12428            .fold(
12429                HashMap::default(),
12430                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12431                    let (result_id, diagnostics) = match diagnostics {
12432                        PulledDiagnostics::Unchanged { result_id } => {
12433                            unchanged_buffers
12434                                .entry(new_registration_id.clone())
12435                                .or_insert_with(HashSet::default)
12436                                .insert(uri.clone());
12437                            (Some(result_id), Vec::new())
12438                        }
12439                        PulledDiagnostics::Changed {
12440                            result_id,
12441                            diagnostics,
12442                        } => (result_id, diagnostics),
12443                    };
12444                    let disk_based_sources = Cow::Owned(
12445                        self.language_server_adapter_for_id(server_id)
12446                            .as_ref()
12447                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12448                            .unwrap_or(&[])
12449                            .to_vec(),
12450                    );
12451
12452                    let Some(abs_path) = uri.to_file_path().ok() else {
12453                        return acc;
12454                    };
12455                    let Some((worktree, relative_path)) =
12456                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12457                    else {
12458                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12459                        return acc;
12460                    };
12461                    let worktree_id = worktree.read(cx).id();
12462                    let project_path = ProjectPath {
12463                        worktree_id,
12464                        path: relative_path,
12465                    };
12466                    if let Some(local_lsp_store) = self.as_local_mut() {
12467                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12468                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12469                    }
12470                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12471                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12472                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12473                        acc.entry(server_id)
12474                            .or_insert_with(HashMap::default)
12475                            .entry(new_registration_id.clone())
12476                            .or_insert_with(Vec::new)
12477                            .push(DocumentDiagnosticsUpdate {
12478                                server_id,
12479                                diagnostics: lsp::PublishDiagnosticsParams {
12480                                    uri,
12481                                    diagnostics,
12482                                    version,
12483                                },
12484                                result_id: result_id.map(SharedString::new),
12485                                disk_based_sources,
12486                                registration_id: new_registration_id,
12487                            });
12488                    }
12489                    acc
12490                },
12491            );
12492
12493        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12494            for (registration_id, diagnostic_updates) in diagnostic_updates {
12495                self.merge_lsp_diagnostics(
12496                    DiagnosticSourceKind::Pulled,
12497                    diagnostic_updates,
12498                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12499                        DiagnosticSourceKind::Pulled => {
12500                            old_diagnostic.registration_id != registration_id
12501                                || unchanged_buffers
12502                                    .get(&old_diagnostic.registration_id)
12503                                    .is_some_and(|unchanged_buffers| {
12504                                        unchanged_buffers.contains(&document_uri)
12505                                    })
12506                        }
12507                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12508                    },
12509                    cx,
12510                )
12511                .log_err();
12512            }
12513        }
12514    }
12515
12516    fn register_server_capabilities(
12517        &mut self,
12518        server_id: LanguageServerId,
12519        params: lsp::RegistrationParams,
12520        cx: &mut Context<Self>,
12521    ) -> anyhow::Result<()> {
12522        let server = self
12523            .language_server_for_id(server_id)
12524            .with_context(|| format!("no server {server_id} found"))?;
12525        for reg in params.registrations {
12526            match reg.method.as_str() {
12527                "workspace/didChangeWatchedFiles" => {
12528                    if let Some(options) = reg.register_options {
12529                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12530                            let caps = serde_json::from_value(options)?;
12531                            local_lsp_store
12532                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12533                            true
12534                        } else {
12535                            false
12536                        };
12537                        if notify {
12538                            notify_server_capabilities_updated(&server, cx);
12539                        }
12540                    }
12541                }
12542                "workspace/didChangeConfiguration" => {
12543                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12544                }
12545                "workspace/didChangeWorkspaceFolders" => {
12546                    // In this case register options is an empty object, we can ignore it
12547                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12548                        supported: Some(true),
12549                        change_notifications: Some(OneOf::Right(reg.id)),
12550                    };
12551                    server.update_capabilities(|capabilities| {
12552                        capabilities
12553                            .workspace
12554                            .get_or_insert_default()
12555                            .workspace_folders = Some(caps);
12556                    });
12557                    notify_server_capabilities_updated(&server, cx);
12558                }
12559                "workspace/symbol" => {
12560                    let options = parse_register_capabilities(reg)?;
12561                    server.update_capabilities(|capabilities| {
12562                        capabilities.workspace_symbol_provider = Some(options);
12563                    });
12564                    notify_server_capabilities_updated(&server, cx);
12565                }
12566                "workspace/fileOperations" => {
12567                    if let Some(options) = reg.register_options {
12568                        let caps = serde_json::from_value(options)?;
12569                        server.update_capabilities(|capabilities| {
12570                            capabilities
12571                                .workspace
12572                                .get_or_insert_default()
12573                                .file_operations = Some(caps);
12574                        });
12575                        notify_server_capabilities_updated(&server, cx);
12576                    }
12577                }
12578                "workspace/executeCommand" => {
12579                    if let Some(options) = reg.register_options {
12580                        let options = serde_json::from_value(options)?;
12581                        server.update_capabilities(|capabilities| {
12582                            capabilities.execute_command_provider = Some(options);
12583                        });
12584                        notify_server_capabilities_updated(&server, cx);
12585                    }
12586                }
12587                "textDocument/rangeFormatting" => {
12588                    let options = parse_register_capabilities(reg)?;
12589                    server.update_capabilities(|capabilities| {
12590                        capabilities.document_range_formatting_provider = Some(options);
12591                    });
12592                    notify_server_capabilities_updated(&server, cx);
12593                }
12594                "textDocument/onTypeFormatting" => {
12595                    if let Some(options) = reg
12596                        .register_options
12597                        .map(serde_json::from_value)
12598                        .transpose()?
12599                    {
12600                        server.update_capabilities(|capabilities| {
12601                            capabilities.document_on_type_formatting_provider = Some(options);
12602                        });
12603                        notify_server_capabilities_updated(&server, cx);
12604                    }
12605                }
12606                "textDocument/formatting" => {
12607                    let options = parse_register_capabilities(reg)?;
12608                    server.update_capabilities(|capabilities| {
12609                        capabilities.document_formatting_provider = Some(options);
12610                    });
12611                    notify_server_capabilities_updated(&server, cx);
12612                }
12613                "textDocument/rename" => {
12614                    let options = parse_register_capabilities(reg)?;
12615                    server.update_capabilities(|capabilities| {
12616                        capabilities.rename_provider = Some(options);
12617                    });
12618                    notify_server_capabilities_updated(&server, cx);
12619                }
12620                "textDocument/inlayHint" => {
12621                    let options = parse_register_capabilities(reg)?;
12622                    server.update_capabilities(|capabilities| {
12623                        capabilities.inlay_hint_provider = Some(options);
12624                    });
12625                    notify_server_capabilities_updated(&server, cx);
12626                }
12627                "textDocument/documentSymbol" => {
12628                    let options = parse_register_capabilities(reg)?;
12629                    server.update_capabilities(|capabilities| {
12630                        capabilities.document_symbol_provider = Some(options);
12631                    });
12632                    notify_server_capabilities_updated(&server, cx);
12633                }
12634                "textDocument/codeAction" => {
12635                    let options = parse_register_capabilities(reg)?;
12636                    let provider = match options {
12637                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12638                        OneOf::Right(caps) => caps,
12639                    };
12640                    server.update_capabilities(|capabilities| {
12641                        capabilities.code_action_provider = Some(provider);
12642                    });
12643                    notify_server_capabilities_updated(&server, cx);
12644                }
12645                "textDocument/definition" => {
12646                    let options = parse_register_capabilities(reg)?;
12647                    server.update_capabilities(|capabilities| {
12648                        capabilities.definition_provider = Some(options);
12649                    });
12650                    notify_server_capabilities_updated(&server, cx);
12651                }
12652                "textDocument/completion" => {
12653                    if let Some(caps) = reg
12654                        .register_options
12655                        .map(serde_json::from_value::<CompletionOptions>)
12656                        .transpose()?
12657                    {
12658                        server.update_capabilities(|capabilities| {
12659                            capabilities.completion_provider = Some(caps.clone());
12660                        });
12661
12662                        if let Some(local) = self.as_local() {
12663                            let mut buffers_with_language_server = Vec::new();
12664                            for handle in self.buffer_store.read(cx).buffers() {
12665                                let buffer_id = handle.read(cx).remote_id();
12666                                if local
12667                                    .buffers_opened_in_servers
12668                                    .get(&buffer_id)
12669                                    .filter(|s| s.contains(&server_id))
12670                                    .is_some()
12671                                {
12672                                    buffers_with_language_server.push(handle);
12673                                }
12674                            }
12675                            let triggers = caps
12676                                .trigger_characters
12677                                .unwrap_or_default()
12678                                .into_iter()
12679                                .collect::<BTreeSet<_>>();
12680                            for handle in buffers_with_language_server {
12681                                let triggers = triggers.clone();
12682                                let _ = handle.update(cx, move |buffer, cx| {
12683                                    buffer.set_completion_triggers(server_id, triggers, cx);
12684                                });
12685                            }
12686                        }
12687                        notify_server_capabilities_updated(&server, cx);
12688                    }
12689                }
12690                "textDocument/hover" => {
12691                    let options = parse_register_capabilities(reg)?;
12692                    let provider = match options {
12693                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12694                        OneOf::Right(caps) => caps,
12695                    };
12696                    server.update_capabilities(|capabilities| {
12697                        capabilities.hover_provider = Some(provider);
12698                    });
12699                    notify_server_capabilities_updated(&server, cx);
12700                }
12701                "textDocument/signatureHelp" => {
12702                    if let Some(caps) = reg
12703                        .register_options
12704                        .map(serde_json::from_value)
12705                        .transpose()?
12706                    {
12707                        server.update_capabilities(|capabilities| {
12708                            capabilities.signature_help_provider = Some(caps);
12709                        });
12710                        notify_server_capabilities_updated(&server, cx);
12711                    }
12712                }
12713                "textDocument/didChange" => {
12714                    if let Some(sync_kind) = reg
12715                        .register_options
12716                        .and_then(|opts| opts.get("syncKind").cloned())
12717                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12718                        .transpose()?
12719                    {
12720                        server.update_capabilities(|capabilities| {
12721                            let mut sync_options =
12722                                Self::take_text_document_sync_options(capabilities);
12723                            sync_options.change = Some(sync_kind);
12724                            capabilities.text_document_sync =
12725                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12726                        });
12727                        notify_server_capabilities_updated(&server, cx);
12728                    }
12729                }
12730                "textDocument/didSave" => {
12731                    if let Some(include_text) = reg
12732                        .register_options
12733                        .map(|opts| {
12734                            let transpose = opts
12735                                .get("includeText")
12736                                .cloned()
12737                                .map(serde_json::from_value::<Option<bool>>)
12738                                .transpose();
12739                            match transpose {
12740                                Ok(value) => Ok(value.flatten()),
12741                                Err(e) => Err(e),
12742                            }
12743                        })
12744                        .transpose()?
12745                    {
12746                        server.update_capabilities(|capabilities| {
12747                            let mut sync_options =
12748                                Self::take_text_document_sync_options(capabilities);
12749                            sync_options.save =
12750                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12751                                    include_text,
12752                                }));
12753                            capabilities.text_document_sync =
12754                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12755                        });
12756                        notify_server_capabilities_updated(&server, cx);
12757                    }
12758                }
12759                "textDocument/codeLens" => {
12760                    if let Some(caps) = reg
12761                        .register_options
12762                        .map(serde_json::from_value)
12763                        .transpose()?
12764                    {
12765                        server.update_capabilities(|capabilities| {
12766                            capabilities.code_lens_provider = Some(caps);
12767                        });
12768                        notify_server_capabilities_updated(&server, cx);
12769                    }
12770                }
12771                "textDocument/diagnostic" => {
12772                    if let Some(caps) = reg
12773                        .register_options
12774                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12775                        .transpose()?
12776                    {
12777                        let local = self
12778                            .as_local_mut()
12779                            .context("Expected LSP Store to be local")?;
12780                        let state = local
12781                            .language_servers
12782                            .get_mut(&server_id)
12783                            .context("Could not obtain Language Servers state")?;
12784                        local
12785                            .language_server_dynamic_registrations
12786                            .entry(server_id)
12787                            .or_default()
12788                            .diagnostics
12789                            .insert(Some(reg.id.clone()), caps.clone());
12790
12791                        let supports_workspace_diagnostics =
12792                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12793                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12794                                    diagnostic_options.workspace_diagnostics
12795                                }
12796                                DiagnosticServerCapabilities::RegistrationOptions(
12797                                    diagnostic_registration_options,
12798                                ) => {
12799                                    diagnostic_registration_options
12800                                        .diagnostic_options
12801                                        .workspace_diagnostics
12802                                }
12803                            };
12804
12805                        if supports_workspace_diagnostics(&caps) {
12806                            if let LanguageServerState::Running {
12807                                workspace_diagnostics_refresh_tasks,
12808                                ..
12809                            } = state
12810                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12811                                    Some(reg.id.clone()),
12812                                    caps.clone(),
12813                                    server.clone(),
12814                                    cx,
12815                                )
12816                            {
12817                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12818                            }
12819                        }
12820
12821                        server.update_capabilities(|capabilities| {
12822                            capabilities.diagnostic_provider = Some(caps);
12823                        });
12824
12825                        notify_server_capabilities_updated(&server, cx);
12826
12827                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12828                    }
12829                }
12830                "textDocument/documentColor" => {
12831                    let options = parse_register_capabilities(reg)?;
12832                    let provider = match options {
12833                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12834                        OneOf::Right(caps) => caps,
12835                    };
12836                    server.update_capabilities(|capabilities| {
12837                        capabilities.color_provider = Some(provider);
12838                    });
12839                    notify_server_capabilities_updated(&server, cx);
12840                }
12841                "textDocument/foldingRange" => {
12842                    let options = parse_register_capabilities(reg)?;
12843                    let provider = match options {
12844                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12845                        OneOf::Right(caps) => caps,
12846                    };
12847                    server.update_capabilities(|capabilities| {
12848                        capabilities.folding_range_provider = Some(provider);
12849                    });
12850                    notify_server_capabilities_updated(&server, cx);
12851                }
12852                _ => log::warn!("unhandled capability registration: {reg:?}"),
12853            }
12854        }
12855
12856        Ok(())
12857    }
12858
12859    fn unregister_server_capabilities(
12860        &mut self,
12861        server_id: LanguageServerId,
12862        params: lsp::UnregistrationParams,
12863        cx: &mut Context<Self>,
12864    ) -> anyhow::Result<()> {
12865        let server = self
12866            .language_server_for_id(server_id)
12867            .with_context(|| format!("no server {server_id} found"))?;
12868        for unreg in params.unregisterations.iter() {
12869            match unreg.method.as_str() {
12870                "workspace/didChangeWatchedFiles" => {
12871                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12872                        local_lsp_store
12873                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12874                        true
12875                    } else {
12876                        false
12877                    };
12878                    if notify {
12879                        notify_server_capabilities_updated(&server, cx);
12880                    }
12881                }
12882                "workspace/didChangeConfiguration" => {
12883                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12884                }
12885                "workspace/didChangeWorkspaceFolders" => {
12886                    server.update_capabilities(|capabilities| {
12887                        capabilities
12888                            .workspace
12889                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12890                                workspace_folders: None,
12891                                file_operations: None,
12892                            })
12893                            .workspace_folders = None;
12894                    });
12895                    notify_server_capabilities_updated(&server, cx);
12896                }
12897                "workspace/symbol" => {
12898                    server.update_capabilities(|capabilities| {
12899                        capabilities.workspace_symbol_provider = None
12900                    });
12901                    notify_server_capabilities_updated(&server, cx);
12902                }
12903                "workspace/fileOperations" => {
12904                    server.update_capabilities(|capabilities| {
12905                        capabilities
12906                            .workspace
12907                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12908                                workspace_folders: None,
12909                                file_operations: None,
12910                            })
12911                            .file_operations = None;
12912                    });
12913                    notify_server_capabilities_updated(&server, cx);
12914                }
12915                "workspace/executeCommand" => {
12916                    server.update_capabilities(|capabilities| {
12917                        capabilities.execute_command_provider = None;
12918                    });
12919                    notify_server_capabilities_updated(&server, cx);
12920                }
12921                "textDocument/rangeFormatting" => {
12922                    server.update_capabilities(|capabilities| {
12923                        capabilities.document_range_formatting_provider = None
12924                    });
12925                    notify_server_capabilities_updated(&server, cx);
12926                }
12927                "textDocument/onTypeFormatting" => {
12928                    server.update_capabilities(|capabilities| {
12929                        capabilities.document_on_type_formatting_provider = None;
12930                    });
12931                    notify_server_capabilities_updated(&server, cx);
12932                }
12933                "textDocument/formatting" => {
12934                    server.update_capabilities(|capabilities| {
12935                        capabilities.document_formatting_provider = None;
12936                    });
12937                    notify_server_capabilities_updated(&server, cx);
12938                }
12939                "textDocument/rename" => {
12940                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12941                    notify_server_capabilities_updated(&server, cx);
12942                }
12943                "textDocument/codeAction" => {
12944                    server.update_capabilities(|capabilities| {
12945                        capabilities.code_action_provider = None;
12946                    });
12947                    notify_server_capabilities_updated(&server, cx);
12948                }
12949                "textDocument/definition" => {
12950                    server.update_capabilities(|capabilities| {
12951                        capabilities.definition_provider = None;
12952                    });
12953                    notify_server_capabilities_updated(&server, cx);
12954                }
12955                "textDocument/completion" => {
12956                    server.update_capabilities(|capabilities| {
12957                        capabilities.completion_provider = None;
12958                    });
12959                    notify_server_capabilities_updated(&server, cx);
12960                }
12961                "textDocument/hover" => {
12962                    server.update_capabilities(|capabilities| {
12963                        capabilities.hover_provider = None;
12964                    });
12965                    notify_server_capabilities_updated(&server, cx);
12966                }
12967                "textDocument/signatureHelp" => {
12968                    server.update_capabilities(|capabilities| {
12969                        capabilities.signature_help_provider = None;
12970                    });
12971                    notify_server_capabilities_updated(&server, cx);
12972                }
12973                "textDocument/didChange" => {
12974                    server.update_capabilities(|capabilities| {
12975                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12976                        sync_options.change = None;
12977                        capabilities.text_document_sync =
12978                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12979                    });
12980                    notify_server_capabilities_updated(&server, cx);
12981                }
12982                "textDocument/didSave" => {
12983                    server.update_capabilities(|capabilities| {
12984                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12985                        sync_options.save = None;
12986                        capabilities.text_document_sync =
12987                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12988                    });
12989                    notify_server_capabilities_updated(&server, cx);
12990                }
12991                "textDocument/codeLens" => {
12992                    server.update_capabilities(|capabilities| {
12993                        capabilities.code_lens_provider = None;
12994                    });
12995                    notify_server_capabilities_updated(&server, cx);
12996                }
12997                "textDocument/diagnostic" => {
12998                    let local = self
12999                        .as_local_mut()
13000                        .context("Expected LSP Store to be local")?;
13001
13002                    let state = local
13003                        .language_servers
13004                        .get_mut(&server_id)
13005                        .context("Could not obtain Language Servers state")?;
13006                    let registrations = local
13007                        .language_server_dynamic_registrations
13008                        .get_mut(&server_id)
13009                        .with_context(|| {
13010                            format!("Expected dynamic registration to exist for server {server_id}")
13011                        })?;
13012                    registrations.diagnostics
13013                        .remove(&Some(unreg.id.clone()))
13014                        .with_context(|| format!(
13015                            "Attempted to unregister non-existent diagnostic registration with ID {}",
13016                            unreg.id)
13017                        )?;
13018                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
13019
13020                    if let LanguageServerState::Running {
13021                        workspace_diagnostics_refresh_tasks,
13022                        ..
13023                    } = state
13024                    {
13025                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
13026                    }
13027
13028                    self.clear_unregistered_diagnostics(
13029                        server_id,
13030                        SharedString::from(unreg.id.clone()),
13031                        cx,
13032                    )?;
13033
13034                    if removed_last_diagnostic_provider {
13035                        server.update_capabilities(|capabilities| {
13036                            debug_assert!(capabilities.diagnostic_provider.is_some());
13037                            capabilities.diagnostic_provider = None;
13038                        });
13039                    }
13040
13041                    notify_server_capabilities_updated(&server, cx);
13042                }
13043                "textDocument/documentColor" => {
13044                    server.update_capabilities(|capabilities| {
13045                        capabilities.color_provider = None;
13046                    });
13047                    notify_server_capabilities_updated(&server, cx);
13048                }
13049                "textDocument/foldingRange" => {
13050                    server.update_capabilities(|capabilities| {
13051                        capabilities.folding_range_provider = None;
13052                    });
13053                    notify_server_capabilities_updated(&server, cx);
13054                }
13055                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
13056            }
13057        }
13058
13059        Ok(())
13060    }
13061
13062    fn clear_unregistered_diagnostics(
13063        &mut self,
13064        server_id: LanguageServerId,
13065        cleared_registration_id: SharedString,
13066        cx: &mut Context<Self>,
13067    ) -> anyhow::Result<()> {
13068        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
13069
13070        self.buffer_store.update(cx, |buffer_store, cx| {
13071            for buffer_handle in buffer_store.buffers() {
13072                let buffer = buffer_handle.read(cx);
13073                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
13074                let Some(abs_path) = abs_path else {
13075                    continue;
13076                };
13077                affected_abs_paths.insert(abs_path);
13078            }
13079        });
13080
13081        let local = self.as_local().context("Expected LSP Store to be local")?;
13082        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
13083            let Some(worktree) = self
13084                .worktree_store
13085                .read(cx)
13086                .worktree_for_id(*worktree_id, cx)
13087            else {
13088                continue;
13089            };
13090
13091            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
13092                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
13093                    let has_matching_registration =
13094                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
13095                            entry.diagnostic.registration_id.as_ref()
13096                                == Some(&cleared_registration_id)
13097                        });
13098                    if has_matching_registration {
13099                        let abs_path = worktree.read(cx).absolutize(rel_path);
13100                        affected_abs_paths.insert(abs_path);
13101                    }
13102                }
13103            }
13104        }
13105
13106        if affected_abs_paths.is_empty() {
13107            return Ok(());
13108        }
13109
13110        // Send a fake diagnostic update which clears the state for the registration ID
13111        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
13112            affected_abs_paths
13113                .into_iter()
13114                .map(|abs_path| DocumentDiagnosticsUpdate {
13115                    diagnostics: DocumentDiagnostics {
13116                        diagnostics: Vec::new(),
13117                        document_abs_path: abs_path,
13118                        version: None,
13119                    },
13120                    result_id: None,
13121                    registration_id: Some(cleared_registration_id.clone()),
13122                    server_id,
13123                    disk_based_sources: Cow::Borrowed(&[]),
13124                })
13125                .collect();
13126
13127        let merge_registration_id = cleared_registration_id.clone();
13128        self.merge_diagnostic_entries(
13129            clears,
13130            move |_, diagnostic, _| {
13131                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
13132                    diagnostic.registration_id != Some(merge_registration_id.clone())
13133                } else {
13134                    true
13135                }
13136            },
13137            cx,
13138        )?;
13139
13140        Ok(())
13141    }
13142
13143    async fn deduplicate_range_based_lsp_requests<T>(
13144        lsp_store: &Entity<Self>,
13145        server_id: Option<LanguageServerId>,
13146        lsp_request_id: LspRequestId,
13147        proto_request: &T::ProtoRequest,
13148        range: Range<Anchor>,
13149        cx: &mut AsyncApp,
13150    ) -> Result<()>
13151    where
13152        T: LspCommand,
13153        T::ProtoRequest: proto::LspRequestMessage,
13154    {
13155        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13156        let version = deserialize_version(proto_request.buffer_version());
13157        let buffer = lsp_store.update(cx, |this, cx| {
13158            this.buffer_store.read(cx).get_existing(buffer_id)
13159        })?;
13160        buffer
13161            .update(cx, |buffer, _| buffer.wait_for_version(version))
13162            .await?;
13163        lsp_store.update(cx, |lsp_store, cx| {
13164            let buffer_snapshot = buffer.read(cx).snapshot();
13165            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13166            let chunks_queried_for = lsp_data
13167                .inlay_hints
13168                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
13169                .collect::<Vec<_>>();
13170            match chunks_queried_for.as_slice() {
13171                &[chunk] => {
13172                    let key = LspKey {
13173                        request_type: TypeId::of::<T>(),
13174                        server_queried: server_id,
13175                    };
13176                    let previous_request = lsp_data
13177                        .chunk_lsp_requests
13178                        .entry(key)
13179                        .or_default()
13180                        .insert(chunk, lsp_request_id);
13181                    if let Some((previous_request, running_requests)) =
13182                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13183                    {
13184                        running_requests.remove(&previous_request);
13185                    }
13186                }
13187                _ambiguous_chunks => {
13188                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13189                    // there, a buffer version-based check will be performed and outdated requests discarded.
13190                }
13191            }
13192            anyhow::Ok(())
13193        })?;
13194
13195        Ok(())
13196    }
13197
13198    async fn query_lsp_locally<T>(
13199        lsp_store: Entity<Self>,
13200        for_server_id: Option<LanguageServerId>,
13201        sender_id: proto::PeerId,
13202        lsp_request_id: LspRequestId,
13203        proto_request: T::ProtoRequest,
13204        position: Option<Anchor>,
13205        cx: &mut AsyncApp,
13206    ) -> Result<()>
13207    where
13208        T: LspCommand + Clone,
13209        T::ProtoRequest: proto::LspRequestMessage,
13210        <T::ProtoRequest as proto::RequestMessage>::Response:
13211            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13212    {
13213        let (buffer_version, buffer) =
13214            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
13215        let request =
13216            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13217        let key = LspKey {
13218            request_type: TypeId::of::<T>(),
13219            server_queried: for_server_id,
13220        };
13221        lsp_store.update(cx, |lsp_store, cx| {
13222            let request_task = match for_server_id {
13223                Some(server_id) => {
13224                    let server_task = lsp_store.request_lsp(
13225                        buffer.clone(),
13226                        LanguageServerToQuery::Other(server_id),
13227                        request.clone(),
13228                        cx,
13229                    );
13230                    cx.background_spawn(async move {
13231                        let mut responses = Vec::new();
13232                        match server_task.await {
13233                            Ok(response) => responses.push((server_id, response)),
13234                            // rust-analyzer likes to error with this when its still loading up
13235                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13236                            Err(e) => log::error!(
13237                                "Error handling response for request {request:?}: {e:#}"
13238                            ),
13239                        }
13240                        responses
13241                    })
13242                }
13243                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13244            };
13245            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13246            if T::ProtoRequest::stop_previous_requests() {
13247                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13248                    lsp_requests.clear();
13249                }
13250            }
13251            lsp_data.lsp_requests.entry(key).or_default().insert(
13252                lsp_request_id,
13253                cx.spawn(async move |lsp_store, cx| {
13254                    let response = request_task.await;
13255                    lsp_store
13256                        .update(cx, |lsp_store, cx| {
13257                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13258                            {
13259                                let response = response
13260                                    .into_iter()
13261                                    .map(|(server_id, response)| {
13262                                        (
13263                                            server_id.to_proto(),
13264                                            T::response_to_proto(
13265                                                response,
13266                                                lsp_store,
13267                                                sender_id,
13268                                                &buffer_version,
13269                                                cx,
13270                                            )
13271                                            .into(),
13272                                        )
13273                                    })
13274                                    .collect::<HashMap<_, _>>();
13275                                match client.send_lsp_response::<T::ProtoRequest>(
13276                                    project_id,
13277                                    lsp_request_id,
13278                                    response,
13279                                ) {
13280                                    Ok(()) => {}
13281                                    Err(e) => {
13282                                        log::error!("Failed to send LSP response: {e:#}",)
13283                                    }
13284                                }
13285                            }
13286                        })
13287                        .ok();
13288                }),
13289            );
13290        });
13291        Ok(())
13292    }
13293
13294    async fn wait_for_buffer_version<T>(
13295        lsp_store: &Entity<Self>,
13296        proto_request: &T::ProtoRequest,
13297        cx: &mut AsyncApp,
13298    ) -> Result<(Global, Entity<Buffer>)>
13299    where
13300        T: LspCommand,
13301        T::ProtoRequest: proto::LspRequestMessage,
13302    {
13303        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13304        let version = deserialize_version(proto_request.buffer_version());
13305        let buffer = lsp_store.update(cx, |this, cx| {
13306            this.buffer_store.read(cx).get_existing(buffer_id)
13307        })?;
13308        buffer
13309            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13310            .await?;
13311        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13312        Ok((buffer_version, buffer))
13313    }
13314
13315    fn take_text_document_sync_options(
13316        capabilities: &mut lsp::ServerCapabilities,
13317    ) -> lsp::TextDocumentSyncOptions {
13318        match capabilities.text_document_sync.take() {
13319            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13320            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13321                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13322                sync_options.change = Some(sync_kind);
13323                sync_options
13324            }
13325            None => lsp::TextDocumentSyncOptions::default(),
13326        }
13327    }
13328
13329    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13330        self.downstream_client.clone()
13331    }
13332
13333    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13334        self.worktree_store.clone()
13335    }
13336
13337    /// Gets what's stored in the LSP data for the given buffer.
13338    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13339        self.lsp_data.get_mut(&buffer_id)
13340    }
13341
13342    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13343    /// new [`BufferLspData`] will be created to replace the previous state.
13344    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13345        let (buffer_id, buffer_version) =
13346            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13347        let lsp_data = self
13348            .lsp_data
13349            .entry(buffer_id)
13350            .or_insert_with(|| BufferLspData::new(buffer, cx));
13351        if buffer_version.changed_since(&lsp_data.buffer_version) {
13352            // To send delta requests for semantic tokens, the previous tokens
13353            // need to be kept between buffer changes.
13354            let semantic_tokens = lsp_data.semantic_tokens.take();
13355            *lsp_data = BufferLspData::new(buffer, cx);
13356            lsp_data.semantic_tokens = semantic_tokens;
13357        }
13358        lsp_data
13359    }
13360}
13361
13362// Registration with registerOptions as null, should fallback to true.
13363// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13364fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13365    reg: lsp::Registration,
13366) -> Result<OneOf<bool, T>> {
13367    Ok(match reg.register_options {
13368        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13369        None => OneOf::Left(true),
13370    })
13371}
13372
13373fn server_capabilities_support_range_formatting(capabilities: &lsp::ServerCapabilities) -> bool {
13374    matches!(
13375        capabilities.document_range_formatting_provider.as_ref(),
13376        Some(provider) if *provider != OneOf::Left(false)
13377    )
13378}
13379
13380fn subscribe_to_binary_statuses(
13381    languages: &Arc<LanguageRegistry>,
13382    cx: &mut Context<'_, LspStore>,
13383) -> Task<()> {
13384    let mut server_statuses = languages.language_server_binary_statuses();
13385    cx.spawn(async move |lsp_store, cx| {
13386        while let Some((server_name, binary_status)) = server_statuses.next().await {
13387            if lsp_store
13388                .update(cx, |_, cx| {
13389                    let mut message = None;
13390                    let binary_status = match binary_status {
13391                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13392                        BinaryStatus::CheckingForUpdate => {
13393                            proto::ServerBinaryStatus::CheckingForUpdate
13394                        }
13395                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13396                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13397                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13398                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13399                        BinaryStatus::Failed { error } => {
13400                            message = Some(error);
13401                            proto::ServerBinaryStatus::Failed
13402                        }
13403                    };
13404                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13405                        // Binary updates are about the binary that might not have any language server id at that point.
13406                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13407                        language_server_id: LanguageServerId(0),
13408                        name: Some(server_name),
13409                        message: proto::update_language_server::Variant::StatusUpdate(
13410                            proto::StatusUpdate {
13411                                message,
13412                                status: Some(proto::status_update::Status::Binary(
13413                                    binary_status as i32,
13414                                )),
13415                            },
13416                        ),
13417                    });
13418                })
13419                .is_err()
13420            {
13421                break;
13422            }
13423        }
13424    })
13425}
13426
13427fn lsp_workspace_diagnostics_refresh(
13428    registration_id: Option<String>,
13429    options: DiagnosticServerCapabilities,
13430    server: Arc<LanguageServer>,
13431    cx: &mut Context<'_, LspStore>,
13432) -> Option<WorkspaceRefreshTask> {
13433    let identifier = workspace_diagnostic_identifier(&options)?;
13434    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13435
13436    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13437    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13438    refresh_tx.try_send(()).ok();
13439
13440    let request_timeout = ProjectSettings::get_global(cx)
13441        .global_lsp_settings
13442        .get_request_timeout();
13443
13444    // Clamp timeout duration at a minimum of [`DEFAULT_LSP_REQUEST_TIMEOUT`] to mitigate useless loops from re-trying connections with smaller timeouts from project settings.
13445    // This allows users to increase the duration if need be
13446    let timeout = if request_timeout != Duration::ZERO {
13447        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13448    } else {
13449        request_timeout
13450    };
13451
13452    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13453        let mut attempts = 0;
13454        let max_attempts = 50;
13455        let mut requests = 0;
13456
13457        loop {
13458            let Some(()) = refresh_rx.recv().await else {
13459                return;
13460            };
13461
13462            'request: loop {
13463                requests += 1;
13464                if attempts > max_attempts {
13465                    log::error!(
13466                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13467                    );
13468                    return;
13469                }
13470                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13471                cx.background_executor()
13472                    .timer(Duration::from_millis(backoff_millis))
13473                    .await;
13474                attempts += 1;
13475
13476                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13477                    lsp_store
13478                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13479                        .into_iter()
13480                        .filter_map(|(abs_path, result_id)| {
13481                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13482                            Some(lsp::PreviousResultId {
13483                                uri,
13484                                value: result_id.to_string(),
13485                            })
13486                        })
13487                        .collect()
13488                }) else {
13489                    return;
13490                };
13491
13492                let token = if let Some(registration_id) = &registration_id {
13493                    format!(
13494                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13495                        server.server_id(),
13496                    )
13497                } else {
13498                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13499                };
13500
13501                progress_rx.try_recv().ok();
13502                let timer = server.request_timer(timeout).fuse();
13503                let progress = pin!(progress_rx.recv().fuse());
13504                let response_result = server
13505                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13506                        lsp::WorkspaceDiagnosticParams {
13507                            previous_result_ids,
13508                            identifier: identifier.clone(),
13509                            work_done_progress_params: Default::default(),
13510                            partial_result_params: lsp::PartialResultParams {
13511                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13512                            },
13513                        },
13514                        select(timer, progress).then(|either| match either {
13515                            Either::Left((message, ..)) => ready(message).left_future(),
13516                            Either::Right(..) => pending::<String>().right_future(),
13517                        }),
13518                    )
13519                    .await;
13520
13521                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13522                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13523                match response_result {
13524                    ConnectionResult::Timeout => {
13525                        log::error!("Timeout during workspace diagnostics pull");
13526                        continue 'request;
13527                    }
13528                    ConnectionResult::ConnectionReset => {
13529                        log::error!("Server closed a workspace diagnostics pull request");
13530                        continue 'request;
13531                    }
13532                    ConnectionResult::Result(Err(e)) => {
13533                        log::error!("Error during workspace diagnostics pull: {e:#}");
13534                        break 'request;
13535                    }
13536                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13537                        attempts = 0;
13538                        if lsp_store
13539                            .update(cx, |lsp_store, cx| {
13540                                lsp_store.apply_workspace_diagnostic_report(
13541                                    server.server_id(),
13542                                    pulled_diagnostics,
13543                                    registration_id_shared.clone(),
13544                                    cx,
13545                                )
13546                            })
13547                            .is_err()
13548                        {
13549                            return;
13550                        }
13551                        break 'request;
13552                    }
13553                }
13554            }
13555        }
13556    });
13557
13558    Some(WorkspaceRefreshTask {
13559        refresh_tx,
13560        progress_tx,
13561        task: workspace_query_language_server,
13562    })
13563}
13564
13565fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13566    match &options {
13567        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13568            .identifier
13569            .as_deref()
13570            .map(SharedString::new),
13571        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13572            let diagnostic_options = &registration_options.diagnostic_options;
13573            diagnostic_options
13574                .identifier
13575                .as_deref()
13576                .map(SharedString::new)
13577        }
13578    }
13579}
13580
13581fn workspace_diagnostic_identifier(
13582    options: &DiagnosticServerCapabilities,
13583) -> Option<Option<String>> {
13584    match &options {
13585        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13586            if !diagnostic_options.workspace_diagnostics {
13587                return None;
13588            }
13589            Some(diagnostic_options.identifier.clone())
13590        }
13591        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13592            let diagnostic_options = &registration_options.diagnostic_options;
13593            if !diagnostic_options.workspace_diagnostics {
13594                return None;
13595            }
13596            Some(diagnostic_options.identifier.clone())
13597        }
13598    }
13599}
13600
13601fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13602    let CompletionSource::BufferWord {
13603        word_range,
13604        resolved,
13605    } = &mut completion.source
13606    else {
13607        return;
13608    };
13609    if *resolved {
13610        return;
13611    }
13612
13613    if completion.new_text
13614        != snapshot
13615            .text_for_range(word_range.clone())
13616            .collect::<String>()
13617    {
13618        return;
13619    }
13620
13621    let mut offset = 0;
13622    for chunk in snapshot.chunks(
13623        word_range.clone(),
13624        LanguageAwareStyling {
13625            tree_sitter: true,
13626            diagnostics: true,
13627        },
13628    ) {
13629        let end_offset = offset + chunk.text.len();
13630        if let Some(highlight_id) = chunk.syntax_highlight_id {
13631            completion
13632                .label
13633                .runs
13634                .push((offset..end_offset, highlight_id));
13635        }
13636        offset = end_offset;
13637    }
13638    *resolved = true;
13639}
13640
13641impl EventEmitter<LspStoreEvent> for LspStore {}
13642
13643fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13644    hover
13645        .contents
13646        .retain(|hover_block| !hover_block.text.trim().is_empty());
13647    if hover.contents.is_empty() {
13648        None
13649    } else {
13650        Some(hover)
13651    }
13652}
13653
13654async fn populate_labels_for_completions(
13655    new_completions: Vec<CoreCompletion>,
13656    language: Option<Arc<Language>>,
13657    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13658) -> Vec<Completion> {
13659    let lsp_completions = new_completions
13660        .iter()
13661        .filter_map(|new_completion| {
13662            new_completion
13663                .source
13664                .lsp_completion(true)
13665                .map(|lsp_completion| lsp_completion.into_owned())
13666        })
13667        .collect::<Vec<_>>();
13668
13669    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13670        lsp_adapter
13671            .labels_for_completions(&lsp_completions, language)
13672            .await
13673            .log_err()
13674            .unwrap_or_default()
13675    } else {
13676        Vec::new()
13677    }
13678    .into_iter()
13679    .fuse();
13680
13681    let mut completions = Vec::new();
13682    for completion in new_completions {
13683        match completion.source.lsp_completion(true) {
13684            Some(lsp_completion) => {
13685                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13686
13687                let mut label = labels.next().flatten().unwrap_or_else(|| {
13688                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13689                });
13690                ensure_uniform_list_compatible_label(&mut label);
13691                completions.push(Completion {
13692                    label,
13693                    documentation,
13694                    replace_range: completion.replace_range,
13695                    new_text: completion.new_text,
13696                    insert_text_mode: lsp_completion.insert_text_mode,
13697                    source: completion.source,
13698                    icon_path: None,
13699                    confirm: None,
13700                    match_start: None,
13701                    snippet_deduplication_key: None,
13702                });
13703            }
13704            None => {
13705                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13706                ensure_uniform_list_compatible_label(&mut label);
13707                completions.push(Completion {
13708                    label,
13709                    documentation: None,
13710                    replace_range: completion.replace_range,
13711                    new_text: completion.new_text,
13712                    source: completion.source,
13713                    insert_text_mode: None,
13714                    icon_path: None,
13715                    confirm: None,
13716                    match_start: None,
13717                    snippet_deduplication_key: None,
13718                });
13719            }
13720        }
13721    }
13722    completions
13723}
13724
13725#[derive(Debug)]
13726pub enum LanguageServerToQuery {
13727    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13728    FirstCapable,
13729    /// Query a specific language server.
13730    Other(LanguageServerId),
13731}
13732
13733#[derive(Default)]
13734struct RenamePathsWatchedForServer {
13735    did_rename: Vec<RenameActionPredicate>,
13736    will_rename: Vec<RenameActionPredicate>,
13737}
13738
13739impl RenamePathsWatchedForServer {
13740    fn with_did_rename_patterns(
13741        mut self,
13742        did_rename: Option<&FileOperationRegistrationOptions>,
13743    ) -> Self {
13744        if let Some(did_rename) = did_rename {
13745            self.did_rename = did_rename
13746                .filters
13747                .iter()
13748                .filter_map(|filter| filter.try_into().log_err())
13749                .collect();
13750        }
13751        self
13752    }
13753    fn with_will_rename_patterns(
13754        mut self,
13755        will_rename: Option<&FileOperationRegistrationOptions>,
13756    ) -> Self {
13757        if let Some(will_rename) = will_rename {
13758            self.will_rename = will_rename
13759                .filters
13760                .iter()
13761                .filter_map(|filter| filter.try_into().log_err())
13762                .collect();
13763        }
13764        self
13765    }
13766
13767    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13768        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13769    }
13770    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13771        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13772    }
13773}
13774
13775impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13776    type Error = globset::Error;
13777    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13778        Ok(Self {
13779            kind: ops.pattern.matches.clone(),
13780            glob: GlobBuilder::new(&ops.pattern.glob)
13781                .case_insensitive(
13782                    ops.pattern
13783                        .options
13784                        .as_ref()
13785                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13786                )
13787                .build()?
13788                .compile_matcher(),
13789        })
13790    }
13791}
13792struct RenameActionPredicate {
13793    glob: GlobMatcher,
13794    kind: Option<FileOperationPatternKind>,
13795}
13796
13797impl RenameActionPredicate {
13798    // Returns true if language server should be notified
13799    fn eval(&self, path: &str, is_dir: bool) -> bool {
13800        self.kind.as_ref().is_none_or(|kind| {
13801            let expected_kind = if is_dir {
13802                FileOperationPatternKind::Folder
13803            } else {
13804                FileOperationPatternKind::File
13805            };
13806            kind == &expected_kind
13807        }) && self.glob.is_match(path)
13808    }
13809}
13810
13811#[derive(Default)]
13812struct LanguageServerWatchedPaths {
13813    worktree_paths: HashMap<WorktreeId, GlobSet>,
13814    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13815}
13816
13817#[derive(Default)]
13818struct LanguageServerWatchedPathsBuilder {
13819    worktree_paths: HashMap<WorktreeId, GlobSet>,
13820    abs_paths: HashMap<Arc<Path>, GlobSet>,
13821}
13822
13823impl LanguageServerWatchedPathsBuilder {
13824    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13825        self.worktree_paths.insert(worktree_id, glob_set);
13826    }
13827    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13828        self.abs_paths.insert(path, glob_set);
13829    }
13830    fn build(
13831        self,
13832        fs: Arc<dyn Fs>,
13833        language_server_id: LanguageServerId,
13834        cx: &mut Context<LspStore>,
13835    ) -> LanguageServerWatchedPaths {
13836        let lsp_store = cx.weak_entity();
13837
13838        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13839        let abs_paths = self
13840            .abs_paths
13841            .into_iter()
13842            .map(|(abs_path, globset)| {
13843                let task = cx.spawn({
13844                    let abs_path = abs_path.clone();
13845                    let fs = fs.clone();
13846
13847                    let lsp_store = lsp_store.clone();
13848                    async move |_, cx| {
13849                        maybe!(async move {
13850                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13851                            while let Some(update) = push_updates.0.next().await {
13852                                let action = lsp_store
13853                                    .update(cx, |this, _| {
13854                                        let Some(local) = this.as_local() else {
13855                                            return ControlFlow::Break(());
13856                                        };
13857                                        let Some(watcher) = local
13858                                            .language_server_watched_paths
13859                                            .get(&language_server_id)
13860                                        else {
13861                                            return ControlFlow::Break(());
13862                                        };
13863                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13864                                            "Watched abs path is not registered with a watcher",
13865                                        );
13866                                        let matching_entries = update
13867                                            .into_iter()
13868                                            .filter(|event| globs.is_match(&event.path))
13869                                            .collect::<Vec<_>>();
13870                                        this.lsp_notify_abs_paths_changed(
13871                                            language_server_id,
13872                                            matching_entries,
13873                                        );
13874                                        ControlFlow::Continue(())
13875                                    })
13876                                    .ok()?;
13877
13878                                if action.is_break() {
13879                                    break;
13880                                }
13881                            }
13882                            Some(())
13883                        })
13884                        .await;
13885                    }
13886                });
13887                (abs_path, (globset, task))
13888            })
13889            .collect();
13890        LanguageServerWatchedPaths {
13891            worktree_paths: self.worktree_paths,
13892            abs_paths,
13893        }
13894    }
13895}
13896
13897struct LspBufferSnapshot {
13898    version: i32,
13899    snapshot: TextBufferSnapshot,
13900}
13901
13902/// A prompt requested by LSP server.
13903#[derive(Clone, Debug)]
13904pub struct LanguageServerPromptRequest {
13905    pub id: usize,
13906    pub level: PromptLevel,
13907    pub message: String,
13908    pub actions: Vec<MessageActionItem>,
13909    pub lsp_name: String,
13910    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13911}
13912
13913impl LanguageServerPromptRequest {
13914    pub fn new(
13915        level: PromptLevel,
13916        message: String,
13917        actions: Vec<MessageActionItem>,
13918        lsp_name: String,
13919        response_channel: smol::channel::Sender<MessageActionItem>,
13920    ) -> Self {
13921        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13922        LanguageServerPromptRequest {
13923            id,
13924            level,
13925            message,
13926            actions,
13927            lsp_name,
13928            response_channel,
13929        }
13930    }
13931    pub async fn respond(self, index: usize) -> Option<()> {
13932        if let Some(response) = self.actions.into_iter().nth(index) {
13933            self.response_channel.send(response).await.ok()
13934        } else {
13935            None
13936        }
13937    }
13938
13939    #[cfg(any(test, feature = "test-support"))]
13940    pub fn test(
13941        level: PromptLevel,
13942        message: String,
13943        actions: Vec<MessageActionItem>,
13944        lsp_name: String,
13945    ) -> Self {
13946        let (tx, _rx) = smol::channel::unbounded();
13947        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13948    }
13949}
13950impl PartialEq for LanguageServerPromptRequest {
13951    fn eq(&self, other: &Self) -> bool {
13952        self.message == other.message && self.actions == other.actions
13953    }
13954}
13955
13956#[derive(Clone, Debug, PartialEq)]
13957pub enum LanguageServerLogType {
13958    Log(MessageType),
13959    Trace { verbose_info: Option<String> },
13960    Rpc { received: bool },
13961}
13962
13963impl LanguageServerLogType {
13964    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13965        match self {
13966            Self::Log(log_type) => {
13967                use proto::log_message::LogLevel;
13968                let level = match *log_type {
13969                    MessageType::ERROR => LogLevel::Error,
13970                    MessageType::WARNING => LogLevel::Warning,
13971                    MessageType::INFO => LogLevel::Info,
13972                    MessageType::LOG => LogLevel::Log,
13973                    other => {
13974                        log::warn!("Unknown lsp log message type: {other:?}");
13975                        LogLevel::Log
13976                    }
13977                };
13978                proto::language_server_log::LogType::Log(proto::LogMessage {
13979                    level: level as i32,
13980                })
13981            }
13982            Self::Trace { verbose_info } => {
13983                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13984                    verbose_info: verbose_info.to_owned(),
13985                })
13986            }
13987            Self::Rpc { received } => {
13988                let kind = if *received {
13989                    proto::rpc_message::Kind::Received
13990                } else {
13991                    proto::rpc_message::Kind::Sent
13992                };
13993                let kind = kind as i32;
13994                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13995            }
13996        }
13997    }
13998
13999    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
14000        use proto::log_message::LogLevel;
14001        use proto::rpc_message;
14002        match log_type {
14003            proto::language_server_log::LogType::Log(message_type) => Self::Log(
14004                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
14005                    LogLevel::Error => MessageType::ERROR,
14006                    LogLevel::Warning => MessageType::WARNING,
14007                    LogLevel::Info => MessageType::INFO,
14008                    LogLevel::Log => MessageType::LOG,
14009                },
14010            ),
14011            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
14012                verbose_info: trace_message.verbose_info,
14013            },
14014            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
14015                received: match rpc_message::Kind::from_i32(message.kind)
14016                    .unwrap_or(rpc_message::Kind::Received)
14017                {
14018                    rpc_message::Kind::Received => true,
14019                    rpc_message::Kind::Sent => false,
14020                },
14021            },
14022        }
14023    }
14024}
14025
14026pub struct WorkspaceRefreshTask {
14027    refresh_tx: mpsc::Sender<()>,
14028    progress_tx: mpsc::Sender<()>,
14029    #[allow(dead_code)]
14030    task: Task<()>,
14031}
14032
14033pub enum LanguageServerState {
14034    Starting {
14035        startup: Task<Option<Arc<LanguageServer>>>,
14036        /// List of language servers that will be added to the workspace once it's initialization completes.
14037        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
14038    },
14039
14040    Running {
14041        adapter: Arc<CachedLspAdapter>,
14042        server: Arc<LanguageServer>,
14043        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
14044        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
14045    },
14046}
14047
14048impl LanguageServerState {
14049    fn add_workspace_folder(&self, uri: Uri) {
14050        match self {
14051            LanguageServerState::Starting {
14052                pending_workspace_folders,
14053                ..
14054            } => {
14055                pending_workspace_folders.lock().insert(uri);
14056            }
14057            LanguageServerState::Running { server, .. } => {
14058                server.add_workspace_folder(uri);
14059            }
14060        }
14061    }
14062    fn _remove_workspace_folder(&self, uri: Uri) {
14063        match self {
14064            LanguageServerState::Starting {
14065                pending_workspace_folders,
14066                ..
14067            } => {
14068                pending_workspace_folders.lock().remove(&uri);
14069            }
14070            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
14071        }
14072    }
14073}
14074
14075impl std::fmt::Debug for LanguageServerState {
14076    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14077        match self {
14078            LanguageServerState::Starting { .. } => {
14079                f.debug_struct("LanguageServerState::Starting").finish()
14080            }
14081            LanguageServerState::Running { .. } => {
14082                f.debug_struct("LanguageServerState::Running").finish()
14083            }
14084        }
14085    }
14086}
14087
14088#[derive(Clone, Debug, Serialize)]
14089pub struct LanguageServerProgress {
14090    pub is_disk_based_diagnostics_progress: bool,
14091    pub is_cancellable: bool,
14092    pub title: Option<String>,
14093    pub message: Option<String>,
14094    pub percentage: Option<usize>,
14095    #[serde(skip_serializing)]
14096    pub last_update_at: Instant,
14097}
14098
14099#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
14100pub struct DiagnosticSummary {
14101    pub error_count: usize,
14102    pub warning_count: usize,
14103}
14104
14105impl DiagnosticSummary {
14106    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
14107        let mut this = Self {
14108            error_count: 0,
14109            warning_count: 0,
14110        };
14111
14112        for entry in diagnostics {
14113            if entry.diagnostic.is_primary {
14114                match entry.diagnostic.severity {
14115                    DiagnosticSeverity::ERROR => this.error_count += 1,
14116                    DiagnosticSeverity::WARNING => this.warning_count += 1,
14117                    _ => {}
14118                }
14119            }
14120        }
14121
14122        this
14123    }
14124
14125    pub fn is_empty(&self) -> bool {
14126        self.error_count == 0 && self.warning_count == 0
14127    }
14128
14129    pub fn to_proto(
14130        self,
14131        language_server_id: LanguageServerId,
14132        path: &RelPath,
14133    ) -> proto::DiagnosticSummary {
14134        proto::DiagnosticSummary {
14135            path: path.to_proto(),
14136            language_server_id: language_server_id.0 as u64,
14137            error_count: self.error_count as u32,
14138            warning_count: self.warning_count as u32,
14139        }
14140    }
14141}
14142
14143#[derive(Clone, Debug)]
14144pub enum CompletionDocumentation {
14145    /// There is no documentation for this completion.
14146    Undocumented,
14147    /// A single line of documentation.
14148    SingleLine(SharedString),
14149    /// Multiple lines of plain text documentation.
14150    MultiLinePlainText(SharedString),
14151    /// Markdown documentation.
14152    MultiLineMarkdown(SharedString),
14153    /// Both single line and multiple lines of plain text documentation.
14154    SingleLineAndMultiLinePlainText {
14155        single_line: SharedString,
14156        plain_text: Option<SharedString>,
14157    },
14158}
14159
14160impl CompletionDocumentation {
14161    #[cfg(any(test, feature = "test-support"))]
14162    pub fn text(&self) -> SharedString {
14163        match self {
14164            CompletionDocumentation::Undocumented => "".into(),
14165            CompletionDocumentation::SingleLine(s) => s.clone(),
14166            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
14167            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
14168            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
14169                single_line.clone()
14170            }
14171        }
14172    }
14173}
14174
14175impl From<lsp::Documentation> for CompletionDocumentation {
14176    fn from(docs: lsp::Documentation) -> Self {
14177        match docs {
14178            lsp::Documentation::String(text) => {
14179                if text.lines().count() <= 1 {
14180                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
14181                } else {
14182                    CompletionDocumentation::MultiLinePlainText(text.into())
14183                }
14184            }
14185
14186            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
14187                lsp::MarkupKind::PlainText => {
14188                    if value.lines().count() <= 1 {
14189                        CompletionDocumentation::SingleLine(value.into())
14190                    } else {
14191                        CompletionDocumentation::MultiLinePlainText(value.into())
14192                    }
14193                }
14194
14195                lsp::MarkupKind::Markdown => {
14196                    CompletionDocumentation::MultiLineMarkdown(value.into())
14197                }
14198            },
14199        }
14200    }
14201}
14202
14203pub enum ResolvedHint {
14204    Resolved(InlayHint),
14205    Resolving(Shared<Task<()>>),
14206}
14207
14208pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
14209    glob.components()
14210        .take_while(|component| match component {
14211            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
14212            _ => true,
14213        })
14214        .collect()
14215}
14216
14217pub struct SshLspAdapter {
14218    name: LanguageServerName,
14219    binary: LanguageServerBinary,
14220    initialization_options: Option<String>,
14221    code_action_kinds: Option<Vec<CodeActionKind>>,
14222}
14223
14224impl SshLspAdapter {
14225    pub fn new(
14226        name: LanguageServerName,
14227        binary: LanguageServerBinary,
14228        initialization_options: Option<String>,
14229        code_action_kinds: Option<String>,
14230    ) -> Self {
14231        Self {
14232            name,
14233            binary,
14234            initialization_options,
14235            code_action_kinds: code_action_kinds
14236                .as_ref()
14237                .and_then(|c| serde_json::from_str(c).ok()),
14238        }
14239    }
14240}
14241
14242impl LspInstaller for SshLspAdapter {
14243    type BinaryVersion = ();
14244    async fn check_if_user_installed(
14245        &self,
14246        _: &dyn LspAdapterDelegate,
14247        _: Option<Toolchain>,
14248        _: &AsyncApp,
14249    ) -> Option<LanguageServerBinary> {
14250        Some(self.binary.clone())
14251    }
14252
14253    async fn cached_server_binary(
14254        &self,
14255        _: PathBuf,
14256        _: &dyn LspAdapterDelegate,
14257    ) -> Option<LanguageServerBinary> {
14258        None
14259    }
14260
14261    async fn fetch_latest_server_version(
14262        &self,
14263        _: &dyn LspAdapterDelegate,
14264        _: bool,
14265        _: &mut AsyncApp,
14266    ) -> Result<()> {
14267        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14268    }
14269
14270    async fn fetch_server_binary(
14271        &self,
14272        _: (),
14273        _: PathBuf,
14274        _: &dyn LspAdapterDelegate,
14275    ) -> Result<LanguageServerBinary> {
14276        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14277    }
14278}
14279
14280#[async_trait(?Send)]
14281impl LspAdapter for SshLspAdapter {
14282    fn name(&self) -> LanguageServerName {
14283        self.name.clone()
14284    }
14285
14286    async fn initialization_options(
14287        self: Arc<Self>,
14288        _: &Arc<dyn LspAdapterDelegate>,
14289        _: &mut AsyncApp,
14290    ) -> Result<Option<serde_json::Value>> {
14291        let Some(options) = &self.initialization_options else {
14292            return Ok(None);
14293        };
14294        let result = serde_json::from_str(options)?;
14295        Ok(result)
14296    }
14297
14298    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14299        self.code_action_kinds.clone()
14300    }
14301}
14302
14303pub fn language_server_settings<'a>(
14304    delegate: &'a dyn LspAdapterDelegate,
14305    language: &LanguageServerName,
14306    cx: &'a App,
14307) -> Option<&'a LspSettings> {
14308    language_server_settings_for(
14309        SettingsLocation {
14310            worktree_id: delegate.worktree_id(),
14311            path: RelPath::empty(),
14312        },
14313        language,
14314        cx,
14315    )
14316}
14317
14318pub fn language_server_settings_for<'a>(
14319    location: SettingsLocation<'a>,
14320    language: &LanguageServerName,
14321    cx: &'a App,
14322) -> Option<&'a LspSettings> {
14323    ProjectSettings::get(Some(location), cx).lsp.get(language)
14324}
14325
14326pub struct LocalLspAdapterDelegate {
14327    lsp_store: WeakEntity<LspStore>,
14328    worktree: worktree::Snapshot,
14329    fs: Arc<dyn Fs>,
14330    http_client: Arc<dyn HttpClient>,
14331    language_registry: Arc<LanguageRegistry>,
14332    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14333}
14334
14335impl LocalLspAdapterDelegate {
14336    pub fn new(
14337        language_registry: Arc<LanguageRegistry>,
14338        environment: &Entity<ProjectEnvironment>,
14339        lsp_store: WeakEntity<LspStore>,
14340        worktree: &Entity<Worktree>,
14341        http_client: Arc<dyn HttpClient>,
14342        fs: Arc<dyn Fs>,
14343        cx: &mut App,
14344    ) -> Arc<Self> {
14345        let load_shell_env_task =
14346            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14347
14348        Arc::new(Self {
14349            lsp_store,
14350            worktree: worktree.read(cx).snapshot(),
14351            fs,
14352            http_client,
14353            language_registry,
14354            load_shell_env_task,
14355        })
14356    }
14357
14358    pub fn from_local_lsp(
14359        local: &LocalLspStore,
14360        worktree: &Entity<Worktree>,
14361        cx: &mut App,
14362    ) -> Arc<Self> {
14363        Self::new(
14364            local.languages.clone(),
14365            &local.environment,
14366            local.weak.clone(),
14367            worktree,
14368            local.http_client.clone(),
14369            local.fs.clone(),
14370            cx,
14371        )
14372    }
14373}
14374
14375#[async_trait]
14376impl LspAdapterDelegate for LocalLspAdapterDelegate {
14377    fn show_notification(&self, message: &str, cx: &mut App) {
14378        self.lsp_store
14379            .update(cx, |_, cx| {
14380                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14381            })
14382            .ok();
14383    }
14384
14385    fn http_client(&self) -> Arc<dyn HttpClient> {
14386        self.http_client.clone()
14387    }
14388
14389    fn worktree_id(&self) -> WorktreeId {
14390        self.worktree.id()
14391    }
14392
14393    fn worktree_root_path(&self) -> &Path {
14394        self.worktree.abs_path().as_ref()
14395    }
14396
14397    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14398        self.worktree.resolve_relative_path(path)
14399    }
14400
14401    async fn shell_env(&self) -> HashMap<String, String> {
14402        let task = self.load_shell_env_task.clone();
14403        task.await.unwrap_or_default()
14404    }
14405
14406    async fn npm_package_installed_version(
14407        &self,
14408        package_name: &str,
14409    ) -> Result<Option<(PathBuf, Version)>> {
14410        let local_package_directory = self.worktree_root_path();
14411        let node_modules_directory = local_package_directory.join("node_modules");
14412
14413        if let Some(version) =
14414            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14415        {
14416            return Ok(Some((node_modules_directory, version)));
14417        }
14418        let Some(npm) = self.which("npm".as_ref()).await else {
14419            log::warn!(
14420                "Failed to find npm executable for {:?}",
14421                local_package_directory
14422            );
14423            return Ok(None);
14424        };
14425
14426        let env = self.shell_env().await;
14427        let output = util::command::new_command(&npm)
14428            .args(["root", "-g"])
14429            .envs(env)
14430            .current_dir(local_package_directory)
14431            .output()
14432            .await?;
14433        let global_node_modules =
14434            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14435
14436        if let Some(version) =
14437            read_package_installed_version(global_node_modules.clone(), package_name).await?
14438        {
14439            return Ok(Some((global_node_modules, version)));
14440        }
14441        return Ok(None);
14442    }
14443
14444    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14445        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14446        if self.fs.is_file(&worktree_abs_path).await {
14447            worktree_abs_path.pop();
14448        }
14449
14450        let env = self.shell_env().await;
14451
14452        let shell_path = env.get("PATH").cloned();
14453
14454        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14455    }
14456
14457    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14458        let mut working_dir = self.worktree_root_path().to_path_buf();
14459        if self.fs.is_file(&working_dir).await {
14460            working_dir.pop();
14461        }
14462        let output = util::command::new_command(&command.path)
14463            .args(command.arguments)
14464            .envs(command.env.clone().unwrap_or_default())
14465            .current_dir(working_dir)
14466            .output()
14467            .await?;
14468
14469        anyhow::ensure!(
14470            output.status.success(),
14471            "{}, stdout: {:?}, stderr: {:?}",
14472            output.status,
14473            String::from_utf8_lossy(&output.stdout),
14474            String::from_utf8_lossy(&output.stderr)
14475        );
14476        Ok(())
14477    }
14478
14479    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14480        self.language_registry
14481            .update_lsp_binary_status(server_name, status);
14482    }
14483
14484    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14485        self.language_registry
14486            .all_lsp_adapters()
14487            .into_iter()
14488            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14489            .collect()
14490    }
14491
14492    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14493        let dir = self.language_registry.language_server_download_dir(name)?;
14494
14495        if !dir.exists() {
14496            smol::fs::create_dir_all(&dir)
14497                .await
14498                .context("failed to create container directory")
14499                .log_err()?;
14500        }
14501
14502        Some(dir)
14503    }
14504
14505    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14506        let entry = self
14507            .worktree
14508            .entry_for_path(path)
14509            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14510        let abs_path = self.worktree.absolutize(&entry.path);
14511        self.fs.load(&abs_path).await
14512    }
14513}
14514
14515async fn populate_labels_for_symbols(
14516    symbols: Vec<CoreSymbol>,
14517    language_registry: &Arc<LanguageRegistry>,
14518    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14519    output: &mut Vec<Symbol>,
14520) {
14521    #[allow(clippy::mutable_key_type)]
14522    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14523
14524    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14525    for symbol in symbols {
14526        let Some(file_name) = symbol.path.file_name() else {
14527            continue;
14528        };
14529        let language = language_registry
14530            .load_language_for_file_path(Path::new(file_name))
14531            .await
14532            .ok()
14533            .or_else(|| {
14534                unknown_paths.insert(file_name.into());
14535                None
14536            });
14537        symbols_by_language
14538            .entry(language)
14539            .or_default()
14540            .push(symbol);
14541    }
14542
14543    for unknown_path in unknown_paths {
14544        log::info!("no language found for symbol in file {unknown_path:?}");
14545    }
14546
14547    let mut label_params = Vec::new();
14548    for (language, mut symbols) in symbols_by_language {
14549        label_params.clear();
14550        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14551            name: mem::take(&mut symbol.name),
14552            kind: symbol.kind,
14553            container_name: symbol.container_name.take(),
14554        }));
14555
14556        let mut labels = Vec::new();
14557        if let Some(language) = language {
14558            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14559                language_registry
14560                    .lsp_adapters(&language.name())
14561                    .first()
14562                    .cloned()
14563            });
14564            if let Some(lsp_adapter) = lsp_adapter {
14565                labels = lsp_adapter
14566                    .labels_for_symbols(&label_params, &language)
14567                    .await
14568                    .log_err()
14569                    .unwrap_or_default();
14570            }
14571        }
14572
14573        for (
14574            (
14575                symbol,
14576                language::Symbol {
14577                    name,
14578                    container_name,
14579                    ..
14580                },
14581            ),
14582            label,
14583        ) in symbols
14584            .into_iter()
14585            .zip(label_params.drain(..))
14586            .zip(labels.into_iter().chain(iter::repeat(None)))
14587        {
14588            output.push(Symbol {
14589                language_server_name: symbol.language_server_name,
14590                source_worktree_id: symbol.source_worktree_id,
14591                source_language_server_id: symbol.source_language_server_id,
14592                path: symbol.path,
14593                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14594                name,
14595                kind: symbol.kind,
14596                range: symbol.range,
14597                container_name,
14598            });
14599        }
14600    }
14601}
14602
14603pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String {
14604    text.lines()
14605        .map(|line| line.trim())
14606        .filter(|line| !line.is_empty())
14607        .join(separator)
14608}
14609
14610fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14611    match server.capabilities().text_document_sync.as_ref()? {
14612        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14613            // Server wants didSave but didn't specify includeText.
14614            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14615            // Server doesn't want didSave at all.
14616            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14617            // Server provided SaveOptions.
14618            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14619                Some(save_options.include_text.unwrap_or(false))
14620            }
14621        },
14622        // We do not have any save info. Kind affects didChange only.
14623        lsp::TextDocumentSyncCapability::Kind(_) => None,
14624    }
14625}
14626
14627/// Completion items are displayed in a `UniformList`.
14628/// Usually, those items are single-line strings, but in LSP responses,
14629/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14630/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14631/// 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,
14632/// breaking the completions menu presentation.
14633///
14634/// 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.
14635pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14636    let mut new_text = String::with_capacity(label.text.len());
14637    let mut offset_map = vec![0; label.text.len() + 1];
14638    let mut last_char_was_space = false;
14639    let mut new_idx = 0;
14640    let chars = label.text.char_indices().fuse();
14641    let mut newlines_removed = false;
14642
14643    for (idx, c) in chars {
14644        offset_map[idx] = new_idx;
14645
14646        match c {
14647            '\n' if last_char_was_space => {
14648                newlines_removed = true;
14649            }
14650            '\t' | ' ' if last_char_was_space => {}
14651            '\n' if !last_char_was_space => {
14652                new_text.push(' ');
14653                new_idx += 1;
14654                last_char_was_space = true;
14655                newlines_removed = true;
14656            }
14657            ' ' | '\t' => {
14658                new_text.push(' ');
14659                new_idx += 1;
14660                last_char_was_space = true;
14661            }
14662            _ => {
14663                new_text.push(c);
14664                new_idx += c.len_utf8();
14665                last_char_was_space = false;
14666            }
14667        }
14668    }
14669    offset_map[label.text.len()] = new_idx;
14670
14671    // Only modify the label if newlines were removed.
14672    if !newlines_removed {
14673        return;
14674    }
14675
14676    let last_index = new_idx;
14677    let mut run_ranges_errors = Vec::new();
14678    label.runs.retain_mut(|(range, _)| {
14679        match offset_map.get(range.start) {
14680            Some(&start) => range.start = start,
14681            None => {
14682                run_ranges_errors.push(range.clone());
14683                return false;
14684            }
14685        }
14686
14687        match offset_map.get(range.end) {
14688            Some(&end) => range.end = end,
14689            None => {
14690                run_ranges_errors.push(range.clone());
14691                range.end = last_index;
14692            }
14693        }
14694        true
14695    });
14696    if !run_ranges_errors.is_empty() {
14697        log::error!(
14698            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14699            label.text
14700        );
14701    }
14702
14703    let mut wrong_filter_range = None;
14704    if label.filter_range == (0..label.text.len()) {
14705        label.filter_range = 0..new_text.len();
14706    } else {
14707        let mut original_filter_range = Some(label.filter_range.clone());
14708        match offset_map.get(label.filter_range.start) {
14709            Some(&start) => label.filter_range.start = start,
14710            None => {
14711                wrong_filter_range = original_filter_range.take();
14712                label.filter_range.start = last_index;
14713            }
14714        }
14715
14716        match offset_map.get(label.filter_range.end) {
14717            Some(&end) => label.filter_range.end = end,
14718            None => {
14719                wrong_filter_range = original_filter_range.take();
14720                label.filter_range.end = last_index;
14721            }
14722        }
14723    }
14724    if let Some(wrong_filter_range) = wrong_filter_range {
14725        log::error!(
14726            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14727            label.text
14728        );
14729    }
14730
14731    label.text = new_text;
14732}
14733
14734/// Apply edits to the buffer that will become part of the formatting transaction.
14735/// Fails if the buffer has been edited since the start of that transaction.
14736fn extend_formatting_transaction(
14737    buffer: &FormattableBuffer,
14738    formatting_transaction_id: text::TransactionId,
14739    cx: &mut AsyncApp,
14740    operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
14741) -> anyhow::Result<()> {
14742    buffer.handle.update(cx, |buffer, cx| {
14743        let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
14744        if last_transaction_id != Some(formatting_transaction_id) {
14745            anyhow::bail!("Buffer edited while formatting. Aborting")
14746        }
14747        buffer.start_transaction();
14748        operation(buffer, cx);
14749        if let Some(transaction_id) = buffer.end_transaction(cx) {
14750            buffer.merge_transactions(transaction_id, formatting_transaction_id);
14751        }
14752        Ok(())
14753    })
14754}