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, LanguageName, LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate,
   76    LspInstaller, ManifestDelegate, ManifestName, ModelineSettings, OffsetUtf16, Patch, PointUtf16,
   77    TextBufferSnapshot, ToOffset, ToOffsetUtf16, ToPointUtf16, Toolchain, Transaction, Unclipped,
   78    language_settings::{
   79        AllLanguageSettings, FormatOnSave, Formatter, LanguageSettings, all_language_settings,
   80    },
   81    modeline, point_to_lsp,
   82    proto::{
   83        deserialize_anchor, deserialize_anchor_range, deserialize_version, serialize_anchor,
   84        serialize_anchor_range, serialize_version,
   85    },
   86    range_from_lsp, range_to_lsp,
   87    row_chunk::RowChunk,
   88};
   89use lsp::{
   90    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   91    DEFAULT_LSP_REQUEST_TIMEOUT, DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   92    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   93    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LanguageServer,
   94    LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId, LanguageServerName,
   95    LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType, OneOf,
   96    RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles,
   97    WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   98};
   99use node_runtime::read_package_installed_version;
  100use parking_lot::Mutex;
  101use postage::{mpsc, sink::Sink, stream::Stream, watch};
  102use rand::prelude::*;
  103use rpc::{
  104    AnyProtoClient, ErrorCode, ErrorExt as _,
  105    proto::{LspRequestId, LspRequestMessage as _},
  106};
  107use semver::Version;
  108use serde::Serialize;
  109use serde_json::Value;
  110use settings::{Settings, SettingsLocation, SettingsStore};
  111use sha2::{Digest, Sha256};
  112use snippet::Snippet;
  113use std::{
  114    any::TypeId,
  115    borrow::Cow,
  116    cell::RefCell,
  117    cmp::{Ordering, Reverse},
  118    collections::{VecDeque, hash_map},
  119    convert::TryInto,
  120    ffi::OsStr,
  121    future::ready,
  122    iter, mem,
  123    ops::{ControlFlow, Range},
  124    path::{self, Path, PathBuf},
  125    pin::pin,
  126    rc::Rc,
  127    sync::{
  128        Arc,
  129        atomic::{self, AtomicUsize},
  130    },
  131    time::{Duration, Instant},
  132    vec,
  133};
  134use sum_tree::Dimensions;
  135use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  136
  137use util::{
  138    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  139    paths::{PathStyle, SanitizedPath, UrlExt},
  140    post_inc,
  141    redact::redact_command,
  142    rel_path::RelPath,
  143};
  144
  145pub use document_colors::DocumentColors;
  146pub use folding_ranges::LspFoldingRange;
  147pub use fs::*;
  148pub use language::Location;
  149pub use lsp_store::inlay_hints::{CacheInlayHints, InvalidationStrategy};
  150#[cfg(any(test, feature = "test-support"))]
  151pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  152#[cfg(any(test, feature = "test-support"))]
  153pub use prettier::RANGE_FORMAT_SUFFIX as TEST_PRETTIER_RANGE_FORMAT_SUFFIX;
  154pub use semantic_tokens::{
  155    BufferSemanticToken, BufferSemanticTokens, RefreshForServer, SemanticTokenStylizer, TokenType,
  156};
  157
  158pub use worktree::{
  159    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  160    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  161};
  162
  163const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  164pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  165const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  166const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  167static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  168
  169#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  170pub enum ProgressToken {
  171    Number(i32),
  172    String(SharedString),
  173}
  174
  175impl std::fmt::Display for ProgressToken {
  176    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  177        match self {
  178            Self::Number(number) => write!(f, "{number}"),
  179            Self::String(string) => write!(f, "{string}"),
  180        }
  181    }
  182}
  183
  184impl ProgressToken {
  185    fn from_lsp(value: lsp::NumberOrString) -> Self {
  186        match value {
  187            lsp::NumberOrString::Number(number) => Self::Number(number),
  188            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  189        }
  190    }
  191
  192    fn to_lsp(&self) -> lsp::NumberOrString {
  193        match self {
  194            Self::Number(number) => lsp::NumberOrString::Number(*number),
  195            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  196        }
  197    }
  198
  199    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  200        Some(match value.value? {
  201            proto::progress_token::Value::Number(number) => Self::Number(number),
  202            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  203        })
  204    }
  205
  206    fn to_proto(&self) -> proto::ProgressToken {
  207        proto::ProgressToken {
  208            value: Some(match self {
  209                Self::Number(number) => proto::progress_token::Value::Number(*number),
  210                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  211            }),
  212        }
  213    }
  214}
  215
  216#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  217pub enum FormatTrigger {
  218    Save,
  219    Manual,
  220}
  221
  222pub enum LspFormatTarget {
  223    Buffers,
  224    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  225}
  226
  227#[derive(Debug, Clone, PartialEq, Eq, Hash)]
  228pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  229
  230struct OpenLspBuffer(Entity<Buffer>);
  231
  232impl FormatTrigger {
  233    fn from_proto(value: i32) -> FormatTrigger {
  234        match value {
  235            0 => FormatTrigger::Save,
  236            1 => FormatTrigger::Manual,
  237            _ => FormatTrigger::Save,
  238        }
  239    }
  240}
  241
  242#[derive(Clone)]
  243struct UnifiedLanguageServer {
  244    id: LanguageServerId,
  245    project_roots: HashSet<Arc<RelPath>>,
  246}
  247
  248/// Settings that affect language server identity.
  249///
  250/// Dynamic settings (`LspSettings::settings`) are excluded because they can be
  251/// updated via `workspace/didChangeConfiguration` without restarting the server.
  252#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  253struct LanguageServerSeedSettings {
  254    binary: Option<BinarySettings>,
  255    initialization_options: Option<serde_json::Value>,
  256}
  257
  258#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  259struct LanguageServerSeed {
  260    worktree_id: WorktreeId,
  261    name: LanguageServerName,
  262    toolchain: Option<Toolchain>,
  263    settings: LanguageServerSeedSettings,
  264}
  265
  266#[derive(Debug)]
  267pub struct DocumentDiagnosticsUpdate<'a, D> {
  268    pub diagnostics: D,
  269    pub result_id: Option<SharedString>,
  270    pub registration_id: Option<SharedString>,
  271    pub server_id: LanguageServerId,
  272    pub disk_based_sources: Cow<'a, [String]>,
  273}
  274
  275pub struct DocumentDiagnostics {
  276    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  277    document_abs_path: PathBuf,
  278    version: Option<i32>,
  279}
  280
  281#[derive(Default, Debug)]
  282struct DynamicRegistrations {
  283    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  284    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  285}
  286
  287pub struct LocalLspStore {
  288    weak: WeakEntity<LspStore>,
  289    pub worktree_store: Entity<WorktreeStore>,
  290    toolchain_store: Entity<LocalToolchainStore>,
  291    http_client: Arc<dyn HttpClient>,
  292    environment: Entity<ProjectEnvironment>,
  293    fs: Arc<dyn Fs>,
  294    languages: Arc<LanguageRegistry>,
  295    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  296    yarn: Entity<YarnPathStore>,
  297    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  298    buffers_being_formatted: HashSet<BufferId>,
  299    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  300    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  301    watched_manifest_filenames: HashSet<ManifestName>,
  302    language_server_paths_watched_for_rename:
  303        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  304    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  305    supplementary_language_servers:
  306        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  307    prettier_store: Entity<PrettierStore>,
  308    next_diagnostic_group_id: usize,
  309    diagnostics: HashMap<
  310        WorktreeId,
  311        HashMap<
  312            Arc<RelPath>,
  313            Vec<(
  314                LanguageServerId,
  315                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  316            )>,
  317        >,
  318    >,
  319    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  320    _subscription: gpui::Subscription,
  321    lsp_tree: LanguageServerTree,
  322    registered_buffers: HashMap<BufferId, usize>,
  323    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  324    buffer_pull_diagnostics_result_ids: HashMap<
  325        LanguageServerId,
  326        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  327    >,
  328    workspace_pull_diagnostics_result_ids: HashMap<
  329        LanguageServerId,
  330        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  331    >,
  332    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  333
  334    buffers_to_refresh_hash_set: HashSet<BufferId>,
  335    buffers_to_refresh_queue: VecDeque<BufferId>,
  336    _background_diagnostics_worker: Shared<Task<()>>,
  337}
  338
  339impl LocalLspStore {
  340    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  341    pub fn running_language_server_for_id(
  342        &self,
  343        id: LanguageServerId,
  344    ) -> Option<&Arc<LanguageServer>> {
  345        let language_server_state = self.language_servers.get(&id)?;
  346
  347        match language_server_state {
  348            LanguageServerState::Running { server, .. } => Some(server),
  349            LanguageServerState::Starting { .. } => None,
  350        }
  351    }
  352
  353    fn get_or_insert_language_server(
  354        &mut self,
  355        worktree_handle: &Entity<Worktree>,
  356        delegate: Arc<LocalLspAdapterDelegate>,
  357        disposition: &Arc<LaunchDisposition>,
  358        language_name: &LanguageName,
  359        cx: &mut App,
  360    ) -> LanguageServerId {
  361        let key = LanguageServerSeed {
  362            worktree_id: worktree_handle.read(cx).id(),
  363            name: disposition.server_name.clone(),
  364            settings: LanguageServerSeedSettings {
  365                binary: disposition.settings.binary.clone(),
  366                initialization_options: disposition.settings.initialization_options.clone(),
  367            },
  368            toolchain: disposition.toolchain.clone(),
  369        };
  370        if let Some(state) = self.language_server_ids.get_mut(&key) {
  371            state.project_roots.insert(disposition.path.path.clone());
  372            state.id
  373        } else {
  374            let adapter = self
  375                .languages
  376                .lsp_adapters(language_name)
  377                .into_iter()
  378                .find(|adapter| adapter.name() == disposition.server_name)
  379                .expect("To find LSP adapter");
  380            let new_language_server_id = self.start_language_server(
  381                worktree_handle,
  382                delegate,
  383                adapter,
  384                disposition.settings.clone(),
  385                key.clone(),
  386                language_name.clone(),
  387                cx,
  388            );
  389            if let Some(state) = self.language_server_ids.get_mut(&key) {
  390                state.project_roots.insert(disposition.path.path.clone());
  391            } else {
  392                debug_assert!(
  393                    false,
  394                    "Expected `start_language_server` to ensure that `key` exists in a map"
  395                );
  396            }
  397            new_language_server_id
  398        }
  399    }
  400
  401    fn start_language_server(
  402        &mut self,
  403        worktree_handle: &Entity<Worktree>,
  404        delegate: Arc<LocalLspAdapterDelegate>,
  405        adapter: Arc<CachedLspAdapter>,
  406        settings: Arc<LspSettings>,
  407        key: LanguageServerSeed,
  408        language_name: LanguageName,
  409        cx: &mut App,
  410    ) -> LanguageServerId {
  411        let worktree = worktree_handle.read(cx);
  412
  413        let worktree_id = worktree.id();
  414        let worktree_abs_path = worktree.abs_path();
  415        let toolchain = key.toolchain.clone();
  416        let override_options = settings.initialization_options.clone();
  417
  418        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  419
  420        let server_id = self.languages.next_language_server_id();
  421        log::trace!(
  422            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  423            adapter.name.0
  424        );
  425
  426        let wait_until_worktree_trust =
  427            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  428                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  429                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  430                });
  431                if can_trust {
  432                    self.restricted_worktrees_tasks.remove(&worktree_id);
  433                    None
  434                } else {
  435                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  436                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  437                        hash_map::Entry::Vacant(v) => {
  438                            let (mut tx, rx) = watch::channel::<bool>();
  439                            let lsp_store = self.weak.clone();
  440                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  441                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  442                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  443                                        tx.blocking_send(true).ok();
  444                                        lsp_store
  445                                            .update(cx, |lsp_store, _| {
  446                                                if let Some(local_lsp_store) =
  447                                                    lsp_store.as_local_mut()
  448                                                {
  449                                                    local_lsp_store
  450                                                        .restricted_worktrees_tasks
  451                                                        .remove(&worktree_id);
  452                                                }
  453                                            })
  454                                            .ok();
  455                                    }
  456                                }
  457                            });
  458                            v.insert((subscription, rx.clone()));
  459                            Some(rx)
  460                        }
  461                    }
  462                }
  463            });
  464        let update_binary_status = wait_until_worktree_trust.is_none();
  465
  466        let binary = self.get_language_server_binary(
  467            worktree_abs_path.clone(),
  468            adapter.clone(),
  469            settings,
  470            toolchain.clone(),
  471            delegate.clone(),
  472            true,
  473            wait_until_worktree_trust,
  474            cx,
  475        );
  476        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  477
  478        let pending_server = cx.spawn({
  479            let adapter = adapter.clone();
  480            let server_name = adapter.name.clone();
  481            let stderr_capture = stderr_capture.clone();
  482            #[cfg(any(test, feature = "test-support"))]
  483            let lsp_store = self.weak.clone();
  484            let pending_workspace_folders = pending_workspace_folders.clone();
  485            async move |cx| {
  486                let binary = binary.await?;
  487                #[cfg(any(test, feature = "test-support"))]
  488                if let Some(server) = lsp_store
  489                    .update(&mut cx.clone(), |this, cx| {
  490                        this.languages.create_fake_language_server(
  491                            server_id,
  492                            &server_name,
  493                            binary.clone(),
  494                            &mut cx.to_async(),
  495                        )
  496                    })
  497                    .ok()
  498                    .flatten()
  499                {
  500                    return Ok(server);
  501                }
  502
  503                let code_action_kinds = adapter.code_action_kinds();
  504                lsp::LanguageServer::new(
  505                    stderr_capture,
  506                    server_id,
  507                    server_name,
  508                    binary,
  509                    &worktree_abs_path,
  510                    code_action_kinds,
  511                    Some(pending_workspace_folders),
  512                    cx,
  513                )
  514            }
  515        });
  516
  517        let startup = {
  518            let server_name = adapter.name.0.clone();
  519            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  520            let key = key.clone();
  521            let adapter = adapter.clone();
  522            let lsp_store = self.weak.clone();
  523            let pending_workspace_folders = pending_workspace_folders.clone();
  524            let pull_diagnostics = ProjectSettings::get_global(cx)
  525                .diagnostics
  526                .lsp_pull_diagnostics
  527                .enabled;
  528            let settings_location = SettingsLocation {
  529                worktree_id,
  530                path: RelPath::empty(),
  531            };
  532            let augments_syntax_tokens = AllLanguageSettings::get(Some(settings_location), cx)
  533                .language(Some(settings_location), Some(&language_name), cx)
  534                .semantic_tokens
  535                .use_tree_sitter();
  536            cx.spawn(async move |cx| {
  537                let result = async {
  538                    let language_server = pending_server.await?;
  539
  540                    let workspace_config = Self::workspace_configuration_for_adapter(
  541                        adapter.adapter.clone(),
  542                        &delegate,
  543                        toolchain,
  544                        None,
  545                        cx,
  546                    )
  547                    .await?;
  548
  549                    let mut initialization_options = Self::initialization_options_for_adapter(
  550                        adapter.adapter.clone(),
  551                        &delegate,
  552                        cx,
  553                    )
  554                    .await?;
  555
  556                    match (&mut initialization_options, override_options) {
  557                        (Some(initialization_options), Some(override_options)) => {
  558                            merge_json_value_into(override_options, initialization_options);
  559                        }
  560                        (None, override_options) => initialization_options = override_options,
  561                        _ => {}
  562                    }
  563
  564                    let initialization_params = cx.update(|cx| {
  565                        let mut params = language_server.default_initialize_params(
  566                            pull_diagnostics,
  567                            augments_syntax_tokens,
  568                            cx,
  569                        );
  570                        params.initialization_options = initialization_options;
  571                        adapter.adapter.prepare_initialize_params(params, cx)
  572                    })?;
  573
  574                    Self::setup_lsp_messages(
  575                        lsp_store.clone(),
  576                        &language_server,
  577                        delegate.clone(),
  578                        adapter.clone(),
  579                    );
  580
  581                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  582                        settings: workspace_config,
  583                    };
  584                    let language_server = cx
  585                        .update(|cx| {
  586                            let request_timeout = ProjectSettings::get_global(cx)
  587                                .global_lsp_settings
  588                                .get_request_timeout();
  589
  590                            language_server.initialize(
  591                                initialization_params,
  592                                Arc::new(did_change_configuration_params.clone()),
  593                                request_timeout,
  594                                cx,
  595                            )
  596                        })
  597                        .await
  598                        .inspect_err(|_| {
  599                            if let Some(lsp_store) = lsp_store.upgrade() {
  600                                lsp_store.update(cx, |lsp_store, cx| {
  601                                    lsp_store.cleanup_lsp_data(server_id);
  602                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  603                                });
  604                            }
  605                        })?;
  606
  607                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  608                        did_change_configuration_params,
  609                    )?;
  610
  611                    anyhow::Ok(language_server)
  612                }
  613                .await;
  614
  615                match result {
  616                    Ok(server) => {
  617                        lsp_store
  618                            .update(cx, |lsp_store, cx| {
  619                                lsp_store.insert_newly_running_language_server(
  620                                    adapter,
  621                                    server.clone(),
  622                                    server_id,
  623                                    key,
  624                                    pending_workspace_folders,
  625                                    cx,
  626                                );
  627                            })
  628                            .ok();
  629                        stderr_capture.lock().take();
  630                        Some(server)
  631                    }
  632
  633                    Err(err) => {
  634                        let log = stderr_capture.lock().take().unwrap_or_default();
  635                        delegate.update_status(
  636                            adapter.name(),
  637                            BinaryStatus::Failed {
  638                                error: if log.is_empty() {
  639                                    format!("{err:#}")
  640                                } else {
  641                                    format!("{err:#}\n-- stderr --\n{log}")
  642                                },
  643                            },
  644                        );
  645                        log::error!(
  646                            "Failed to start language server {server_name:?}: {}",
  647                            redact_command(&format!("{err:?}"))
  648                        );
  649                        if !log.is_empty() {
  650                            log::error!("server stderr: {}", redact_command(&log));
  651                        }
  652                        None
  653                    }
  654                }
  655            })
  656        };
  657        let state = LanguageServerState::Starting {
  658            startup,
  659            pending_workspace_folders,
  660        };
  661
  662        if update_binary_status {
  663            self.languages
  664                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  665        }
  666
  667        self.language_servers.insert(server_id, state);
  668        self.language_server_ids
  669            .entry(key)
  670            .or_insert(UnifiedLanguageServer {
  671                id: server_id,
  672                project_roots: Default::default(),
  673            });
  674        server_id
  675    }
  676
  677    fn get_language_server_binary(
  678        &self,
  679        worktree_abs_path: Arc<Path>,
  680        adapter: Arc<CachedLspAdapter>,
  681        settings: Arc<LspSettings>,
  682        toolchain: Option<Toolchain>,
  683        delegate: Arc<dyn LspAdapterDelegate>,
  684        allow_binary_download: bool,
  685        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  686        cx: &mut App,
  687    ) -> Task<Result<LanguageServerBinary>> {
  688        if let Some(settings) = &settings.binary
  689            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  690        {
  691            let settings = settings.clone();
  692            let languages = self.languages.clone();
  693            return cx.background_spawn(async move {
  694                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  695                    let already_trusted =  *wait_until_worktree_trust.borrow();
  696                    if !already_trusted {
  697                        log::info!(
  698                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  699                            adapter.name(),
  700                        );
  701                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  702                            if worktree_trusted {
  703                                break;
  704                            }
  705                        }
  706                        log::info!(
  707                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  708                            adapter.name(),
  709                        );
  710                    }
  711                    languages
  712                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  713                }
  714                let mut env = delegate.shell_env().await;
  715                env.extend(settings.env.unwrap_or_default());
  716
  717                Ok(LanguageServerBinary {
  718                    path: delegate.resolve_relative_path(path),
  719                    env: Some(env),
  720                    arguments: settings
  721                        .arguments
  722                        .unwrap_or_default()
  723                        .iter()
  724                        .map(Into::into)
  725                        .collect(),
  726                })
  727            });
  728        }
  729        let lsp_binary_options = LanguageServerBinaryOptions {
  730            allow_path_lookup: !settings
  731                .binary
  732                .as_ref()
  733                .and_then(|b| b.ignore_system_version)
  734                .unwrap_or_default(),
  735            allow_binary_download,
  736            pre_release: settings
  737                .fetch
  738                .as_ref()
  739                .and_then(|f| f.pre_release)
  740                .unwrap_or(false),
  741        };
  742
  743        cx.spawn(async move |cx| {
  744            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  745                let already_trusted =  *wait_until_worktree_trust.borrow();
  746                if !already_trusted {
  747                    log::info!(
  748                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  749                        adapter.name(),
  750                    );
  751                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  752                        if worktree_trusted {
  753                            break;
  754                        }
  755                    }
  756                    log::info!(
  757                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  758                            adapter.name(),
  759                    );
  760                }
  761            }
  762
  763            let (existing_binary, maybe_download_binary) = adapter
  764                .clone()
  765                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  766                .await
  767                .await;
  768
  769            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  770
  771            let mut binary = match (existing_binary, maybe_download_binary) {
  772                (binary, None) => binary?,
  773                (Err(_), Some(downloader)) => downloader.await?,
  774                (Ok(existing_binary), Some(downloader)) => {
  775                    let mut download_timeout = cx
  776                        .background_executor()
  777                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  778                        .fuse();
  779                    let mut downloader = downloader.fuse();
  780                    futures::select! {
  781                        _ = download_timeout => {
  782                            // Return existing binary and kick the existing work to the background.
  783                            cx.spawn(async move |_| downloader.await).detach();
  784                            Ok(existing_binary)
  785                        },
  786                        downloaded_or_existing_binary = downloader => {
  787                            // If download fails, this results in the existing binary.
  788                            downloaded_or_existing_binary
  789                        }
  790                    }?
  791                }
  792            };
  793            let mut shell_env = delegate.shell_env().await;
  794
  795            shell_env.extend(binary.env.unwrap_or_default());
  796
  797            if let Some(settings) = settings.binary.as_ref() {
  798                if let Some(arguments) = &settings.arguments {
  799                    binary.arguments = arguments.iter().map(Into::into).collect();
  800                }
  801                if let Some(env) = &settings.env {
  802                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  803                }
  804            }
  805
  806            binary.env = Some(shell_env);
  807            Ok(binary)
  808        })
  809    }
  810
  811    fn setup_lsp_messages(
  812        lsp_store: WeakEntity<LspStore>,
  813        language_server: &LanguageServer,
  814        delegate: Arc<dyn LspAdapterDelegate>,
  815        adapter: Arc<CachedLspAdapter>,
  816    ) {
  817        let name = language_server.name();
  818        let server_id = language_server.server_id();
  819        language_server
  820            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  821                let adapter = adapter.clone();
  822                let this = lsp_store.clone();
  823                move |mut params, cx| {
  824                    let adapter = adapter.clone();
  825                    if let Some(this) = this.upgrade() {
  826                        this.update(cx, |this, cx| {
  827                            adapter.process_diagnostics(&mut params, server_id);
  828
  829                            this.merge_lsp_diagnostics(
  830                                DiagnosticSourceKind::Pushed,
  831                                vec![DocumentDiagnosticsUpdate {
  832                                    server_id,
  833                                    diagnostics: params,
  834                                    result_id: None,
  835                                    disk_based_sources: Cow::Borrowed(
  836                                        &adapter.disk_based_diagnostic_sources,
  837                                    ),
  838                                    registration_id: None,
  839                                }],
  840                                |_, diagnostic, _cx| match diagnostic.source_kind {
  841                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  842                                        adapter.retain_old_diagnostic(diagnostic)
  843                                    }
  844                                    DiagnosticSourceKind::Pulled => true,
  845                                },
  846                                cx,
  847                            )
  848                            .log_err();
  849                        });
  850                    }
  851                }
  852            })
  853            .detach();
  854        language_server
  855            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  856                let adapter = adapter.adapter.clone();
  857                let delegate = delegate.clone();
  858                let this = lsp_store.clone();
  859                move |params, cx| {
  860                    let adapter = adapter.clone();
  861                    let delegate = delegate.clone();
  862                    let this = this.clone();
  863                    let mut cx = cx.clone();
  864                    async move {
  865                        let toolchain_for_id = this
  866                            .update(&mut cx, |this, _| {
  867                                this.as_local()?.language_server_ids.iter().find_map(
  868                                    |(seed, value)| {
  869                                        (value.id == server_id).then(|| seed.toolchain.clone())
  870                                    },
  871                                )
  872                            })?
  873                            .context("Expected the LSP store to be in a local mode")?;
  874
  875                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  876                        for item in &params.items {
  877                            let scope_uri = item.scope_uri.clone();
  878                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  879                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  880                            else {
  881                                // We've already queried workspace configuration of this URI.
  882                                continue;
  883                            };
  884                            let workspace_config = Self::workspace_configuration_for_adapter(
  885                                adapter.clone(),
  886                                &delegate,
  887                                toolchain_for_id.clone(),
  888                                scope_uri,
  889                                &mut cx,
  890                            )
  891                            .await?;
  892                            new_scope_uri.insert(workspace_config);
  893                        }
  894
  895                        Ok(params
  896                            .items
  897                            .into_iter()
  898                            .filter_map(|item| {
  899                                let workspace_config =
  900                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  901                                if let Some(section) = &item.section {
  902                                    Some(
  903                                        workspace_config
  904                                            .get(section)
  905                                            .cloned()
  906                                            .unwrap_or(serde_json::Value::Null),
  907                                    )
  908                                } else {
  909                                    Some(workspace_config.clone())
  910                                }
  911                            })
  912                            .collect())
  913                    }
  914                }
  915            })
  916            .detach();
  917
  918        language_server
  919            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  920                let this = lsp_store.clone();
  921                move |_, cx| {
  922                    let this = this.clone();
  923                    let cx = cx.clone();
  924                    async move {
  925                        let Some(server) =
  926                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  927                        else {
  928                            return Ok(None);
  929                        };
  930                        let root = server.workspace_folders();
  931                        Ok(Some(
  932                            root.into_iter()
  933                                .map(|uri| WorkspaceFolder {
  934                                    uri,
  935                                    name: Default::default(),
  936                                })
  937                                .collect(),
  938                        ))
  939                    }
  940                }
  941            })
  942            .detach();
  943        // Even though we don't have handling for these requests, respond to them to
  944        // avoid stalling any language server like `gopls` which waits for a response
  945        // to these requests when initializing.
  946        language_server
  947            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  948                let this = lsp_store.clone();
  949                move |params, cx| {
  950                    let this = this.clone();
  951                    let mut cx = cx.clone();
  952                    async move {
  953                        this.update(&mut cx, |this, _| {
  954                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  955                            {
  956                                status
  957                                    .progress_tokens
  958                                    .insert(ProgressToken::from_lsp(params.token));
  959                            }
  960                        })?;
  961
  962                        Ok(())
  963                    }
  964                }
  965            })
  966            .detach();
  967
  968        language_server
  969            .on_request::<lsp::request::RegisterCapability, _, _>({
  970                let lsp_store = lsp_store.clone();
  971                move |params, cx| {
  972                    let lsp_store = lsp_store.clone();
  973                    let mut cx = cx.clone();
  974                    async move {
  975                        lsp_store
  976                            .update(&mut cx, |lsp_store, cx| {
  977                                if lsp_store.as_local().is_some() {
  978                                    match lsp_store
  979                                        .register_server_capabilities(server_id, params, cx)
  980                                    {
  981                                        Ok(()) => {}
  982                                        Err(e) => {
  983                                            log::error!(
  984                                                "Failed to register server capabilities: {e:#}"
  985                                            );
  986                                        }
  987                                    };
  988                                }
  989                            })
  990                            .ok();
  991                        Ok(())
  992                    }
  993                }
  994            })
  995            .detach();
  996
  997        language_server
  998            .on_request::<lsp::request::UnregisterCapability, _, _>({
  999                let lsp_store = lsp_store.clone();
 1000                move |params, cx| {
 1001                    let lsp_store = lsp_store.clone();
 1002                    let mut cx = cx.clone();
 1003                    async move {
 1004                        lsp_store
 1005                            .update(&mut cx, |lsp_store, cx| {
 1006                                if lsp_store.as_local().is_some() {
 1007                                    match lsp_store
 1008                                        .unregister_server_capabilities(server_id, params, cx)
 1009                                    {
 1010                                        Ok(()) => {}
 1011                                        Err(e) => {
 1012                                            log::error!(
 1013                                                "Failed to unregister server capabilities: {e:#}"
 1014                                            );
 1015                                        }
 1016                                    }
 1017                                }
 1018                            })
 1019                            .ok();
 1020                        Ok(())
 1021                    }
 1022                }
 1023            })
 1024            .detach();
 1025
 1026        language_server
 1027            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
 1028                let this = lsp_store.clone();
 1029                move |params, cx| {
 1030                    let mut cx = cx.clone();
 1031                    let this = this.clone();
 1032                    async move {
 1033                        LocalLspStore::on_lsp_workspace_edit(
 1034                            this.clone(),
 1035                            params,
 1036                            server_id,
 1037                            &mut cx,
 1038                        )
 1039                        .await
 1040                    }
 1041                }
 1042            })
 1043            .detach();
 1044
 1045        language_server
 1046            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1047                let lsp_store = lsp_store.clone();
 1048                let request_id = Arc::new(AtomicUsize::new(0));
 1049                move |(), cx| {
 1050                    let lsp_store = lsp_store.clone();
 1051                    let request_id = request_id.clone();
 1052                    let mut cx = cx.clone();
 1053                    async move {
 1054                        lsp_store
 1055                            .update(&mut cx, |lsp_store, cx| {
 1056                                let request_id =
 1057                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1058                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1059                                    server_id,
 1060                                    request_id,
 1061                                });
 1062                                lsp_store
 1063                                    .downstream_client
 1064                                    .as_ref()
 1065                                    .map(|(client, project_id)| {
 1066                                        client.send(proto::RefreshInlayHints {
 1067                                            project_id: *project_id,
 1068                                            server_id: server_id.to_proto(),
 1069                                            request_id: request_id.map(|id| id as u64),
 1070                                        })
 1071                                    })
 1072                            })?
 1073                            .transpose()?;
 1074                        Ok(())
 1075                    }
 1076                }
 1077            })
 1078            .detach();
 1079
 1080        language_server
 1081            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1082                let this = lsp_store.clone();
 1083                move |(), cx| {
 1084                    let this = this.clone();
 1085                    let mut cx = cx.clone();
 1086                    async move {
 1087                        this.update(&mut cx, |this, cx| {
 1088                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1089                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1090                                client.send(proto::RefreshCodeLens {
 1091                                    project_id: *project_id,
 1092                                })
 1093                            })
 1094                        })?
 1095                        .transpose()?;
 1096                        Ok(())
 1097                    }
 1098                }
 1099            })
 1100            .detach();
 1101
 1102        language_server
 1103            .on_request::<lsp::request::SemanticTokensRefresh, _, _>({
 1104                let lsp_store = lsp_store.clone();
 1105                let request_id = Arc::new(AtomicUsize::new(0));
 1106                move |(), cx| {
 1107                    let lsp_store = lsp_store.clone();
 1108                    let request_id = request_id.clone();
 1109                    let mut cx = cx.clone();
 1110                    async move {
 1111                        lsp_store
 1112                            .update(&mut cx, |lsp_store, cx| {
 1113                                let request_id =
 1114                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1115                                cx.emit(LspStoreEvent::RefreshSemanticTokens {
 1116                                    server_id,
 1117                                    request_id,
 1118                                });
 1119                                lsp_store
 1120                                    .downstream_client
 1121                                    .as_ref()
 1122                                    .map(|(client, project_id)| {
 1123                                        client.send(proto::RefreshSemanticTokens {
 1124                                            project_id: *project_id,
 1125                                            server_id: server_id.to_proto(),
 1126                                            request_id: request_id.map(|id| id as u64),
 1127                                        })
 1128                                    })
 1129                            })?
 1130                            .transpose()?;
 1131                        Ok(())
 1132                    }
 1133                }
 1134            })
 1135            .detach();
 1136
 1137        language_server
 1138            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1139                let this = lsp_store.clone();
 1140                move |(), cx| {
 1141                    let this = this.clone();
 1142                    let mut cx = cx.clone();
 1143                    async move {
 1144                        this.update(&mut cx, |lsp_store, cx| {
 1145                            lsp_store.pull_workspace_diagnostics(server_id);
 1146                            lsp_store
 1147                                .downstream_client
 1148                                .as_ref()
 1149                                .map(|(client, project_id)| {
 1150                                    client.send(proto::PullWorkspaceDiagnostics {
 1151                                        project_id: *project_id,
 1152                                        server_id: server_id.to_proto(),
 1153                                    })
 1154                                })
 1155                                .transpose()?;
 1156                            anyhow::Ok(
 1157                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1158                            )
 1159                        })??
 1160                        .await;
 1161                        Ok(())
 1162                    }
 1163                }
 1164            })
 1165            .detach();
 1166
 1167        language_server
 1168            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1169                let this = lsp_store.clone();
 1170                let name = name.to_string();
 1171                let adapter = adapter.clone();
 1172                move |params, cx| {
 1173                    let this = this.clone();
 1174                    let name = name.to_string();
 1175                    let adapter = adapter.clone();
 1176                    let mut cx = cx.clone();
 1177                    async move {
 1178                        let actions = params.actions.unwrap_or_default();
 1179                        let message = params.message.clone();
 1180                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1181                        let level = match params.typ {
 1182                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1183                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1184                            _ => PromptLevel::Info,
 1185                        };
 1186                        let request = LanguageServerPromptRequest::new(
 1187                            level,
 1188                            params.message,
 1189                            actions,
 1190                            name.clone(),
 1191                            tx,
 1192                        );
 1193
 1194                        let did_update = this
 1195                            .update(&mut cx, |_, cx| {
 1196                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1197                            })
 1198                            .is_ok();
 1199                        if did_update {
 1200                            let response = rx.recv().await.ok();
 1201                            if let Some(ref selected_action) = response {
 1202                                let context = language::PromptResponseContext {
 1203                                    message,
 1204                                    selected_action: selected_action.clone(),
 1205                                };
 1206                                adapter.process_prompt_response(&context, &mut cx)
 1207                            }
 1208
 1209                            Ok(response)
 1210                        } else {
 1211                            Ok(None)
 1212                        }
 1213                    }
 1214                }
 1215            })
 1216            .detach();
 1217        language_server
 1218            .on_notification::<lsp::notification::ShowMessage, _>({
 1219                let this = lsp_store.clone();
 1220                let name = name.to_string();
 1221                move |params, cx| {
 1222                    let this = this.clone();
 1223                    let name = name.to_string();
 1224                    let mut cx = cx.clone();
 1225
 1226                    let (tx, _) = smol::channel::bounded(1);
 1227                    let level = match params.typ {
 1228                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1229                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1230                        _ => PromptLevel::Info,
 1231                    };
 1232                    let request =
 1233                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1234
 1235                    let _ = this.update(&mut cx, |_, cx| {
 1236                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1237                    });
 1238                }
 1239            })
 1240            .detach();
 1241
 1242        let disk_based_diagnostics_progress_token =
 1243            adapter.disk_based_diagnostics_progress_token.clone();
 1244
 1245        language_server
 1246            .on_notification::<lsp::notification::Progress, _>({
 1247                let this = lsp_store.clone();
 1248                move |params, cx| {
 1249                    if let Some(this) = this.upgrade() {
 1250                        this.update(cx, |this, cx| {
 1251                            this.on_lsp_progress(
 1252                                params,
 1253                                server_id,
 1254                                disk_based_diagnostics_progress_token.clone(),
 1255                                cx,
 1256                            );
 1257                        });
 1258                    }
 1259                }
 1260            })
 1261            .detach();
 1262
 1263        language_server
 1264            .on_notification::<lsp::notification::LogMessage, _>({
 1265                let this = lsp_store.clone();
 1266                move |params, cx| {
 1267                    if let Some(this) = this.upgrade() {
 1268                        this.update(cx, |_, cx| {
 1269                            cx.emit(LspStoreEvent::LanguageServerLog(
 1270                                server_id,
 1271                                LanguageServerLogType::Log(params.typ),
 1272                                params.message,
 1273                            ));
 1274                        });
 1275                    }
 1276                }
 1277            })
 1278            .detach();
 1279
 1280        language_server
 1281            .on_notification::<lsp::notification::LogTrace, _>({
 1282                let this = lsp_store.clone();
 1283                move |params, cx| {
 1284                    let mut cx = cx.clone();
 1285                    if let Some(this) = this.upgrade() {
 1286                        this.update(&mut cx, |_, cx| {
 1287                            cx.emit(LspStoreEvent::LanguageServerLog(
 1288                                server_id,
 1289                                LanguageServerLogType::Trace {
 1290                                    verbose_info: params.verbose,
 1291                                },
 1292                                params.message,
 1293                            ));
 1294                        });
 1295                    }
 1296                }
 1297            })
 1298            .detach();
 1299
 1300        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1301        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1302        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1303        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1304    }
 1305
 1306    fn shutdown_language_servers_on_quit(&mut self) -> impl Future<Output = ()> + use<> {
 1307        let shutdown_futures = self
 1308            .language_servers
 1309            .drain()
 1310            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1311            .collect::<Vec<_>>();
 1312
 1313        async move {
 1314            join_all(shutdown_futures).await;
 1315        }
 1316    }
 1317
 1318    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1319        match server_state {
 1320            LanguageServerState::Running { server, .. } => {
 1321                if let Some(shutdown) = server.shutdown() {
 1322                    shutdown.await;
 1323                }
 1324            }
 1325            LanguageServerState::Starting { startup, .. } => {
 1326                if let Some(server) = startup.await
 1327                    && let Some(shutdown) = server.shutdown()
 1328                {
 1329                    shutdown.await;
 1330                }
 1331            }
 1332        }
 1333        Ok(())
 1334    }
 1335
 1336    fn language_servers_for_worktree(
 1337        &self,
 1338        worktree_id: WorktreeId,
 1339    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1340        self.language_server_ids
 1341            .iter()
 1342            .filter_map(move |(seed, state)| {
 1343                if seed.worktree_id != worktree_id {
 1344                    return None;
 1345                }
 1346
 1347                if let Some(LanguageServerState::Running { server, .. }) =
 1348                    self.language_servers.get(&state.id)
 1349                {
 1350                    Some(server)
 1351                } else {
 1352                    None
 1353                }
 1354            })
 1355    }
 1356
 1357    fn language_server_ids_for_project_path(
 1358        &self,
 1359        project_path: ProjectPath,
 1360        language: &Language,
 1361        cx: &mut App,
 1362    ) -> Vec<LanguageServerId> {
 1363        let Some(worktree) = self
 1364            .worktree_store
 1365            .read(cx)
 1366            .worktree_for_id(project_path.worktree_id, cx)
 1367        else {
 1368            return Vec::new();
 1369        };
 1370        let delegate: Arc<dyn ManifestDelegate> =
 1371            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1372
 1373        self.lsp_tree
 1374            .get(
 1375                project_path,
 1376                language.name(),
 1377                language.manifest(),
 1378                &delegate,
 1379                cx,
 1380            )
 1381            .collect::<Vec<_>>()
 1382    }
 1383
 1384    fn language_server_ids_for_buffer(
 1385        &self,
 1386        buffer: &Buffer,
 1387        cx: &mut App,
 1388    ) -> Vec<LanguageServerId> {
 1389        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1390            let worktree_id = file.worktree_id(cx);
 1391
 1392            let path: Arc<RelPath> = file
 1393                .path()
 1394                .parent()
 1395                .map(Arc::from)
 1396                .unwrap_or_else(|| file.path().clone());
 1397            let worktree_path = ProjectPath { worktree_id, path };
 1398            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1399        } else {
 1400            Vec::new()
 1401        }
 1402    }
 1403
 1404    fn language_servers_for_buffer<'a>(
 1405        &'a self,
 1406        buffer: &'a Buffer,
 1407        cx: &'a mut App,
 1408    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1409        self.language_server_ids_for_buffer(buffer, cx)
 1410            .into_iter()
 1411            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1412                LanguageServerState::Running {
 1413                    adapter, server, ..
 1414                } => Some((adapter, server)),
 1415                _ => None,
 1416            })
 1417    }
 1418
 1419    async fn execute_code_action_kind_locally(
 1420        lsp_store: WeakEntity<LspStore>,
 1421        mut buffers: Vec<Entity<Buffer>>,
 1422        kind: CodeActionKind,
 1423        push_to_history: bool,
 1424        cx: &mut AsyncApp,
 1425    ) -> anyhow::Result<ProjectTransaction> {
 1426        // Do not allow multiple concurrent code actions requests for the
 1427        // same buffer.
 1428        lsp_store.update(cx, |this, cx| {
 1429            let this = this.as_local_mut().unwrap();
 1430            buffers.retain(|buffer| {
 1431                this.buffers_being_formatted
 1432                    .insert(buffer.read(cx).remote_id())
 1433            });
 1434        })?;
 1435        let _cleanup = defer({
 1436            let this = lsp_store.clone();
 1437            let mut cx = cx.clone();
 1438            let buffers = &buffers;
 1439            move || {
 1440                this.update(&mut cx, |this, cx| {
 1441                    let this = this.as_local_mut().unwrap();
 1442                    for buffer in buffers {
 1443                        this.buffers_being_formatted
 1444                            .remove(&buffer.read(cx).remote_id());
 1445                    }
 1446                })
 1447                .ok();
 1448            }
 1449        });
 1450        let mut project_transaction = ProjectTransaction::default();
 1451
 1452        for buffer in &buffers {
 1453            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1454                buffer.update(cx, |buffer, cx| {
 1455                    lsp_store
 1456                        .as_local()
 1457                        .unwrap()
 1458                        .language_servers_for_buffer(buffer, cx)
 1459                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1460                        .collect::<Vec<_>>()
 1461                })
 1462            })?;
 1463            for (_, language_server) in adapters_and_servers.iter() {
 1464                let actions = Self::get_server_code_actions_from_action_kinds(
 1465                    &lsp_store,
 1466                    language_server.server_id(),
 1467                    vec![kind.clone()],
 1468                    buffer,
 1469                    cx,
 1470                )
 1471                .await?;
 1472                Self::execute_code_actions_on_server(
 1473                    &lsp_store,
 1474                    language_server,
 1475                    actions,
 1476                    push_to_history,
 1477                    &mut project_transaction,
 1478                    cx,
 1479                )
 1480                .await?;
 1481            }
 1482        }
 1483        Ok(project_transaction)
 1484    }
 1485
 1486    async fn format_locally(
 1487        lsp_store: WeakEntity<LspStore>,
 1488        mut buffers: Vec<FormattableBuffer>,
 1489        push_to_history: bool,
 1490        trigger: FormatTrigger,
 1491        logger: zlog::Logger,
 1492        cx: &mut AsyncApp,
 1493    ) -> anyhow::Result<ProjectTransaction> {
 1494        // Do not allow multiple concurrent formatting requests for the
 1495        // same buffer.
 1496        lsp_store.update(cx, |this, cx| {
 1497            let this = this.as_local_mut().unwrap();
 1498            buffers.retain(|buffer| {
 1499                this.buffers_being_formatted
 1500                    .insert(buffer.handle.read(cx).remote_id())
 1501            });
 1502        })?;
 1503
 1504        let _cleanup = defer({
 1505            let this = lsp_store.clone();
 1506            let mut cx = cx.clone();
 1507            let buffers = &buffers;
 1508            move || {
 1509                this.update(&mut cx, |this, cx| {
 1510                    let this = this.as_local_mut().unwrap();
 1511                    for buffer in buffers {
 1512                        this.buffers_being_formatted
 1513                            .remove(&buffer.handle.read(cx).remote_id());
 1514                    }
 1515                })
 1516                .ok();
 1517            }
 1518        });
 1519
 1520        let mut project_transaction = ProjectTransaction::default();
 1521
 1522        for buffer in &buffers {
 1523            zlog::debug!(
 1524                logger =>
 1525                "formatting buffer '{:?}'",
 1526                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1527            );
 1528            // Create an empty transaction to hold all of the formatting edits.
 1529            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1530                // ensure no transactions created while formatting are
 1531                // grouped with the previous transaction in the history
 1532                // based on the transaction group interval
 1533                buffer.finalize_last_transaction();
 1534                buffer
 1535                    .start_transaction()
 1536                    .context("transaction already open")?;
 1537                buffer.end_transaction(cx);
 1538                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1539                buffer.finalize_last_transaction();
 1540                anyhow::Ok(transaction_id)
 1541            })?;
 1542
 1543            let result = Self::format_buffer_locally(
 1544                lsp_store.clone(),
 1545                buffer,
 1546                formatting_transaction_id,
 1547                trigger,
 1548                logger,
 1549                cx,
 1550            )
 1551            .await;
 1552
 1553            buffer.handle.update(cx, |buffer, cx| {
 1554                let Some(formatting_transaction) =
 1555                    buffer.get_transaction(formatting_transaction_id).cloned()
 1556                else {
 1557                    zlog::warn!(logger => "no formatting transaction");
 1558                    return;
 1559                };
 1560                if formatting_transaction.edit_ids.is_empty() {
 1561                    zlog::debug!(logger => "no changes made while formatting");
 1562                    buffer.forget_transaction(formatting_transaction_id);
 1563                    return;
 1564                }
 1565                if !push_to_history {
 1566                    zlog::trace!(logger => "forgetting format transaction");
 1567                    buffer.forget_transaction(formatting_transaction.id);
 1568                }
 1569                project_transaction
 1570                    .0
 1571                    .insert(cx.entity(), formatting_transaction);
 1572            });
 1573
 1574            result?;
 1575        }
 1576
 1577        Ok(project_transaction)
 1578    }
 1579
 1580    async fn format_buffer_locally(
 1581        lsp_store: WeakEntity<LspStore>,
 1582        buffer: &FormattableBuffer,
 1583        formatting_transaction_id: clock::Lamport,
 1584        trigger: FormatTrigger,
 1585        logger: zlog::Logger,
 1586        cx: &mut AsyncApp,
 1587    ) -> Result<()> {
 1588        let (adapters_and_servers, settings, request_timeout) =
 1589            lsp_store.update(cx, |lsp_store, cx| {
 1590                buffer.handle.update(cx, |buffer, cx| {
 1591                    let adapters_and_servers = lsp_store
 1592                        .as_local()
 1593                        .unwrap()
 1594                        .language_servers_for_buffer(buffer, cx)
 1595                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1596                        .collect::<Vec<_>>();
 1597                    let settings = LanguageSettings::for_buffer(buffer, cx).into_owned();
 1598                    let request_timeout = ProjectSettings::get_global(cx)
 1599                        .global_lsp_settings
 1600                        .get_request_timeout();
 1601                    (adapters_and_servers, settings, request_timeout)
 1602                })
 1603            })?;
 1604
 1605        // handle whitespace formatting
 1606        if settings.remove_trailing_whitespace_on_save {
 1607            zlog::trace!(logger => "removing trailing whitespace");
 1608            let diff = buffer
 1609                .handle
 1610                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1611                .await;
 1612            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1613                buffer.apply_diff(diff, cx);
 1614            })?;
 1615        }
 1616
 1617        if settings.ensure_final_newline_on_save {
 1618            zlog::trace!(logger => "ensuring final newline");
 1619            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1620                buffer.ensure_final_newline(cx);
 1621            })?;
 1622        }
 1623
 1624        // Formatter for `code_actions_on_format` that runs before
 1625        // the rest of the formatters
 1626        let mut code_actions_on_format_formatters = None;
 1627        let should_run_code_actions_on_format = !matches!(
 1628            (trigger, &settings.format_on_save),
 1629            (FormatTrigger::Save, &FormatOnSave::Off)
 1630        );
 1631        if should_run_code_actions_on_format {
 1632            let have_code_actions_to_run_on_format = settings
 1633                .code_actions_on_format
 1634                .values()
 1635                .any(|enabled| *enabled);
 1636            if have_code_actions_to_run_on_format {
 1637                zlog::trace!(logger => "going to run code actions on format");
 1638                code_actions_on_format_formatters = Some(
 1639                    settings
 1640                        .code_actions_on_format
 1641                        .iter()
 1642                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1643                        .cloned()
 1644                        .map(Formatter::CodeAction)
 1645                        .collect::<Vec<_>>(),
 1646                );
 1647            }
 1648        }
 1649
 1650        let formatters = match (trigger, &settings.format_on_save) {
 1651            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1652            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1653                settings.formatter.as_ref()
 1654            }
 1655        };
 1656
 1657        let formatters = code_actions_on_format_formatters
 1658            .iter()
 1659            .flatten()
 1660            .chain(formatters);
 1661
 1662        for formatter in formatters {
 1663            let formatter = if formatter == &Formatter::Auto {
 1664                if settings.prettier.allowed {
 1665                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1666                    &Formatter::Prettier
 1667                } else {
 1668                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1669                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1670                }
 1671            } else {
 1672                formatter
 1673            };
 1674            if let Err(err) = Self::apply_formatter(
 1675                formatter,
 1676                &lsp_store,
 1677                buffer,
 1678                formatting_transaction_id,
 1679                &adapters_and_servers,
 1680                &settings,
 1681                request_timeout,
 1682                logger,
 1683                cx,
 1684            )
 1685            .await
 1686            {
 1687                zlog::error!(logger => "Formatter failed, skipping: {err:#}");
 1688            }
 1689        }
 1690
 1691        Ok(())
 1692    }
 1693
 1694    async fn apply_formatter(
 1695        formatter: &Formatter,
 1696        lsp_store: &WeakEntity<LspStore>,
 1697        buffer: &FormattableBuffer,
 1698        formatting_transaction_id: clock::Lamport,
 1699        adapters_and_servers: &[(Arc<CachedLspAdapter>, Arc<LanguageServer>)],
 1700        settings: &LanguageSettings,
 1701        request_timeout: Duration,
 1702        logger: zlog::Logger,
 1703        cx: &mut AsyncApp,
 1704    ) -> anyhow::Result<()> {
 1705        match formatter {
 1706            Formatter::None => {
 1707                zlog::trace!(logger => "skipping formatter 'none'");
 1708                return Ok(());
 1709            }
 1710            Formatter::Auto => {
 1711                debug_panic!("Auto resolved above");
 1712                return Ok(());
 1713            }
 1714            Formatter::Prettier => {
 1715                let logger = zlog::scoped!(logger => "prettier");
 1716                zlog::trace!(logger => "formatting");
 1717                let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1718
 1719                // When selection ranges are provided (via FormatSelections), we pass the
 1720                // encompassing UTF-16 range to Prettier so it can scope its formatting.
 1721                // After diffing, we filter the resulting edits to only keep those that
 1722                // overlap with the original byte-level selection ranges.
 1723                let (range_utf16, byte_ranges) = match buffer.ranges.as_ref() {
 1724                    Some(ranges) if !ranges.is_empty() => {
 1725                        let (utf16_range, byte_ranges) =
 1726                            buffer.handle.read_with(cx, |buffer, _cx| {
 1727                                let snapshot = buffer.snapshot();
 1728                                let mut min_start_utf16 = OffsetUtf16(usize::MAX);
 1729                                let mut max_end_utf16 = OffsetUtf16(0);
 1730                                let mut byte_ranges = Vec::with_capacity(ranges.len());
 1731                                for range in ranges {
 1732                                    let start_utf16 = range.start.to_offset_utf16(&snapshot);
 1733                                    let end_utf16 = range.end.to_offset_utf16(&snapshot);
 1734                                    min_start_utf16.0 = min_start_utf16.0.min(start_utf16.0);
 1735                                    max_end_utf16.0 = max_end_utf16.0.max(end_utf16.0);
 1736
 1737                                    let start_byte = range.start.to_offset(&snapshot);
 1738                                    let end_byte = range.end.to_offset(&snapshot);
 1739                                    byte_ranges.push(start_byte..end_byte);
 1740                                }
 1741                                (min_start_utf16..max_end_utf16, byte_ranges)
 1742                            });
 1743                        (Some(utf16_range), Some(byte_ranges))
 1744                    }
 1745                    _ => (None, None),
 1746                };
 1747
 1748                let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1749                    lsp_store.prettier_store().unwrap().downgrade()
 1750                })?;
 1751                let diff = prettier_store::format_with_prettier(
 1752                    &prettier,
 1753                    &buffer.handle,
 1754                    range_utf16,
 1755                    cx,
 1756                )
 1757                .await
 1758                .transpose()?;
 1759                let Some(mut diff) = diff else {
 1760                    zlog::trace!(logger => "No changes");
 1761                    return Ok(());
 1762                };
 1763
 1764                if let Some(byte_ranges) = byte_ranges {
 1765                    diff.edits.retain(|(edit_range, _)| {
 1766                        byte_ranges.iter().any(|selection_range| {
 1767                            edit_range.start < selection_range.end
 1768                                && edit_range.end > selection_range.start
 1769                        })
 1770                    });
 1771                    if diff.edits.is_empty() {
 1772                        zlog::trace!(logger => "No changes within selection");
 1773                        return Ok(());
 1774                    }
 1775                }
 1776
 1777                extend_formatting_transaction(
 1778                    buffer,
 1779                    formatting_transaction_id,
 1780                    cx,
 1781                    |buffer, cx| {
 1782                        buffer.apply_diff(diff, cx);
 1783                    },
 1784                )?;
 1785            }
 1786            Formatter::External { command, arguments } => {
 1787                let logger = zlog::scoped!(logger => "command");
 1788
 1789                if buffer.ranges.is_some() {
 1790                    zlog::debug!(logger => "External formatter does not support range formatting; skipping");
 1791                    return Ok(());
 1792                }
 1793
 1794                zlog::trace!(logger => "formatting");
 1795                let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1796
 1797                let diff =
 1798                    Self::format_via_external_command(buffer, &command, arguments.as_deref(), cx)
 1799                        .await
 1800                        .with_context(|| {
 1801                            format!("Failed to format buffer via external command: {}", command)
 1802                        })?;
 1803                let Some(diff) = diff else {
 1804                    zlog::trace!(logger => "No changes");
 1805                    return Ok(());
 1806                };
 1807
 1808                extend_formatting_transaction(
 1809                    buffer,
 1810                    formatting_transaction_id,
 1811                    cx,
 1812                    |buffer, cx| {
 1813                        buffer.apply_diff(diff, cx);
 1814                    },
 1815                )?;
 1816            }
 1817            Formatter::LanguageServer(specifier) => {
 1818                let logger = zlog::scoped!(logger => "language-server");
 1819                zlog::trace!(logger => "formatting");
 1820                let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1821
 1822                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1823                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1824                    return Ok(());
 1825                };
 1826
 1827                let language_server = match specifier {
 1828                    settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1829                        adapters_and_servers.iter().find_map(|(adapter, server)| {
 1830                            if adapter.name.0.as_ref() == name {
 1831                                Some(server.clone())
 1832                            } else {
 1833                                None
 1834                            }
 1835                        })
 1836                    }
 1837                    settings::LanguageServerFormatterSpecifier::Current => adapters_and_servers
 1838                        .iter()
 1839                        .find(|(_, server)| Self::server_supports_formatting(server))
 1840                        .map(|(_, server)| server.clone()),
 1841                };
 1842
 1843                let Some(language_server) = language_server else {
 1844                    log::debug!(
 1845                        "No language server found to format buffer '{:?}'. Skipping",
 1846                        buffer_path_abs.as_path().to_string_lossy()
 1847                    );
 1848                    return Ok(());
 1849                };
 1850
 1851                zlog::trace!(
 1852                    logger =>
 1853                    "Formatting buffer '{:?}' using language server '{:?}'",
 1854                    buffer_path_abs.as_path().to_string_lossy(),
 1855                    language_server.name()
 1856                );
 1857
 1858                let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1859                    zlog::trace!(logger => "formatting ranges");
 1860                    Self::format_ranges_via_lsp(
 1861                        &lsp_store,
 1862                        &buffer.handle,
 1863                        ranges,
 1864                        buffer_path_abs,
 1865                        &language_server,
 1866                        &settings,
 1867                        cx,
 1868                    )
 1869                    .await
 1870                    .context("Failed to format ranges via language server")?
 1871                } else {
 1872                    zlog::trace!(logger => "formatting full");
 1873                    Self::format_via_lsp(
 1874                        &lsp_store,
 1875                        &buffer.handle,
 1876                        buffer_path_abs,
 1877                        &language_server,
 1878                        &settings,
 1879                        cx,
 1880                    )
 1881                    .await
 1882                    .context("failed to format via language server")?
 1883                };
 1884
 1885                if edits.is_empty() {
 1886                    zlog::trace!(logger => "No changes");
 1887                    return Ok(());
 1888                }
 1889                extend_formatting_transaction(
 1890                    buffer,
 1891                    formatting_transaction_id,
 1892                    cx,
 1893                    |buffer, cx| {
 1894                        buffer.edit(edits, None, cx);
 1895                    },
 1896                )?;
 1897            }
 1898            Formatter::CodeAction(code_action_name) => {
 1899                let logger = zlog::scoped!(logger => "code-actions");
 1900                zlog::trace!(logger => "formatting");
 1901                let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1902
 1903                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1904                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1905                    return Ok(());
 1906                };
 1907
 1908                let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1909                zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1910
 1911                let mut actions_and_servers = Vec::new();
 1912
 1913                for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1914                    let actions_result = Self::get_server_code_actions_from_action_kinds(
 1915                        &lsp_store,
 1916                        language_server.server_id(),
 1917                        vec![code_action_kind.clone()],
 1918                        &buffer.handle,
 1919                        cx,
 1920                    )
 1921                    .await
 1922                    .with_context(|| {
 1923                        format!(
 1924                            "Failed to resolve code action {:?} with language server {}",
 1925                            code_action_kind,
 1926                            language_server.name()
 1927                        )
 1928                    });
 1929                    let Ok(actions) = actions_result else {
 1930                        // note: it may be better to set result to the error and break formatters here
 1931                        // but for now we try to execute the actions that we can resolve and skip the rest
 1932                        zlog::error!(
 1933                            logger =>
 1934                            "Failed to resolve code action {:?} with language server {}",
 1935                            code_action_kind,
 1936                            language_server.name()
 1937                        );
 1938                        continue;
 1939                    };
 1940                    for action in actions {
 1941                        actions_and_servers.push((action, index));
 1942                    }
 1943                }
 1944
 1945                if actions_and_servers.is_empty() {
 1946                    zlog::warn!(logger => "No code actions were resolved, continuing");
 1947                    return Ok(());
 1948                }
 1949
 1950                'actions: for (mut action, server_index) in actions_and_servers {
 1951                    let server = &adapters_and_servers[server_index].1;
 1952
 1953                    let describe_code_action = |action: &CodeAction| {
 1954                        format!(
 1955                            "code action '{}' with title \"{}\" on server {}",
 1956                            action
 1957                                .lsp_action
 1958                                .action_kind()
 1959                                .unwrap_or("unknown".into())
 1960                                .as_str(),
 1961                            action.lsp_action.title(),
 1962                            server.name(),
 1963                        )
 1964                    };
 1965
 1966                    zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1967
 1968                    if let Err(err) =
 1969                        Self::try_resolve_code_action(server, &mut action, request_timeout).await
 1970                    {
 1971                        zlog::error!(
 1972                            logger =>
 1973                            "Failed to resolve {}. Error: {}",
 1974                            describe_code_action(&action),
 1975                            err
 1976                        );
 1977                        continue;
 1978                    }
 1979
 1980                    if let Some(edit) = action.lsp_action.edit().cloned() {
 1981                        // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1982                        // but filters out and logs warnings for code actions that require unreasonably
 1983                        // difficult handling on our part, such as:
 1984                        // - applying edits that call commands
 1985                        //   which can result in arbitrary workspace edits being sent from the server that
 1986                        //   have no way of being tied back to the command that initiated them (i.e. we
 1987                        //   can't know which edits are part of the format request, or if the server is done sending
 1988                        //   actions in response to the command)
 1989                        // - actions that create/delete/modify/rename files other than the one we are formatting
 1990                        //   as we then would need to handle such changes correctly in the local history as well
 1991                        //   as the remote history through the ProjectTransaction
 1992                        // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1993                        // Supporting these actions is not impossible, but not supported as of yet.
 1994                        if edit.changes.is_none() && edit.document_changes.is_none() {
 1995                            zlog::trace!(
 1996                                logger =>
 1997                                "No changes for code action. Skipping {}",
 1998                                describe_code_action(&action),
 1999                            );
 2000                            continue;
 2001                        }
 2002
 2003                        let mut operations = Vec::new();
 2004                        if let Some(document_changes) = edit.document_changes {
 2005                            match document_changes {
 2006                                lsp::DocumentChanges::Edits(edits) => operations.extend(
 2007                                    edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 2008                                ),
 2009                                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2010                            }
 2011                        } else if let Some(changes) = edit.changes {
 2012                            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2013                                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2014                                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2015                                        uri,
 2016                                        version: None,
 2017                                    },
 2018                                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2019                                })
 2020                            }));
 2021                        }
 2022
 2023                        let mut edits = Vec::with_capacity(operations.len());
 2024
 2025                        if operations.is_empty() {
 2026                            zlog::trace!(
 2027                                logger =>
 2028                                "No changes for code action. Skipping {}",
 2029                                describe_code_action(&action),
 2030                            );
 2031                            continue;
 2032                        }
 2033                        for operation in operations {
 2034                            let op = match operation {
 2035                                lsp::DocumentChangeOperation::Edit(op) => op,
 2036                                lsp::DocumentChangeOperation::Op(_) => {
 2037                                    zlog::warn!(
 2038                                        logger =>
 2039                                        "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 2040                                        describe_code_action(&action),
 2041                                    );
 2042                                    continue 'actions;
 2043                                }
 2044                            };
 2045                            let Ok(file_path) = op.text_document.uri.to_file_path() else {
 2046                                zlog::warn!(
 2047                                    logger =>
 2048                                    "Failed to convert URI '{:?}' to file path. Skipping {}",
 2049                                    &op.text_document.uri,
 2050                                    describe_code_action(&action),
 2051                                );
 2052                                continue 'actions;
 2053                            };
 2054                            if &file_path != buffer_path_abs {
 2055                                zlog::warn!(
 2056                                    logger =>
 2057                                    "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 2058                                    file_path,
 2059                                    buffer_path_abs,
 2060                                    describe_code_action(&action),
 2061                                );
 2062                                continue 'actions;
 2063                            }
 2064
 2065                            let mut lsp_edits = Vec::new();
 2066                            for edit in op.edits {
 2067                                match edit {
 2068                                    Edit::Plain(edit) => {
 2069                                        if !lsp_edits.contains(&edit) {
 2070                                            lsp_edits.push(edit);
 2071                                        }
 2072                                    }
 2073                                    Edit::Annotated(edit) => {
 2074                                        if !lsp_edits.contains(&edit.text_edit) {
 2075                                            lsp_edits.push(edit.text_edit);
 2076                                        }
 2077                                    }
 2078                                    Edit::Snippet(_) => {
 2079                                        zlog::warn!(
 2080                                            logger =>
 2081                                            "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 2082                                            describe_code_action(&action),
 2083                                        );
 2084                                        continue 'actions;
 2085                                    }
 2086                                }
 2087                            }
 2088                            let edits_result = lsp_store
 2089                                .update(cx, |lsp_store, cx| {
 2090                                    lsp_store.as_local_mut().unwrap().edits_from_lsp(
 2091                                        &buffer.handle,
 2092                                        lsp_edits,
 2093                                        server.server_id(),
 2094                                        op.text_document.version,
 2095                                        cx,
 2096                                    )
 2097                                })?
 2098                                .await;
 2099                            let Ok(resolved_edits) = edits_result else {
 2100                                zlog::warn!(
 2101                                    logger =>
 2102                                    "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 2103                                    buffer_path_abs.as_path(),
 2104                                    describe_code_action(&action),
 2105                                );
 2106                                continue 'actions;
 2107                            };
 2108                            edits.extend(resolved_edits);
 2109                        }
 2110
 2111                        if edits.is_empty() {
 2112                            zlog::warn!(logger => "No edits resolved from LSP");
 2113                            continue;
 2114                        }
 2115
 2116                        extend_formatting_transaction(
 2117                            buffer,
 2118                            formatting_transaction_id,
 2119                            cx,
 2120                            |buffer, cx| {
 2121                                zlog::info!(
 2122                                    "Applying edits {edits:?}. Content: {:?}",
 2123                                    buffer.text()
 2124                                );
 2125                                buffer.edit(edits, None, cx);
 2126                                zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 2127                            },
 2128                        )?;
 2129                    }
 2130
 2131                    let Some(command) = action.lsp_action.command() else {
 2132                        continue;
 2133                    };
 2134
 2135                    zlog::warn!(
 2136                        logger =>
 2137                        "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2138                        &command.command,
 2139                    );
 2140
 2141                    let server_capabilities = server.capabilities();
 2142                    let available_commands = server_capabilities
 2143                        .execute_command_provider
 2144                        .as_ref()
 2145                        .map(|options| options.commands.as_slice())
 2146                        .unwrap_or_default();
 2147                    if !available_commands.contains(&command.command) {
 2148                        zlog::warn!(
 2149                            logger =>
 2150                            "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2151                            command.command,
 2152                            server.name(),
 2153                        );
 2154                        continue;
 2155                    }
 2156
 2157                    extend_formatting_transaction(
 2158                        buffer,
 2159                        formatting_transaction_id,
 2160                        cx,
 2161                        |_, _| {},
 2162                    )?;
 2163                    zlog::info!(logger => "Executing command {}", &command.command);
 2164
 2165                    lsp_store.update(cx, |this, _| {
 2166                        this.as_local_mut()
 2167                            .unwrap()
 2168                            .last_workspace_edits_by_language_server
 2169                            .remove(&server.server_id());
 2170                    })?;
 2171
 2172                    let execute_command_result = server
 2173                        .request::<lsp::request::ExecuteCommand>(
 2174                            lsp::ExecuteCommandParams {
 2175                                command: command.command.clone(),
 2176                                arguments: command.arguments.clone().unwrap_or_default(),
 2177                                ..Default::default()
 2178                            },
 2179                            request_timeout,
 2180                        )
 2181                        .await
 2182                        .into_response();
 2183
 2184                    if execute_command_result.is_err() {
 2185                        zlog::error!(
 2186                            logger =>
 2187                            "Failed to execute command '{}' as part of {}",
 2188                            &command.command,
 2189                            describe_code_action(&action),
 2190                        );
 2191                        continue 'actions;
 2192                    }
 2193
 2194                    let mut project_transaction_command = lsp_store.update(cx, |this, _| {
 2195                        this.as_local_mut()
 2196                            .unwrap()
 2197                            .last_workspace_edits_by_language_server
 2198                            .remove(&server.server_id())
 2199                            .unwrap_or_default()
 2200                    })?;
 2201
 2202                    if let Some(transaction) = project_transaction_command.0.remove(&buffer.handle)
 2203                    {
 2204                        zlog::trace!(
 2205                            logger =>
 2206                            "Successfully captured {} edits that resulted from command {}",
 2207                            transaction.edit_ids.len(),
 2208                            &command.command,
 2209                        );
 2210                        let transaction_id_project_transaction = transaction.id;
 2211                        buffer.handle.update(cx, |buffer, _| {
 2212                            // it may have been removed from history if push_to_history was
 2213                            // false in deserialize_workspace_edit. If so push it so we
 2214                            // can merge it with the format transaction
 2215                            // and pop the combined transaction off the history stack
 2216                            // later if push_to_history is false
 2217                            if buffer.get_transaction(transaction.id).is_none() {
 2218                                buffer.push_transaction(transaction, Instant::now());
 2219                            }
 2220                            buffer.merge_transactions(
 2221                                transaction_id_project_transaction,
 2222                                formatting_transaction_id,
 2223                            );
 2224                        });
 2225                    }
 2226
 2227                    if project_transaction_command.0.is_empty() {
 2228                        continue;
 2229                    }
 2230
 2231                    let mut extra_buffers = String::new();
 2232                    for buffer in project_transaction_command.0.keys() {
 2233                        buffer.read_with(cx, |b, cx| {
 2234                            let Some(path) = b.project_path(cx) else {
 2235                                return;
 2236                            };
 2237
 2238                            if !extra_buffers.is_empty() {
 2239                                extra_buffers.push_str(", ");
 2240                            }
 2241                            extra_buffers.push_str(path.path.as_unix_str());
 2242                        });
 2243                    }
 2244                    zlog::warn!(
 2245                        logger =>
 2246                        "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2247                        &command.command,
 2248                        extra_buffers,
 2249                    );
 2250                    // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2251                    // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2252                    // add it so it's included, and merge it into the format transaction when its created later
 2253                }
 2254            }
 2255        }
 2256
 2257        Ok(())
 2258    }
 2259
 2260    pub async fn format_ranges_via_lsp(
 2261        this: &WeakEntity<LspStore>,
 2262        buffer_handle: &Entity<Buffer>,
 2263        ranges: &[Range<Anchor>],
 2264        abs_path: &Path,
 2265        language_server: &Arc<LanguageServer>,
 2266        settings: &LanguageSettings,
 2267        cx: &mut AsyncApp,
 2268    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2269        let capabilities = &language_server.capabilities();
 2270        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2271        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2272            anyhow::bail!(
 2273                "{} language server does not support range formatting",
 2274                language_server.name()
 2275            );
 2276        }
 2277
 2278        let uri = file_path_to_lsp_url(abs_path)?;
 2279        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2280
 2281        let request_timeout = cx.update(|app| {
 2282            ProjectSettings::get_global(app)
 2283                .global_lsp_settings
 2284                .get_request_timeout()
 2285        });
 2286        let lsp_edits = {
 2287            let mut lsp_ranges = Vec::new();
 2288            this.update(cx, |_this, cx| {
 2289                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2290                // not have been sent to the language server. This seems like a fairly systemic
 2291                // issue, though, the resolution probably is not specific to formatting.
 2292                //
 2293                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2294                // LSP.
 2295                let snapshot = buffer_handle.read(cx).snapshot();
 2296                for range in ranges {
 2297                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2298                }
 2299                anyhow::Ok(())
 2300            })??;
 2301
 2302            let mut edits = None;
 2303            for range in lsp_ranges {
 2304                if let Some(mut edit) = language_server
 2305                    .request::<lsp::request::RangeFormatting>(
 2306                        lsp::DocumentRangeFormattingParams {
 2307                            text_document: text_document.clone(),
 2308                            range,
 2309                            options: lsp_command::lsp_formatting_options(settings),
 2310                            work_done_progress_params: Default::default(),
 2311                        },
 2312                        request_timeout,
 2313                    )
 2314                    .await
 2315                    .into_response()?
 2316                {
 2317                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2318                }
 2319            }
 2320            edits
 2321        };
 2322
 2323        if let Some(lsp_edits) = lsp_edits {
 2324            this.update(cx, |this, cx| {
 2325                this.as_local_mut().unwrap().edits_from_lsp(
 2326                    buffer_handle,
 2327                    lsp_edits,
 2328                    language_server.server_id(),
 2329                    None,
 2330                    cx,
 2331                )
 2332            })?
 2333            .await
 2334        } else {
 2335            Ok(Vec::with_capacity(0))
 2336        }
 2337    }
 2338
 2339    fn server_supports_formatting(server: &Arc<LanguageServer>) -> bool {
 2340        let capabilities = server.capabilities();
 2341        let formatting = capabilities.document_formatting_provider.as_ref();
 2342        let range_formatting = capabilities.document_range_formatting_provider.as_ref();
 2343        matches!(formatting, Some(p) if *p != OneOf::Left(false))
 2344            || matches!(range_formatting, Some(p) if *p != OneOf::Left(false))
 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        }
 4434    }
 4435
 4436    fn on_prettier_store_event(
 4437        &mut self,
 4438        _: Entity<PrettierStore>,
 4439        event: &PrettierStoreEvent,
 4440        cx: &mut Context<Self>,
 4441    ) {
 4442        match event {
 4443            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4444                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4445            }
 4446            PrettierStoreEvent::LanguageServerAdded {
 4447                new_server_id,
 4448                name,
 4449                prettier_server,
 4450            } => {
 4451                self.register_supplementary_language_server(
 4452                    *new_server_id,
 4453                    name.clone(),
 4454                    prettier_server.clone(),
 4455                    cx,
 4456                );
 4457            }
 4458        }
 4459    }
 4460
 4461    fn on_toolchain_store_event(
 4462        &mut self,
 4463        _: Entity<LocalToolchainStore>,
 4464        event: &ToolchainStoreEvent,
 4465        _: &mut Context<Self>,
 4466    ) {
 4467        if let ToolchainStoreEvent::ToolchainActivated = event {
 4468            self.request_workspace_config_refresh()
 4469        }
 4470    }
 4471
 4472    fn request_workspace_config_refresh(&mut self) {
 4473        *self._maintain_workspace_config.1.borrow_mut() = ();
 4474    }
 4475
 4476    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4477        self.as_local().map(|local| local.prettier_store.clone())
 4478    }
 4479
 4480    fn on_buffer_event(
 4481        &mut self,
 4482        buffer: Entity<Buffer>,
 4483        event: &language::BufferEvent,
 4484        cx: &mut Context<Self>,
 4485    ) {
 4486        match event {
 4487            language::BufferEvent::Edited { .. } => {
 4488                self.on_buffer_edited(buffer, cx);
 4489            }
 4490
 4491            language::BufferEvent::Saved => {
 4492                self.on_buffer_saved(buffer, cx);
 4493            }
 4494
 4495            language::BufferEvent::Reloaded => {
 4496                self.on_buffer_reloaded(buffer, cx);
 4497            }
 4498
 4499            _ => {}
 4500        }
 4501    }
 4502
 4503    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4504        buffer
 4505            .read(cx)
 4506            .set_language_registry(self.languages.clone());
 4507
 4508        cx.subscribe(buffer, |this, buffer, event, cx| {
 4509            this.on_buffer_event(buffer, event, cx);
 4510        })
 4511        .detach();
 4512
 4513        self.parse_modeline(buffer, cx);
 4514        self.detect_language_for_buffer(buffer, cx);
 4515        if let Some(local) = self.as_local_mut() {
 4516            local.initialize_buffer(buffer, cx);
 4517        }
 4518
 4519        Ok(())
 4520    }
 4521
 4522    pub fn refresh_background_diagnostics_for_buffers(
 4523        &mut self,
 4524        buffers: HashSet<BufferId>,
 4525        cx: &mut Context<Self>,
 4526    ) -> Shared<Task<()>> {
 4527        let Some(local) = self.as_local_mut() else {
 4528            return Task::ready(()).shared();
 4529        };
 4530        for buffer in buffers {
 4531            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4532                local.buffers_to_refresh_queue.push_back(buffer);
 4533                if local.buffers_to_refresh_queue.len() == 1 {
 4534                    local._background_diagnostics_worker =
 4535                        Self::background_diagnostics_worker(cx).shared();
 4536                }
 4537            }
 4538        }
 4539
 4540        local._background_diagnostics_worker.clone()
 4541    }
 4542
 4543    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4544        let buffer_store = self.buffer_store.clone();
 4545        let local = self.as_local_mut()?;
 4546        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4547            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4548            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4549                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4550            }
 4551        }
 4552        None
 4553    }
 4554
 4555    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4556        cx.spawn(async move |this, cx| {
 4557            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4558                task.await.log_err();
 4559            }
 4560        })
 4561    }
 4562
 4563    fn on_buffer_reloaded(&mut self, buffer: Entity<Buffer>, cx: &mut Context<Self>) {
 4564        if self.parse_modeline(&buffer, cx) {
 4565            self.detect_language_for_buffer(&buffer, cx);
 4566        }
 4567
 4568        let buffer_id = buffer.read(cx).remote_id();
 4569        let task = self.pull_diagnostics_for_buffer(buffer, cx);
 4570        self.buffer_reload_tasks.insert(buffer_id, task);
 4571    }
 4572
 4573    pub(crate) fn register_buffer_with_language_servers(
 4574        &mut self,
 4575        buffer: &Entity<Buffer>,
 4576        only_register_servers: HashSet<LanguageServerSelector>,
 4577        ignore_refcounts: bool,
 4578        cx: &mut Context<Self>,
 4579    ) -> OpenLspBufferHandle {
 4580        let buffer_id = buffer.read(cx).remote_id();
 4581        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4582        if let Some(local) = self.as_local_mut() {
 4583            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4584            if !ignore_refcounts {
 4585                *refcount += 1;
 4586            }
 4587
 4588            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4589            // 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
 4590            // 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
 4591            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4592            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4593                return handle;
 4594            };
 4595            if !file.is_local() {
 4596                return handle;
 4597            }
 4598
 4599            if ignore_refcounts || *refcount == 1 {
 4600                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4601            }
 4602            if !ignore_refcounts {
 4603                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4604                    let refcount = {
 4605                        let local = lsp_store.as_local_mut().unwrap();
 4606                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4607                            debug_panic!("bad refcounting");
 4608                            return;
 4609                        };
 4610
 4611                        *refcount -= 1;
 4612                        *refcount
 4613                    };
 4614                    if refcount == 0 {
 4615                        lsp_store.lsp_data.remove(&buffer_id);
 4616                        lsp_store.buffer_reload_tasks.remove(&buffer_id);
 4617                        let local = lsp_store.as_local_mut().unwrap();
 4618                        local.registered_buffers.remove(&buffer_id);
 4619
 4620                        local.buffers_opened_in_servers.remove(&buffer_id);
 4621                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4622                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4623
 4624                            let buffer_abs_path = file.abs_path(cx);
 4625                            for (_, buffer_pull_diagnostics_result_ids) in
 4626                                &mut local.buffer_pull_diagnostics_result_ids
 4627                            {
 4628                                buffer_pull_diagnostics_result_ids.retain(
 4629                                    |_, buffer_result_ids| {
 4630                                        buffer_result_ids.remove(&buffer_abs_path);
 4631                                        !buffer_result_ids.is_empty()
 4632                                    },
 4633                                );
 4634                            }
 4635
 4636                            let diagnostic_updates = local
 4637                                .language_servers
 4638                                .keys()
 4639                                .cloned()
 4640                                .map(|server_id| DocumentDiagnosticsUpdate {
 4641                                    diagnostics: DocumentDiagnostics {
 4642                                        document_abs_path: buffer_abs_path.clone(),
 4643                                        version: None,
 4644                                        diagnostics: Vec::new(),
 4645                                    },
 4646                                    result_id: None,
 4647                                    registration_id: None,
 4648                                    server_id,
 4649                                    disk_based_sources: Cow::Borrowed(&[]),
 4650                                })
 4651                                .collect::<Vec<_>>();
 4652
 4653                            lsp_store
 4654                                .merge_diagnostic_entries(
 4655                                    diagnostic_updates,
 4656                                    |_, diagnostic, _| {
 4657                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4658                                    },
 4659                                    cx,
 4660                                )
 4661                                .context("Clearing diagnostics for the closed buffer")
 4662                                .log_err();
 4663                        }
 4664                    }
 4665                })
 4666                .detach();
 4667            }
 4668        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4669            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4670            cx.background_spawn(async move {
 4671                upstream_client
 4672                    .request(proto::RegisterBufferWithLanguageServers {
 4673                        project_id: upstream_project_id,
 4674                        buffer_id,
 4675                        only_servers: only_register_servers
 4676                            .into_iter()
 4677                            .map(|selector| {
 4678                                let selector = match selector {
 4679                                    LanguageServerSelector::Id(language_server_id) => {
 4680                                        proto::language_server_selector::Selector::ServerId(
 4681                                            language_server_id.to_proto(),
 4682                                        )
 4683                                    }
 4684                                    LanguageServerSelector::Name(language_server_name) => {
 4685                                        proto::language_server_selector::Selector::Name(
 4686                                            language_server_name.to_string(),
 4687                                        )
 4688                                    }
 4689                                };
 4690                                proto::LanguageServerSelector {
 4691                                    selector: Some(selector),
 4692                                }
 4693                            })
 4694                            .collect(),
 4695                    })
 4696                    .await
 4697            })
 4698            .detach();
 4699        } else {
 4700            // Our remote connection got closed
 4701        }
 4702        handle
 4703    }
 4704
 4705    fn maintain_buffer_languages(
 4706        languages: Arc<LanguageRegistry>,
 4707        cx: &mut Context<Self>,
 4708    ) -> Task<()> {
 4709        let mut subscription = languages.subscribe();
 4710        let mut prev_reload_count = languages.reload_count();
 4711        cx.spawn(async move |this, cx| {
 4712            while let Some(()) = subscription.next().await {
 4713                if let Some(this) = this.upgrade() {
 4714                    // If the language registry has been reloaded, then remove and
 4715                    // re-assign the languages on all open buffers.
 4716                    let reload_count = languages.reload_count();
 4717                    if reload_count > prev_reload_count {
 4718                        prev_reload_count = reload_count;
 4719                        this.update(cx, |this, cx| {
 4720                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4721                                for buffer in buffer_store.buffers() {
 4722                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4723                                    {
 4724                                        buffer.update(cx, |buffer, cx| {
 4725                                            buffer.set_language_async(None, cx)
 4726                                        });
 4727                                        if let Some(local) = this.as_local_mut() {
 4728                                            local.reset_buffer(&buffer, &f, cx);
 4729
 4730                                            if local
 4731                                                .registered_buffers
 4732                                                .contains_key(&buffer.read(cx).remote_id())
 4733                                                && let Some(file_url) =
 4734                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4735                                            {
 4736                                                local.unregister_buffer_from_language_servers(
 4737                                                    &buffer, &file_url, cx,
 4738                                                );
 4739                                            }
 4740                                        }
 4741                                    }
 4742                                }
 4743                            });
 4744                        });
 4745                    }
 4746
 4747                    this.update(cx, |this, cx| {
 4748                        let mut plain_text_buffers = Vec::new();
 4749                        let mut buffers_with_unknown_injections = Vec::new();
 4750                        for handle in this.buffer_store.read(cx).buffers() {
 4751                            let buffer = handle.read(cx);
 4752                            if buffer.language().is_none()
 4753                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4754                            {
 4755                                plain_text_buffers.push(handle);
 4756                            } else if buffer.contains_unknown_injections() {
 4757                                buffers_with_unknown_injections.push(handle);
 4758                            }
 4759                        }
 4760
 4761                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4762                        // and reused later in the invisible worktrees.
 4763                        plain_text_buffers.sort_by_key(|buffer| {
 4764                            Reverse(
 4765                                File::from_dyn(buffer.read(cx).file())
 4766                                    .map(|file| file.worktree.read(cx).is_visible()),
 4767                            )
 4768                        });
 4769
 4770                        for buffer in plain_text_buffers {
 4771                            this.detect_language_for_buffer(&buffer, cx);
 4772                            if let Some(local) = this.as_local_mut() {
 4773                                local.initialize_buffer(&buffer, cx);
 4774                                if local
 4775                                    .registered_buffers
 4776                                    .contains_key(&buffer.read(cx).remote_id())
 4777                                {
 4778                                    local.register_buffer_with_language_servers(
 4779                                        &buffer,
 4780                                        HashSet::default(),
 4781                                        cx,
 4782                                    );
 4783                                }
 4784                            }
 4785                        }
 4786
 4787                        for buffer in buffers_with_unknown_injections {
 4788                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4789                        }
 4790                    });
 4791                }
 4792            }
 4793        })
 4794    }
 4795
 4796    fn parse_modeline(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<Self>) -> bool {
 4797        let buffer = buffer_handle.read(cx);
 4798        let content = buffer.as_rope();
 4799
 4800        let modeline_settings = {
 4801            let settings_store = cx.global::<SettingsStore>();
 4802            let modeline_lines = settings_store
 4803                .raw_user_settings()
 4804                .and_then(|s| s.content.modeline_lines)
 4805                .or(settings_store.raw_default_settings().modeline_lines)
 4806                .unwrap_or(5);
 4807
 4808            const MAX_MODELINE_BYTES: usize = 1024;
 4809
 4810            let first_bytes =
 4811                content.clip_offset(content.len().min(MAX_MODELINE_BYTES), Bias::Left);
 4812            let mut first_lines = Vec::new();
 4813            let mut lines = content.chunks_in_range(0..first_bytes).lines();
 4814            for _ in 0..modeline_lines {
 4815                if let Some(line) = lines.next() {
 4816                    first_lines.push(line.to_string());
 4817                } else {
 4818                    break;
 4819                }
 4820            }
 4821            let first_lines_ref: Vec<_> = first_lines.iter().map(|line| line.as_str()).collect();
 4822
 4823            let last_start =
 4824                content.clip_offset(content.len().saturating_sub(MAX_MODELINE_BYTES), Bias::Left);
 4825            let mut last_lines = Vec::new();
 4826            let mut lines = content
 4827                .reversed_chunks_in_range(last_start..content.len())
 4828                .lines();
 4829            for _ in 0..modeline_lines {
 4830                if let Some(line) = lines.next() {
 4831                    last_lines.push(line.to_string());
 4832                } else {
 4833                    break;
 4834                }
 4835            }
 4836            let last_lines_ref: Vec<_> =
 4837                last_lines.iter().rev().map(|line| line.as_str()).collect();
 4838            modeline::parse_modeline(&first_lines_ref, &last_lines_ref)
 4839        };
 4840
 4841        log::debug!("Parsed modeline settings: {:?}", modeline_settings);
 4842
 4843        buffer_handle.update(cx, |buffer, _cx| buffer.set_modeline(modeline_settings))
 4844    }
 4845
 4846    fn detect_language_for_buffer(
 4847        &mut self,
 4848        buffer_handle: &Entity<Buffer>,
 4849        cx: &mut Context<Self>,
 4850    ) -> Option<language::AvailableLanguage> {
 4851        // If the buffer has a language, set it and start the language server if we haven't already.
 4852        let buffer = buffer_handle.read(cx);
 4853        let file = buffer.file()?;
 4854        let content = buffer.as_rope();
 4855        let modeline_settings = buffer.modeline().map(Arc::as_ref);
 4856
 4857        let available_language = if let Some(ModelineSettings {
 4858            mode: Some(mode_name),
 4859            ..
 4860        }) = modeline_settings
 4861        {
 4862            self.languages
 4863                .available_language_for_modeline_name(mode_name)
 4864        } else {
 4865            self.languages.language_for_file(file, Some(content), cx)
 4866        };
 4867        if let Some(available_language) = &available_language {
 4868            if let Some(Ok(Ok(new_language))) = self
 4869                .languages
 4870                .load_language(available_language)
 4871                .now_or_never()
 4872            {
 4873                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4874            }
 4875        } else {
 4876            cx.emit(LspStoreEvent::LanguageDetected {
 4877                buffer: buffer_handle.clone(),
 4878                new_language: None,
 4879            });
 4880        }
 4881
 4882        available_language
 4883    }
 4884
 4885    pub(crate) fn set_language_for_buffer(
 4886        &mut self,
 4887        buffer_entity: &Entity<Buffer>,
 4888        new_language: Arc<Language>,
 4889        cx: &mut Context<Self>,
 4890    ) {
 4891        let buffer = buffer_entity.read(cx);
 4892        let buffer_file = buffer.file().cloned();
 4893        let buffer_id = buffer.remote_id();
 4894        if let Some(local_store) = self.as_local_mut()
 4895            && local_store.registered_buffers.contains_key(&buffer_id)
 4896            && let Some(abs_path) =
 4897                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4898            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4899        {
 4900            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4901        }
 4902        buffer_entity.update(cx, |buffer, cx| {
 4903            if buffer
 4904                .language()
 4905                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4906            {
 4907                buffer.set_language_async(Some(new_language.clone()), cx);
 4908            }
 4909        });
 4910
 4911        let settings = LanguageSettings::resolve(
 4912            Some(&buffer_entity.read(cx)),
 4913            Some(&new_language.name()),
 4914            cx,
 4915        )
 4916        .into_owned();
 4917        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4918
 4919        let worktree_id = if let Some(file) = buffer_file {
 4920            let worktree = file.worktree.clone();
 4921
 4922            if let Some(local) = self.as_local_mut()
 4923                && local.registered_buffers.contains_key(&buffer_id)
 4924            {
 4925                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4926            }
 4927            Some(worktree.read(cx).id())
 4928        } else {
 4929            None
 4930        };
 4931
 4932        if settings.prettier.allowed
 4933            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4934        {
 4935            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4936            if let Some(prettier_store) = prettier_store {
 4937                prettier_store.update(cx, |prettier_store, cx| {
 4938                    prettier_store.install_default_prettier(
 4939                        worktree_id,
 4940                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4941                        cx,
 4942                    )
 4943                })
 4944            }
 4945        }
 4946
 4947        cx.emit(LspStoreEvent::LanguageDetected {
 4948            buffer: buffer_entity.clone(),
 4949            new_language: Some(new_language),
 4950        })
 4951    }
 4952
 4953    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4954        self.buffer_store.clone()
 4955    }
 4956
 4957    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4958        self.active_entry = active_entry;
 4959    }
 4960
 4961    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4962        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4963            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4964        {
 4965            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4966                summaries
 4967                    .iter()
 4968                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4969            });
 4970            if let Some(summary) = summaries.next() {
 4971                client
 4972                    .send(proto::UpdateDiagnosticSummary {
 4973                        project_id: downstream_project_id,
 4974                        worktree_id: worktree.id().to_proto(),
 4975                        summary: Some(summary),
 4976                        more_summaries: summaries.collect(),
 4977                    })
 4978                    .log_err();
 4979            }
 4980        }
 4981    }
 4982
 4983    fn is_capable_for_proto_request<R>(
 4984        &self,
 4985        buffer: &Entity<Buffer>,
 4986        request: &R,
 4987        cx: &App,
 4988    ) -> bool
 4989    where
 4990        R: LspCommand,
 4991    {
 4992        self.check_if_capable_for_proto_request(
 4993            buffer,
 4994            |capabilities| {
 4995                request.check_capabilities(AdapterServerCapabilities {
 4996                    server_capabilities: capabilities.clone(),
 4997                    code_action_kinds: None,
 4998                })
 4999            },
 5000            cx,
 5001        )
 5002    }
 5003
 5004    fn check_if_capable_for_proto_request<F>(
 5005        &self,
 5006        buffer: &Entity<Buffer>,
 5007        check: F,
 5008        cx: &App,
 5009    ) -> bool
 5010    where
 5011        F: FnMut(&lsp::ServerCapabilities) -> bool,
 5012    {
 5013        let Some(language) = buffer.read(cx).language().cloned() else {
 5014            return false;
 5015        };
 5016        let registered_language_servers = self
 5017            .languages
 5018            .lsp_adapters(&language.name())
 5019            .into_iter()
 5020            .map(|lsp_adapter| lsp_adapter.name())
 5021            .collect::<HashSet<_>>();
 5022        self.language_server_statuses
 5023            .iter()
 5024            .filter_map(|(server_id, server_status)| {
 5025                // Include servers that are either registered for this language OR
 5026                // available to be loaded (for SSH remote mode where adapters like
 5027                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 5028                // but only loaded on the server side)
 5029                let is_relevant = registered_language_servers.contains(&server_status.name)
 5030                    || self.languages.is_lsp_adapter_available(&server_status.name);
 5031                is_relevant.then_some(server_id)
 5032            })
 5033            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 5034            .any(check)
 5035    }
 5036
 5037    fn all_capable_for_proto_request<F>(
 5038        &self,
 5039        buffer: &Entity<Buffer>,
 5040        mut check: F,
 5041        cx: &App,
 5042    ) -> Vec<(lsp::LanguageServerId, lsp::LanguageServerName)>
 5043    where
 5044        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 5045    {
 5046        let Some(language) = buffer.read(cx).language().cloned() else {
 5047            return Vec::default();
 5048        };
 5049        let registered_language_servers = self
 5050            .languages
 5051            .lsp_adapters(&language.name())
 5052            .into_iter()
 5053            .map(|lsp_adapter| lsp_adapter.name())
 5054            .collect::<HashSet<_>>();
 5055        self.language_server_statuses
 5056            .iter()
 5057            .filter_map(|(server_id, server_status)| {
 5058                // Include servers that are either registered for this language OR
 5059                // available to be loaded (for SSH remote mode where adapters like
 5060                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 5061                // but only loaded on the server side)
 5062                let is_relevant = registered_language_servers.contains(&server_status.name)
 5063                    || self.languages.is_lsp_adapter_available(&server_status.name);
 5064                is_relevant.then_some((server_id, &server_status.name))
 5065            })
 5066            .filter_map(|(server_id, server_name)| {
 5067                self.lsp_server_capabilities
 5068                    .get(server_id)
 5069                    .map(|c| (server_id, server_name, c))
 5070            })
 5071            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 5072            .map(|(server_id, server_name, _)| (*server_id, server_name.clone()))
 5073            .collect()
 5074    }
 5075
 5076    pub fn request_lsp<R>(
 5077        &mut self,
 5078        buffer: Entity<Buffer>,
 5079        server: LanguageServerToQuery,
 5080        request: R,
 5081        cx: &mut Context<Self>,
 5082    ) -> Task<Result<R::Response>>
 5083    where
 5084        R: LspCommand,
 5085        <R::LspRequest as lsp::request::Request>::Result: Send,
 5086        <R::LspRequest as lsp::request::Request>::Params: Send,
 5087    {
 5088        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 5089            return self.send_lsp_proto_request(
 5090                buffer,
 5091                upstream_client,
 5092                upstream_project_id,
 5093                request,
 5094                cx,
 5095            );
 5096        }
 5097
 5098        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 5099            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 5100                local
 5101                    .language_servers_for_buffer(buffer, cx)
 5102                    .find(|(_, server)| {
 5103                        request.check_capabilities(server.adapter_server_capabilities())
 5104                    })
 5105                    .map(|(_, server)| server.clone())
 5106            }),
 5107            LanguageServerToQuery::Other(id) => self
 5108                .language_server_for_local_buffer(buffer, id, cx)
 5109                .and_then(|(_, server)| {
 5110                    request
 5111                        .check_capabilities(server.adapter_server_capabilities())
 5112                        .then(|| Arc::clone(server))
 5113                }),
 5114        }) else {
 5115            return Task::ready(Ok(Default::default()));
 5116        };
 5117
 5118        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 5119
 5120        let Some(file) = file else {
 5121            return Task::ready(Ok(Default::default()));
 5122        };
 5123
 5124        let lsp_params = match request.to_lsp_params_or_response(
 5125            &file.abs_path(cx),
 5126            buffer.read(cx),
 5127            &language_server,
 5128            cx,
 5129        ) {
 5130            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 5131            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 5132            Err(err) => {
 5133                let message = format!(
 5134                    "{} via {} failed: {}",
 5135                    request.display_name(),
 5136                    language_server.name(),
 5137                    err
 5138                );
 5139                // rust-analyzer likes to error with this when its still loading up
 5140                if !message.ends_with("content modified") {
 5141                    log::warn!("{message}");
 5142                }
 5143                return Task::ready(Err(anyhow!(message)));
 5144            }
 5145        };
 5146
 5147        let status = request.status();
 5148        let request_timeout = ProjectSettings::get_global(cx)
 5149            .global_lsp_settings
 5150            .get_request_timeout();
 5151
 5152        cx.spawn(async move |this, cx| {
 5153            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5154
 5155            let id = lsp_request.id();
 5156            let _cleanup = if status.is_some() {
 5157                cx.update(|cx| {
 5158                    this.update(cx, |this, cx| {
 5159                        this.on_lsp_work_start(
 5160                            language_server.server_id(),
 5161                            ProgressToken::Number(id),
 5162                            LanguageServerProgress {
 5163                                is_disk_based_diagnostics_progress: false,
 5164                                is_cancellable: false,
 5165                                title: None,
 5166                                message: status.clone(),
 5167                                percentage: None,
 5168                                last_update_at: cx.background_executor().now(),
 5169                            },
 5170                            cx,
 5171                        );
 5172                    })
 5173                })
 5174                .log_err();
 5175
 5176                Some(defer(|| {
 5177                    cx.update(|cx| {
 5178                        this.update(cx, |this, cx| {
 5179                            this.on_lsp_work_end(
 5180                                language_server.server_id(),
 5181                                ProgressToken::Number(id),
 5182                                cx,
 5183                            );
 5184                        })
 5185                    })
 5186                    .log_err();
 5187                }))
 5188            } else {
 5189                None
 5190            };
 5191
 5192            let result = lsp_request.await.into_response();
 5193
 5194            let response = result.map_err(|err| {
 5195                let message = format!(
 5196                    "{} via {} failed: {}",
 5197                    request.display_name(),
 5198                    language_server.name(),
 5199                    err
 5200                );
 5201                // rust-analyzer likes to error with this when its still loading up
 5202                if !message.ends_with("content modified") {
 5203                    log::warn!("{message}");
 5204                }
 5205                anyhow::anyhow!(message)
 5206            })?;
 5207
 5208            request
 5209                .response_from_lsp(
 5210                    response,
 5211                    this.upgrade().context("no app context")?,
 5212                    buffer,
 5213                    language_server.server_id(),
 5214                    cx.clone(),
 5215                )
 5216                .await
 5217        })
 5218    }
 5219
 5220    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5221        let mut language_formatters_to_check = Vec::new();
 5222        for buffer in self.buffer_store.read(cx).buffers() {
 5223            let buffer = buffer.read(cx);
 5224            let settings = LanguageSettings::for_buffer(buffer, cx);
 5225            if buffer.language().is_some() {
 5226                let buffer_file = File::from_dyn(buffer.file());
 5227                language_formatters_to_check.push((
 5228                    buffer_file.map(|f| f.worktree_id(cx)),
 5229                    settings.into_owned(),
 5230                ));
 5231            }
 5232        }
 5233
 5234        self.request_workspace_config_refresh();
 5235
 5236        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5237            prettier_store.update(cx, |prettier_store, cx| {
 5238                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5239            })
 5240        }
 5241
 5242        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5243            .global_lsp_settings
 5244            .semantic_token_rules
 5245            .clone();
 5246        self.semantic_token_config
 5247            .update_rules(new_semantic_token_rules);
 5248        // Always clear cached stylizers so that changes to language-specific
 5249        // semantic token rules (e.g. from extension install/uninstall) are
 5250        // picked up. Stylizers are recreated lazily, so this is cheap.
 5251        self.semantic_token_config.clear_stylizers();
 5252
 5253        let new_global_semantic_tokens_mode =
 5254            all_language_settings(None, cx).defaults.semantic_tokens;
 5255        if self
 5256            .semantic_token_config
 5257            .update_global_mode(new_global_semantic_tokens_mode)
 5258        {
 5259            self.restart_all_language_servers(cx);
 5260        }
 5261
 5262        cx.notify();
 5263    }
 5264
 5265    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5266        let buffer_store = self.buffer_store.clone();
 5267        let Some(local) = self.as_local_mut() else {
 5268            return;
 5269        };
 5270        let mut adapters = BTreeMap::default();
 5271        let get_adapter = {
 5272            let languages = local.languages.clone();
 5273            let environment = local.environment.clone();
 5274            let weak = local.weak.clone();
 5275            let worktree_store = local.worktree_store.clone();
 5276            let http_client = local.http_client.clone();
 5277            let fs = local.fs.clone();
 5278            move |worktree_id, cx: &mut App| {
 5279                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5280                Some(LocalLspAdapterDelegate::new(
 5281                    languages.clone(),
 5282                    &environment,
 5283                    weak.clone(),
 5284                    &worktree,
 5285                    http_client.clone(),
 5286                    fs.clone(),
 5287                    cx,
 5288                ))
 5289            }
 5290        };
 5291
 5292        let mut messages_to_report = Vec::new();
 5293        let (new_tree, to_stop) = {
 5294            let mut rebase = local.lsp_tree.rebase();
 5295            let buffers = buffer_store
 5296                .read(cx)
 5297                .buffers()
 5298                .filter_map(|buffer| {
 5299                    let raw_buffer = buffer.read(cx);
 5300                    if !local
 5301                        .registered_buffers
 5302                        .contains_key(&raw_buffer.remote_id())
 5303                    {
 5304                        return None;
 5305                    }
 5306                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5307                    let language = raw_buffer.language().cloned()?;
 5308                    Some((file, language, raw_buffer.remote_id()))
 5309                })
 5310                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5311            for (file, language, buffer_id) in buffers {
 5312                let worktree_id = file.worktree_id(cx);
 5313                let Some(worktree) = local
 5314                    .worktree_store
 5315                    .read(cx)
 5316                    .worktree_for_id(worktree_id, cx)
 5317                else {
 5318                    continue;
 5319                };
 5320
 5321                if let Some((_, apply)) = local.reuse_existing_language_server(
 5322                    rebase.server_tree(),
 5323                    &worktree,
 5324                    &language.name(),
 5325                    cx,
 5326                ) {
 5327                    (apply)(rebase.server_tree());
 5328                } else if let Some(lsp_delegate) = adapters
 5329                    .entry(worktree_id)
 5330                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5331                    .clone()
 5332                {
 5333                    let delegate =
 5334                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5335                    let path = file
 5336                        .path()
 5337                        .parent()
 5338                        .map(Arc::from)
 5339                        .unwrap_or_else(|| file.path().clone());
 5340                    let worktree_path = ProjectPath { worktree_id, path };
 5341                    let abs_path = file.abs_path(cx);
 5342                    let nodes = rebase
 5343                        .walk(
 5344                            worktree_path,
 5345                            language.name(),
 5346                            language.manifest(),
 5347                            delegate.clone(),
 5348                            cx,
 5349                        )
 5350                        .collect::<Vec<_>>();
 5351                    for node in nodes {
 5352                        let server_id = node.server_id_or_init(|disposition| {
 5353                            let path = &disposition.path;
 5354                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5355                            let key = LanguageServerSeed {
 5356                                worktree_id,
 5357                                name: disposition.server_name.clone(),
 5358                                settings: LanguageServerSeedSettings {
 5359                                    binary: disposition.settings.binary.clone(),
 5360                                    initialization_options: disposition
 5361                                        .settings
 5362                                        .initialization_options
 5363                                        .clone(),
 5364                                },
 5365                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5366                                    path.worktree_id,
 5367                                    &path.path,
 5368                                    language.name(),
 5369                                ),
 5370                            };
 5371                            local.language_server_ids.remove(&key);
 5372
 5373                            let server_id = local.get_or_insert_language_server(
 5374                                &worktree,
 5375                                lsp_delegate.clone(),
 5376                                disposition,
 5377                                &language.name(),
 5378                                cx,
 5379                            );
 5380                            if let Some(state) = local.language_servers.get(&server_id)
 5381                                && let Ok(uri) = uri
 5382                            {
 5383                                state.add_workspace_folder(uri);
 5384                            };
 5385                            server_id
 5386                        });
 5387
 5388                        if let Some(language_server_id) = server_id {
 5389                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5390                                language_server_id,
 5391                                name: node.name(),
 5392                                message:
 5393                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5394                                        proto::RegisteredForBuffer {
 5395                                            buffer_abs_path: abs_path
 5396                                                .to_string_lossy()
 5397                                                .into_owned(),
 5398                                            buffer_id: buffer_id.to_proto(),
 5399                                        },
 5400                                    ),
 5401                            });
 5402                        }
 5403                    }
 5404                } else {
 5405                    continue;
 5406                }
 5407            }
 5408            rebase.finish()
 5409        };
 5410        for message in messages_to_report {
 5411            cx.emit(message);
 5412        }
 5413        local.lsp_tree = new_tree;
 5414        for (id, _) in to_stop {
 5415            self.stop_local_language_server(id, cx).detach();
 5416        }
 5417    }
 5418
 5419    pub fn apply_code_action(
 5420        &self,
 5421        buffer_handle: Entity<Buffer>,
 5422        mut action: CodeAction,
 5423        push_to_history: bool,
 5424        cx: &mut Context<Self>,
 5425    ) -> Task<Result<ProjectTransaction>> {
 5426        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5427            let request = proto::ApplyCodeAction {
 5428                project_id,
 5429                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5430                action: Some(Self::serialize_code_action(&action)),
 5431            };
 5432            let buffer_store = self.buffer_store();
 5433            cx.spawn(async move |_, cx| {
 5434                let response = upstream_client
 5435                    .request(request)
 5436                    .await?
 5437                    .transaction
 5438                    .context("missing transaction")?;
 5439
 5440                buffer_store
 5441                    .update(cx, |buffer_store, cx| {
 5442                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5443                    })
 5444                    .await
 5445            })
 5446        } else if self.mode.is_local() {
 5447            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5448                let request_timeout = ProjectSettings::get_global(cx)
 5449                    .global_lsp_settings
 5450                    .get_request_timeout();
 5451                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5452                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5453            }) else {
 5454                return Task::ready(Ok(ProjectTransaction::default()));
 5455            };
 5456
 5457            cx.spawn(async move |this, cx| {
 5458                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5459                    .await
 5460                    .context("resolving a code action")?;
 5461                if let Some(edit) = action.lsp_action.edit()
 5462                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5463                        return LocalLspStore::deserialize_workspace_edit(
 5464                            this.upgrade().context("no app present")?,
 5465                            edit.clone(),
 5466                            push_to_history,
 5467
 5468                            lang_server.clone(),
 5469                            cx,
 5470                        )
 5471                        .await;
 5472                    }
 5473
 5474                let Some(command) = action.lsp_action.command() else {
 5475                    return Ok(ProjectTransaction::default())
 5476                };
 5477
 5478                let server_capabilities = lang_server.capabilities();
 5479                let available_commands = server_capabilities
 5480                    .execute_command_provider
 5481                    .as_ref()
 5482                    .map(|options| options.commands.as_slice())
 5483                    .unwrap_or_default();
 5484
 5485                if !available_commands.contains(&command.command) {
 5486                    log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5487                    return Ok(ProjectTransaction::default())
 5488                }
 5489
 5490                let request_timeout = cx.update(|app|
 5491                    ProjectSettings::get_global(app)
 5492                    .global_lsp_settings
 5493                    .get_request_timeout()
 5494                );
 5495
 5496                this.update(cx, |this, _| {
 5497                    this.as_local_mut()
 5498                        .unwrap()
 5499                        .last_workspace_edits_by_language_server
 5500                        .remove(&lang_server.server_id());
 5501                })?;
 5502
 5503                let _result = lang_server
 5504                    .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5505                        command: command.command.clone(),
 5506                        arguments: command.arguments.clone().unwrap_or_default(),
 5507                        ..lsp::ExecuteCommandParams::default()
 5508                    }, request_timeout)
 5509                    .await.into_response()
 5510                    .context("execute command")?;
 5511
 5512                return this.update(cx, |this, _| {
 5513                    this.as_local_mut()
 5514                        .unwrap()
 5515                        .last_workspace_edits_by_language_server
 5516                        .remove(&lang_server.server_id())
 5517                        .unwrap_or_default()
 5518                });
 5519            })
 5520        } else {
 5521            Task::ready(Err(anyhow!("no upstream client and not local")))
 5522        }
 5523    }
 5524
 5525    pub fn apply_code_action_kind(
 5526        &mut self,
 5527        buffers: HashSet<Entity<Buffer>>,
 5528        kind: CodeActionKind,
 5529        push_to_history: bool,
 5530        cx: &mut Context<Self>,
 5531    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5532        if self.as_local().is_some() {
 5533            cx.spawn(async move |lsp_store, cx| {
 5534                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5535                let result = LocalLspStore::execute_code_action_kind_locally(
 5536                    lsp_store.clone(),
 5537                    buffers,
 5538                    kind,
 5539                    push_to_history,
 5540                    cx,
 5541                )
 5542                .await;
 5543                lsp_store.update(cx, |lsp_store, _| {
 5544                    lsp_store.update_last_formatting_failure(&result);
 5545                })?;
 5546                result
 5547            })
 5548        } else if let Some((client, project_id)) = self.upstream_client() {
 5549            let buffer_store = self.buffer_store();
 5550            cx.spawn(async move |lsp_store, cx| {
 5551                let result = client
 5552                    .request(proto::ApplyCodeActionKind {
 5553                        project_id,
 5554                        kind: kind.as_str().to_owned(),
 5555                        buffer_ids: buffers
 5556                            .iter()
 5557                            .map(|buffer| {
 5558                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5559                            })
 5560                            .collect(),
 5561                    })
 5562                    .await
 5563                    .and_then(|result| result.transaction.context("missing transaction"));
 5564                lsp_store.update(cx, |lsp_store, _| {
 5565                    lsp_store.update_last_formatting_failure(&result);
 5566                })?;
 5567
 5568                let transaction_response = result?;
 5569                buffer_store
 5570                    .update(cx, |buffer_store, cx| {
 5571                        buffer_store.deserialize_project_transaction(
 5572                            transaction_response,
 5573                            push_to_history,
 5574                            cx,
 5575                        )
 5576                    })
 5577                    .await
 5578            })
 5579        } else {
 5580            Task::ready(Ok(ProjectTransaction::default()))
 5581        }
 5582    }
 5583
 5584    pub fn resolved_hint(
 5585        &mut self,
 5586        buffer_id: BufferId,
 5587        id: InlayId,
 5588        cx: &mut Context<Self>,
 5589    ) -> Option<ResolvedHint> {
 5590        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5591
 5592        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5593        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5594        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5595        let (server_id, resolve_data) = match &hint.resolve_state {
 5596            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5597            ResolveState::Resolving => {
 5598                return Some(ResolvedHint::Resolving(
 5599                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5600                ));
 5601            }
 5602            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5603        };
 5604
 5605        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5606        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5607        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5608            id,
 5609            cx.spawn(async move |lsp_store, cx| {
 5610                let resolved_hint = resolve_task.await;
 5611                lsp_store
 5612                    .update(cx, |lsp_store, _| {
 5613                        if let Some(old_inlay_hint) = lsp_store
 5614                            .lsp_data
 5615                            .get_mut(&buffer_id)
 5616                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5617                        {
 5618                            match resolved_hint {
 5619                                Ok(resolved_hint) => {
 5620                                    *old_inlay_hint = resolved_hint;
 5621                                }
 5622                                Err(e) => {
 5623                                    old_inlay_hint.resolve_state =
 5624                                        ResolveState::CanResolve(server_id, resolve_data);
 5625                                    log::error!("Inlay hint resolve failed: {e:#}");
 5626                                }
 5627                            }
 5628                        }
 5629                    })
 5630                    .ok();
 5631            })
 5632            .shared(),
 5633        );
 5634        debug_assert!(
 5635            previous_task.is_none(),
 5636            "Did not change hint's resolve state after spawning its resolve"
 5637        );
 5638        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5639        None
 5640    }
 5641
 5642    pub(crate) fn linked_edits(
 5643        &mut self,
 5644        buffer: &Entity<Buffer>,
 5645        position: Anchor,
 5646        cx: &mut Context<Self>,
 5647    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5648        let snapshot = buffer.read(cx).snapshot();
 5649        let scope = snapshot.language_scope_at(position);
 5650        let Some(server_id) = self
 5651            .as_local()
 5652            .and_then(|local| {
 5653                buffer.update(cx, |buffer, cx| {
 5654                    local
 5655                        .language_servers_for_buffer(buffer, cx)
 5656                        .filter(|(_, server)| {
 5657                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5658                        })
 5659                        .filter(|(adapter, _)| {
 5660                            scope
 5661                                .as_ref()
 5662                                .map(|scope| scope.language_allowed(&adapter.name))
 5663                                .unwrap_or(true)
 5664                        })
 5665                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5666                        .next()
 5667                })
 5668            })
 5669            .or_else(|| {
 5670                self.upstream_client()
 5671                    .is_some()
 5672                    .then_some(LanguageServerToQuery::FirstCapable)
 5673            })
 5674            .filter(|_| {
 5675                maybe!({
 5676                    buffer.read(cx).language_at(position)?;
 5677                    Some(
 5678                        LanguageSettings::for_buffer_at(&buffer.read(cx), position, cx)
 5679                            .linked_edits,
 5680                    )
 5681                }) == Some(true)
 5682            })
 5683        else {
 5684            return Task::ready(Ok(Vec::new()));
 5685        };
 5686
 5687        self.request_lsp(
 5688            buffer.clone(),
 5689            server_id,
 5690            LinkedEditingRange { position },
 5691            cx,
 5692        )
 5693    }
 5694
 5695    fn apply_on_type_formatting(
 5696        &mut self,
 5697        buffer: Entity<Buffer>,
 5698        position: Anchor,
 5699        trigger: String,
 5700        cx: &mut Context<Self>,
 5701    ) -> Task<Result<Option<Transaction>>> {
 5702        if let Some((client, project_id)) = self.upstream_client() {
 5703            if !self.check_if_capable_for_proto_request(
 5704                &buffer,
 5705                |capabilities| {
 5706                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5707                },
 5708                cx,
 5709            ) {
 5710                return Task::ready(Ok(None));
 5711            }
 5712            let request = proto::OnTypeFormatting {
 5713                project_id,
 5714                buffer_id: buffer.read(cx).remote_id().into(),
 5715                position: Some(serialize_anchor(&position)),
 5716                trigger,
 5717                version: serialize_version(&buffer.read(cx).version()),
 5718            };
 5719            cx.background_spawn(async move {
 5720                client
 5721                    .request(request)
 5722                    .await?
 5723                    .transaction
 5724                    .map(language::proto::deserialize_transaction)
 5725                    .transpose()
 5726            })
 5727        } else if let Some(local) = self.as_local_mut() {
 5728            let buffer_id = buffer.read(cx).remote_id();
 5729            local.buffers_being_formatted.insert(buffer_id);
 5730            cx.spawn(async move |this, cx| {
 5731                let _cleanup = defer({
 5732                    let this = this.clone();
 5733                    let mut cx = cx.clone();
 5734                    move || {
 5735                        this.update(&mut cx, |this, _| {
 5736                            if let Some(local) = this.as_local_mut() {
 5737                                local.buffers_being_formatted.remove(&buffer_id);
 5738                            }
 5739                        })
 5740                        .ok();
 5741                    }
 5742                });
 5743
 5744                buffer
 5745                    .update(cx, |buffer, _| {
 5746                        buffer.wait_for_edits(Some(position.timestamp()))
 5747                    })
 5748                    .await?;
 5749                this.update(cx, |this, cx| {
 5750                    let position = position.to_point_utf16(buffer.read(cx));
 5751                    this.on_type_format(buffer, position, trigger, false, cx)
 5752                })?
 5753                .await
 5754            })
 5755        } else {
 5756            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5757        }
 5758    }
 5759
 5760    pub fn on_type_format<T: ToPointUtf16>(
 5761        &mut self,
 5762        buffer: Entity<Buffer>,
 5763        position: T,
 5764        trigger: String,
 5765        push_to_history: bool,
 5766        cx: &mut Context<Self>,
 5767    ) -> Task<Result<Option<Transaction>>> {
 5768        let position = position.to_point_utf16(buffer.read(cx));
 5769        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5770    }
 5771
 5772    fn on_type_format_impl(
 5773        &mut self,
 5774        buffer: Entity<Buffer>,
 5775        position: PointUtf16,
 5776        trigger: String,
 5777        push_to_history: bool,
 5778        cx: &mut Context<Self>,
 5779    ) -> Task<Result<Option<Transaction>>> {
 5780        let options = buffer.update(cx, |buffer, cx| {
 5781            lsp_command::lsp_formatting_options(
 5782                LanguageSettings::for_buffer_at(buffer, position, cx).as_ref(),
 5783            )
 5784        });
 5785
 5786        cx.spawn(async move |this, cx| {
 5787            if let Some(waiter) =
 5788                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5789            {
 5790                waiter.await?;
 5791            }
 5792            cx.update(|cx| {
 5793                this.update(cx, |this, cx| {
 5794                    this.request_lsp(
 5795                        buffer.clone(),
 5796                        LanguageServerToQuery::FirstCapable,
 5797                        OnTypeFormatting {
 5798                            position,
 5799                            trigger,
 5800                            options,
 5801                            push_to_history,
 5802                        },
 5803                        cx,
 5804                    )
 5805                })
 5806            })?
 5807            .await
 5808        })
 5809    }
 5810
 5811    pub fn definitions(
 5812        &mut self,
 5813        buffer: &Entity<Buffer>,
 5814        position: PointUtf16,
 5815        cx: &mut Context<Self>,
 5816    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5817        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5818            let request = GetDefinitions { position };
 5819            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5820                return Task::ready(Ok(None));
 5821            }
 5822
 5823            let request_timeout = ProjectSettings::get_global(cx)
 5824                .global_lsp_settings
 5825                .get_request_timeout();
 5826
 5827            let request_task = upstream_client.request_lsp(
 5828                project_id,
 5829                None,
 5830                request_timeout,
 5831                cx.background_executor().clone(),
 5832                request.to_proto(project_id, buffer.read(cx)),
 5833            );
 5834            let buffer = buffer.clone();
 5835            cx.spawn(async move |weak_lsp_store, cx| {
 5836                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5837                    return Ok(None);
 5838                };
 5839                let Some(responses) = request_task.await? else {
 5840                    return Ok(None);
 5841                };
 5842                let actions = join_all(responses.payload.into_iter().map(|response| {
 5843                    GetDefinitions { position }.response_from_proto(
 5844                        response.response,
 5845                        lsp_store.clone(),
 5846                        buffer.clone(),
 5847                        cx.clone(),
 5848                    )
 5849                }))
 5850                .await;
 5851
 5852                Ok(Some(
 5853                    actions
 5854                        .into_iter()
 5855                        .collect::<Result<Vec<Vec<_>>>>()?
 5856                        .into_iter()
 5857                        .flatten()
 5858                        .dedup()
 5859                        .collect(),
 5860                ))
 5861            })
 5862        } else {
 5863            let definitions_task = self.request_multiple_lsp_locally(
 5864                buffer,
 5865                Some(position),
 5866                GetDefinitions { position },
 5867                cx,
 5868            );
 5869            cx.background_spawn(async move {
 5870                Ok(Some(
 5871                    definitions_task
 5872                        .await
 5873                        .into_iter()
 5874                        .flat_map(|(_, definitions)| definitions)
 5875                        .dedup()
 5876                        .collect(),
 5877                ))
 5878            })
 5879        }
 5880    }
 5881
 5882    pub fn declarations(
 5883        &mut self,
 5884        buffer: &Entity<Buffer>,
 5885        position: PointUtf16,
 5886        cx: &mut Context<Self>,
 5887    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5888        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5889            let request = GetDeclarations { position };
 5890            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5891                return Task::ready(Ok(None));
 5892            }
 5893            let request_timeout = ProjectSettings::get_global(cx)
 5894                .global_lsp_settings
 5895                .get_request_timeout();
 5896            let request_task = upstream_client.request_lsp(
 5897                project_id,
 5898                None,
 5899                request_timeout,
 5900                cx.background_executor().clone(),
 5901                request.to_proto(project_id, buffer.read(cx)),
 5902            );
 5903            let buffer = buffer.clone();
 5904            cx.spawn(async move |weak_lsp_store, cx| {
 5905                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5906                    return Ok(None);
 5907                };
 5908                let Some(responses) = request_task.await? else {
 5909                    return Ok(None);
 5910                };
 5911                let actions = join_all(responses.payload.into_iter().map(|response| {
 5912                    GetDeclarations { position }.response_from_proto(
 5913                        response.response,
 5914                        lsp_store.clone(),
 5915                        buffer.clone(),
 5916                        cx.clone(),
 5917                    )
 5918                }))
 5919                .await;
 5920
 5921                Ok(Some(
 5922                    actions
 5923                        .into_iter()
 5924                        .collect::<Result<Vec<Vec<_>>>>()?
 5925                        .into_iter()
 5926                        .flatten()
 5927                        .dedup()
 5928                        .collect(),
 5929                ))
 5930            })
 5931        } else {
 5932            let declarations_task = self.request_multiple_lsp_locally(
 5933                buffer,
 5934                Some(position),
 5935                GetDeclarations { position },
 5936                cx,
 5937            );
 5938            cx.background_spawn(async move {
 5939                Ok(Some(
 5940                    declarations_task
 5941                        .await
 5942                        .into_iter()
 5943                        .flat_map(|(_, declarations)| declarations)
 5944                        .dedup()
 5945                        .collect(),
 5946                ))
 5947            })
 5948        }
 5949    }
 5950
 5951    pub fn type_definitions(
 5952        &mut self,
 5953        buffer: &Entity<Buffer>,
 5954        position: PointUtf16,
 5955        cx: &mut Context<Self>,
 5956    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5957        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5958            let request = GetTypeDefinitions { position };
 5959            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5960                return Task::ready(Ok(None));
 5961            }
 5962            let request_timeout = ProjectSettings::get_global(cx)
 5963                .global_lsp_settings
 5964                .get_request_timeout();
 5965            let request_task = upstream_client.request_lsp(
 5966                project_id,
 5967                None,
 5968                request_timeout,
 5969                cx.background_executor().clone(),
 5970                request.to_proto(project_id, buffer.read(cx)),
 5971            );
 5972            let buffer = buffer.clone();
 5973            cx.spawn(async move |weak_lsp_store, cx| {
 5974                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5975                    return Ok(None);
 5976                };
 5977                let Some(responses) = request_task.await? else {
 5978                    return Ok(None);
 5979                };
 5980                let actions = join_all(responses.payload.into_iter().map(|response| {
 5981                    GetTypeDefinitions { position }.response_from_proto(
 5982                        response.response,
 5983                        lsp_store.clone(),
 5984                        buffer.clone(),
 5985                        cx.clone(),
 5986                    )
 5987                }))
 5988                .await;
 5989
 5990                Ok(Some(
 5991                    actions
 5992                        .into_iter()
 5993                        .collect::<Result<Vec<Vec<_>>>>()?
 5994                        .into_iter()
 5995                        .flatten()
 5996                        .dedup()
 5997                        .collect(),
 5998                ))
 5999            })
 6000        } else {
 6001            let type_definitions_task = self.request_multiple_lsp_locally(
 6002                buffer,
 6003                Some(position),
 6004                GetTypeDefinitions { position },
 6005                cx,
 6006            );
 6007            cx.background_spawn(async move {
 6008                Ok(Some(
 6009                    type_definitions_task
 6010                        .await
 6011                        .into_iter()
 6012                        .flat_map(|(_, type_definitions)| type_definitions)
 6013                        .dedup()
 6014                        .collect(),
 6015                ))
 6016            })
 6017        }
 6018    }
 6019
 6020    pub fn implementations(
 6021        &mut self,
 6022        buffer: &Entity<Buffer>,
 6023        position: PointUtf16,
 6024        cx: &mut Context<Self>,
 6025    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 6026        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6027            let request = GetImplementations { position };
 6028            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6029                return Task::ready(Ok(None));
 6030            }
 6031
 6032            let request_timeout = ProjectSettings::get_global(cx)
 6033                .global_lsp_settings
 6034                .get_request_timeout();
 6035            let request_task = upstream_client.request_lsp(
 6036                project_id,
 6037                None,
 6038                request_timeout,
 6039                cx.background_executor().clone(),
 6040                request.to_proto(project_id, buffer.read(cx)),
 6041            );
 6042            let buffer = buffer.clone();
 6043            cx.spawn(async move |weak_lsp_store, cx| {
 6044                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6045                    return Ok(None);
 6046                };
 6047                let Some(responses) = request_task.await? else {
 6048                    return Ok(None);
 6049                };
 6050                let actions = join_all(responses.payload.into_iter().map(|response| {
 6051                    GetImplementations { position }.response_from_proto(
 6052                        response.response,
 6053                        lsp_store.clone(),
 6054                        buffer.clone(),
 6055                        cx.clone(),
 6056                    )
 6057                }))
 6058                .await;
 6059
 6060                Ok(Some(
 6061                    actions
 6062                        .into_iter()
 6063                        .collect::<Result<Vec<Vec<_>>>>()?
 6064                        .into_iter()
 6065                        .flatten()
 6066                        .dedup()
 6067                        .collect(),
 6068                ))
 6069            })
 6070        } else {
 6071            let implementations_task = self.request_multiple_lsp_locally(
 6072                buffer,
 6073                Some(position),
 6074                GetImplementations { position },
 6075                cx,
 6076            );
 6077            cx.background_spawn(async move {
 6078                Ok(Some(
 6079                    implementations_task
 6080                        .await
 6081                        .into_iter()
 6082                        .flat_map(|(_, implementations)| implementations)
 6083                        .dedup()
 6084                        .collect(),
 6085                ))
 6086            })
 6087        }
 6088    }
 6089
 6090    pub fn references(
 6091        &mut self,
 6092        buffer: &Entity<Buffer>,
 6093        position: PointUtf16,
 6094        cx: &mut Context<Self>,
 6095    ) -> Task<Result<Option<Vec<Location>>>> {
 6096        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6097            let request = GetReferences { position };
 6098            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6099                return Task::ready(Ok(None));
 6100            }
 6101
 6102            let request_timeout = ProjectSettings::get_global(cx)
 6103                .global_lsp_settings
 6104                .get_request_timeout();
 6105            let request_task = upstream_client.request_lsp(
 6106                project_id,
 6107                None,
 6108                request_timeout,
 6109                cx.background_executor().clone(),
 6110                request.to_proto(project_id, buffer.read(cx)),
 6111            );
 6112            let buffer = buffer.clone();
 6113            cx.spawn(async move |weak_lsp_store, cx| {
 6114                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6115                    return Ok(None);
 6116                };
 6117                let Some(responses) = request_task.await? else {
 6118                    return Ok(None);
 6119                };
 6120
 6121                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 6122                    GetReferences { position }.response_from_proto(
 6123                        lsp_response.response,
 6124                        lsp_store.clone(),
 6125                        buffer.clone(),
 6126                        cx.clone(),
 6127                    )
 6128                }))
 6129                .await
 6130                .into_iter()
 6131                .collect::<Result<Vec<Vec<_>>>>()?
 6132                .into_iter()
 6133                .flatten()
 6134                .dedup()
 6135                .collect();
 6136                Ok(Some(locations))
 6137            })
 6138        } else {
 6139            let references_task = self.request_multiple_lsp_locally(
 6140                buffer,
 6141                Some(position),
 6142                GetReferences { position },
 6143                cx,
 6144            );
 6145            cx.background_spawn(async move {
 6146                Ok(Some(
 6147                    references_task
 6148                        .await
 6149                        .into_iter()
 6150                        .flat_map(|(_, references)| references)
 6151                        .dedup()
 6152                        .collect(),
 6153                ))
 6154            })
 6155        }
 6156    }
 6157
 6158    pub fn code_actions(
 6159        &mut self,
 6160        buffer: &Entity<Buffer>,
 6161        range: Range<Anchor>,
 6162        kinds: Option<Vec<CodeActionKind>>,
 6163        cx: &mut Context<Self>,
 6164    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6165        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6166            let request = GetCodeActions {
 6167                range: range.clone(),
 6168                kinds: kinds.clone(),
 6169            };
 6170            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6171                return Task::ready(Ok(None));
 6172            }
 6173            let request_timeout = ProjectSettings::get_global(cx)
 6174                .global_lsp_settings
 6175                .get_request_timeout();
 6176            let request_task = upstream_client.request_lsp(
 6177                project_id,
 6178                None,
 6179                request_timeout,
 6180                cx.background_executor().clone(),
 6181                request.to_proto(project_id, buffer.read(cx)),
 6182            );
 6183            let buffer = buffer.clone();
 6184            cx.spawn(async move |weak_lsp_store, cx| {
 6185                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6186                    return Ok(None);
 6187                };
 6188                let Some(responses) = request_task.await? else {
 6189                    return Ok(None);
 6190                };
 6191                let actions = join_all(responses.payload.into_iter().map(|response| {
 6192                    GetCodeActions {
 6193                        range: range.clone(),
 6194                        kinds: kinds.clone(),
 6195                    }
 6196                    .response_from_proto(
 6197                        response.response,
 6198                        lsp_store.clone(),
 6199                        buffer.clone(),
 6200                        cx.clone(),
 6201                    )
 6202                }))
 6203                .await;
 6204
 6205                Ok(Some(
 6206                    actions
 6207                        .into_iter()
 6208                        .collect::<Result<Vec<Vec<_>>>>()?
 6209                        .into_iter()
 6210                        .flatten()
 6211                        .collect(),
 6212                ))
 6213            })
 6214        } else {
 6215            let all_actions_task = self.request_multiple_lsp_locally(
 6216                buffer,
 6217                Some(range.start),
 6218                GetCodeActions { range, kinds },
 6219                cx,
 6220            );
 6221            cx.background_spawn(async move {
 6222                Ok(Some(
 6223                    all_actions_task
 6224                        .await
 6225                        .into_iter()
 6226                        .flat_map(|(_, actions)| actions)
 6227                        .collect(),
 6228                ))
 6229            })
 6230        }
 6231    }
 6232
 6233    #[inline(never)]
 6234    pub fn completions(
 6235        &self,
 6236        buffer: &Entity<Buffer>,
 6237        position: PointUtf16,
 6238        context: CompletionContext,
 6239        cx: &mut Context<Self>,
 6240    ) -> Task<Result<Vec<CompletionResponse>>> {
 6241        let language_registry = self.languages.clone();
 6242
 6243        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6244            let snapshot = buffer.read(cx).snapshot();
 6245            let offset = position.to_offset(&snapshot);
 6246            let scope = snapshot.language_scope_at(offset);
 6247            let capable_lsps = self.all_capable_for_proto_request(
 6248                buffer,
 6249                |server_name, capabilities| {
 6250                    capabilities.completion_provider.is_some()
 6251                        && scope
 6252                            .as_ref()
 6253                            .map(|scope| scope.language_allowed(server_name))
 6254                            .unwrap_or(true)
 6255                },
 6256                cx,
 6257            );
 6258            if capable_lsps.is_empty() {
 6259                return Task::ready(Ok(Vec::new()));
 6260            }
 6261
 6262            let language = buffer.read(cx).language().cloned();
 6263
 6264            let buffer = buffer.clone();
 6265
 6266            cx.spawn(async move |this, cx| {
 6267                let requests = join_all(
 6268                    capable_lsps
 6269                        .into_iter()
 6270                        .map(|(id, server_name)| {
 6271                            let request = GetCompletions {
 6272                                position,
 6273                                context: context.clone(),
 6274                                server_id: Some(id),
 6275                            };
 6276                            let buffer = buffer.clone();
 6277                            let language = language.clone();
 6278                            let lsp_adapter = language.as_ref().and_then(|language| {
 6279                                let adapters = language_registry.lsp_adapters(&language.name());
 6280                                adapters
 6281                                    .iter()
 6282                                    .find(|adapter| adapter.name() == server_name)
 6283                                    .or_else(|| adapters.first())
 6284                                    .cloned()
 6285                            });
 6286                            let upstream_client = upstream_client.clone();
 6287                            let response = this
 6288                                .update(cx, |this, cx| {
 6289                                    this.send_lsp_proto_request(
 6290                                        buffer,
 6291                                        upstream_client,
 6292                                        project_id,
 6293                                        request,
 6294                                        cx,
 6295                                    )
 6296                                })
 6297                                .log_err();
 6298                            async move {
 6299                                let response = response?.await.log_err()?;
 6300
 6301                                let completions = populate_labels_for_completions(
 6302                                    response.completions,
 6303                                    language,
 6304                                    lsp_adapter,
 6305                                )
 6306                                .await;
 6307
 6308                                Some(CompletionResponse {
 6309                                    completions,
 6310                                    display_options: CompletionDisplayOptions::default(),
 6311                                    is_incomplete: response.is_incomplete,
 6312                                })
 6313                            }
 6314                        })
 6315                        .collect::<Vec<_>>(),
 6316                );
 6317                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6318            })
 6319        } else if let Some(local) = self.as_local() {
 6320            let snapshot = buffer.read(cx).snapshot();
 6321            let offset = position.to_offset(&snapshot);
 6322            let scope = snapshot.language_scope_at(offset);
 6323            let language = snapshot.language().cloned();
 6324            let completion_settings = LanguageSettings::for_buffer(&buffer.read(cx), cx)
 6325                .completions
 6326                .clone();
 6327            if !completion_settings.lsp {
 6328                return Task::ready(Ok(Vec::new()));
 6329            }
 6330
 6331            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6332                local
 6333                    .language_servers_for_buffer(buffer, cx)
 6334                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6335                    .filter(|(adapter, _)| {
 6336                        scope
 6337                            .as_ref()
 6338                            .map(|scope| scope.language_allowed(&adapter.name))
 6339                            .unwrap_or(true)
 6340                    })
 6341                    .map(|(_, server)| server.server_id())
 6342                    .collect()
 6343            });
 6344
 6345            let buffer = buffer.clone();
 6346            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6347            let lsp_timeout = if lsp_timeout > 0 {
 6348                Some(Duration::from_millis(lsp_timeout))
 6349            } else {
 6350                None
 6351            };
 6352            cx.spawn(async move |this,  cx| {
 6353                let mut tasks = Vec::with_capacity(server_ids.len());
 6354                this.update(cx, |lsp_store, cx| {
 6355                    for server_id in server_ids {
 6356                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6357                        let lsp_timeout = lsp_timeout
 6358                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6359                        let mut timeout = cx.background_spawn(async move {
 6360                            match lsp_timeout {
 6361                                Some(lsp_timeout) => {
 6362                                    lsp_timeout.await;
 6363                                    true
 6364                                },
 6365                                None => false,
 6366                            }
 6367                        }).fuse();
 6368                        let mut lsp_request = lsp_store.request_lsp(
 6369                            buffer.clone(),
 6370                            LanguageServerToQuery::Other(server_id),
 6371                            GetCompletions {
 6372                                position,
 6373                                context: context.clone(),
 6374                                server_id: Some(server_id),
 6375                            },
 6376                            cx,
 6377                        ).fuse();
 6378                        let new_task = cx.background_spawn(async move {
 6379                            select_biased! {
 6380                                response = lsp_request => anyhow::Ok(Some(response?)),
 6381                                timeout_happened = timeout => {
 6382                                    if timeout_happened {
 6383                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6384                                        Ok(None)
 6385                                    } else {
 6386                                        let completions = lsp_request.await?;
 6387                                        Ok(Some(completions))
 6388                                    }
 6389                                },
 6390                            }
 6391                        });
 6392                        tasks.push((lsp_adapter, new_task));
 6393                    }
 6394                })?;
 6395
 6396                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6397                    let completion_response = task.await.ok()??;
 6398                    let completions = populate_labels_for_completions(
 6399                            completion_response.completions,
 6400                            language.clone(),
 6401                            lsp_adapter,
 6402                        )
 6403                        .await;
 6404                    Some(CompletionResponse {
 6405                        completions,
 6406                        display_options: CompletionDisplayOptions::default(),
 6407                        is_incomplete: completion_response.is_incomplete,
 6408                    })
 6409                });
 6410
 6411                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6412
 6413                Ok(responses.into_iter().flatten().collect())
 6414            })
 6415        } else {
 6416            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6417        }
 6418    }
 6419
 6420    pub fn resolve_completions(
 6421        &self,
 6422        buffer: Entity<Buffer>,
 6423        completion_indices: Vec<usize>,
 6424        completions: Rc<RefCell<Box<[Completion]>>>,
 6425        cx: &mut Context<Self>,
 6426    ) -> Task<Result<bool>> {
 6427        let client = self.upstream_client();
 6428        let buffer_id = buffer.read(cx).remote_id();
 6429        let buffer_snapshot = buffer.read(cx).snapshot();
 6430
 6431        if !self.check_if_capable_for_proto_request(
 6432            &buffer,
 6433            GetCompletions::can_resolve_completions,
 6434            cx,
 6435        ) {
 6436            return Task::ready(Ok(false));
 6437        }
 6438        cx.spawn(async move |lsp_store, cx| {
 6439            let request_timeout = cx.update(|app| {
 6440                ProjectSettings::get_global(app)
 6441                    .global_lsp_settings
 6442                    .get_request_timeout()
 6443            });
 6444
 6445            let mut did_resolve = false;
 6446            if let Some((client, project_id)) = client {
 6447                for completion_index in completion_indices {
 6448                    let server_id = {
 6449                        let completion = &completions.borrow()[completion_index];
 6450                        completion.source.server_id()
 6451                    };
 6452                    if let Some(server_id) = server_id {
 6453                        if Self::resolve_completion_remote(
 6454                            project_id,
 6455                            server_id,
 6456                            buffer_id,
 6457                            completions.clone(),
 6458                            completion_index,
 6459                            client.clone(),
 6460                        )
 6461                        .await
 6462                        .log_err()
 6463                        .is_some()
 6464                        {
 6465                            did_resolve = true;
 6466                        }
 6467                    } else {
 6468                        resolve_word_completion(
 6469                            &buffer_snapshot,
 6470                            &mut completions.borrow_mut()[completion_index],
 6471                        );
 6472                    }
 6473                }
 6474            } else {
 6475                for completion_index in completion_indices {
 6476                    let server_id = {
 6477                        let completion = &completions.borrow()[completion_index];
 6478                        completion.source.server_id()
 6479                    };
 6480                    if let Some(server_id) = server_id {
 6481                        let server_and_adapter = lsp_store
 6482                            .read_with(cx, |lsp_store, _| {
 6483                                let server = lsp_store.language_server_for_id(server_id)?;
 6484                                let adapter =
 6485                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6486                                Some((server, adapter))
 6487                            })
 6488                            .ok()
 6489                            .flatten();
 6490                        let Some((server, adapter)) = server_and_adapter else {
 6491                            continue;
 6492                        };
 6493
 6494                        let resolved = Self::resolve_completion_local(
 6495                            server,
 6496                            completions.clone(),
 6497                            completion_index,
 6498                            request_timeout,
 6499                        )
 6500                        .await
 6501                        .log_err()
 6502                        .is_some();
 6503                        if resolved {
 6504                            Self::regenerate_completion_labels(
 6505                                adapter,
 6506                                &buffer_snapshot,
 6507                                completions.clone(),
 6508                                completion_index,
 6509                            )
 6510                            .await
 6511                            .log_err();
 6512                            did_resolve = true;
 6513                        }
 6514                    } else {
 6515                        resolve_word_completion(
 6516                            &buffer_snapshot,
 6517                            &mut completions.borrow_mut()[completion_index],
 6518                        );
 6519                    }
 6520                }
 6521            }
 6522
 6523            Ok(did_resolve)
 6524        })
 6525    }
 6526
 6527    async fn resolve_completion_local(
 6528        server: Arc<lsp::LanguageServer>,
 6529        completions: Rc<RefCell<Box<[Completion]>>>,
 6530        completion_index: usize,
 6531        request_timeout: Duration,
 6532    ) -> Result<()> {
 6533        let server_id = server.server_id();
 6534        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6535            return Ok(());
 6536        }
 6537
 6538        let request = {
 6539            let completion = &completions.borrow()[completion_index];
 6540            match &completion.source {
 6541                CompletionSource::Lsp {
 6542                    lsp_completion,
 6543                    resolved,
 6544                    server_id: completion_server_id,
 6545                    ..
 6546                } => {
 6547                    if *resolved {
 6548                        return Ok(());
 6549                    }
 6550                    anyhow::ensure!(
 6551                        server_id == *completion_server_id,
 6552                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6553                    );
 6554                    server.request::<lsp::request::ResolveCompletionItem>(
 6555                        *lsp_completion.clone(),
 6556                        request_timeout,
 6557                    )
 6558                }
 6559                CompletionSource::BufferWord { .. }
 6560                | CompletionSource::Dap { .. }
 6561                | CompletionSource::Custom => {
 6562                    return Ok(());
 6563                }
 6564            }
 6565        };
 6566        let resolved_completion = request
 6567            .await
 6568            .into_response()
 6569            .context("resolve completion")?;
 6570
 6571        let mut completions = completions.borrow_mut();
 6572        let completion = &mut completions[completion_index];
 6573        if let CompletionSource::Lsp {
 6574            lsp_completion,
 6575            resolved,
 6576            server_id: completion_server_id,
 6577            ..
 6578        } = &mut completion.source
 6579        {
 6580            if *resolved {
 6581                return Ok(());
 6582            }
 6583            anyhow::ensure!(
 6584                server_id == *completion_server_id,
 6585                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6586            );
 6587            **lsp_completion = resolved_completion;
 6588            *resolved = true;
 6589
 6590            // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not supposed to change during resolve.
 6591            // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6592            //
 6593            // We still re-derive new_text here as a workaround for the specific
 6594            // VS Code TypeScript completion resolve flow that vtsls wraps:
 6595            // https://github.com/microsoft/vscode/blob/838b48504cd9a2338e2ca9e854da9cec990c4d57/extensions/typescript-language-features/src/languageFeatures/completions.ts#L218
 6596            //
 6597            // Some servers (e.g. vtsls with completeFunctionCalls) update
 6598            // insertText/textEdit during resolve to add snippet content like
 6599            // function call parentheses.
 6600            //
 6601            // vtsls resolve flow:
 6602            //   https://github.com/yioneko/vtsls/blob/fecf52324a30e72dfab1537047556076720c1a5f/packages/service/src/service/completion.ts#L228-L244
 6603            // vtsls converter (isSnippet / insertTextFormat):
 6604            //   https://github.com/yioneko/vtsls/blob/28e075105d7711d635ebf8aefc971bb8e1d2fe65/packages/service/src/utils/converter.ts#L149-L200
 6605            //
 6606            // NB: We only update the text content here, NOT the replace/insert
 6607            // ranges on `Completion`. Those ranges were converted to anchors from
 6608            // the original response and stay valid across buffer edits. The LSP
 6609            // ranges in the resolved text_edit are stale when completions are
 6610            // cached across keystrokes (see #34094).
 6611            let resolved_new_text = lsp_completion
 6612                .text_edit
 6613                .as_ref()
 6614                .map(|edit| match edit {
 6615                    lsp::CompletionTextEdit::Edit(e) => e.new_text.clone(),
 6616                    lsp::CompletionTextEdit::InsertAndReplace(e) => e.new_text.clone(),
 6617                })
 6618                .or_else(|| lsp_completion.insert_text.clone());
 6619            if let Some(mut resolved_new_text) = resolved_new_text {
 6620                LineEnding::normalize(&mut resolved_new_text);
 6621                completion.new_text = resolved_new_text;
 6622            }
 6623        }
 6624        Ok(())
 6625    }
 6626
 6627    async fn regenerate_completion_labels(
 6628        adapter: Arc<CachedLspAdapter>,
 6629        snapshot: &BufferSnapshot,
 6630        completions: Rc<RefCell<Box<[Completion]>>>,
 6631        completion_index: usize,
 6632    ) -> Result<()> {
 6633        let completion_item = completions.borrow()[completion_index]
 6634            .source
 6635            .lsp_completion(true)
 6636            .map(Cow::into_owned);
 6637        if let Some(lsp_documentation) = completion_item
 6638            .as_ref()
 6639            .and_then(|completion_item| completion_item.documentation.clone())
 6640        {
 6641            let mut completions = completions.borrow_mut();
 6642            let completion = &mut completions[completion_index];
 6643            completion.documentation = Some(lsp_documentation.into());
 6644        } else {
 6645            let mut completions = completions.borrow_mut();
 6646            let completion = &mut completions[completion_index];
 6647            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6648        }
 6649
 6650        let mut new_label = match completion_item {
 6651            Some(completion_item) => {
 6652                // Some language servers always return `detail` lazily via resolve, regardless of
 6653                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6654                // See: https://github.com/yioneko/vtsls/issues/213
 6655                let language = snapshot.language();
 6656                match language {
 6657                    Some(language) => {
 6658                        adapter
 6659                            .labels_for_completions(
 6660                                std::slice::from_ref(&completion_item),
 6661                                language,
 6662                            )
 6663                            .await?
 6664                    }
 6665                    None => Vec::new(),
 6666                }
 6667                .pop()
 6668                .flatten()
 6669                .unwrap_or_else(|| {
 6670                    CodeLabel::fallback_for_completion(
 6671                        &completion_item,
 6672                        language.map(|language| language.as_ref()),
 6673                    )
 6674                })
 6675            }
 6676            None => CodeLabel::plain(
 6677                completions.borrow()[completion_index].new_text.clone(),
 6678                None,
 6679            ),
 6680        };
 6681        ensure_uniform_list_compatible_label(&mut new_label);
 6682
 6683        let mut completions = completions.borrow_mut();
 6684        let completion = &mut completions[completion_index];
 6685        if completion.label.filter_text() == new_label.filter_text() {
 6686            completion.label = new_label;
 6687        } else {
 6688            log::error!(
 6689                "Resolved completion changed display label from {} to {}. \
 6690                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6691                completion.label.text(),
 6692                new_label.text(),
 6693                completion.label.filter_text(),
 6694                new_label.filter_text()
 6695            );
 6696        }
 6697
 6698        Ok(())
 6699    }
 6700
 6701    async fn resolve_completion_remote(
 6702        project_id: u64,
 6703        server_id: LanguageServerId,
 6704        buffer_id: BufferId,
 6705        completions: Rc<RefCell<Box<[Completion]>>>,
 6706        completion_index: usize,
 6707        client: AnyProtoClient,
 6708    ) -> Result<()> {
 6709        let lsp_completion = {
 6710            let completion = &completions.borrow()[completion_index];
 6711            match &completion.source {
 6712                CompletionSource::Lsp {
 6713                    lsp_completion,
 6714                    resolved,
 6715                    server_id: completion_server_id,
 6716                    ..
 6717                } => {
 6718                    anyhow::ensure!(
 6719                        server_id == *completion_server_id,
 6720                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6721                    );
 6722                    if *resolved {
 6723                        return Ok(());
 6724                    }
 6725                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6726                }
 6727                CompletionSource::Custom
 6728                | CompletionSource::Dap { .. }
 6729                | CompletionSource::BufferWord { .. } => {
 6730                    return Ok(());
 6731                }
 6732            }
 6733        };
 6734        let request = proto::ResolveCompletionDocumentation {
 6735            project_id,
 6736            language_server_id: server_id.0 as u64,
 6737            lsp_completion,
 6738            buffer_id: buffer_id.into(),
 6739        };
 6740
 6741        let response = client
 6742            .request(request)
 6743            .await
 6744            .context("completion documentation resolve proto request")?;
 6745        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6746
 6747        let documentation = if response.documentation.is_empty() {
 6748            CompletionDocumentation::Undocumented
 6749        } else if response.documentation_is_markdown {
 6750            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6751        } else if response.documentation.lines().count() <= 1 {
 6752            CompletionDocumentation::SingleLine(response.documentation.into())
 6753        } else {
 6754            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6755        };
 6756
 6757        let mut completions = completions.borrow_mut();
 6758        let completion = &mut completions[completion_index];
 6759        completion.documentation = Some(documentation);
 6760        if let CompletionSource::Lsp {
 6761            insert_range,
 6762            lsp_completion,
 6763            resolved,
 6764            server_id: completion_server_id,
 6765            lsp_defaults: _,
 6766        } = &mut completion.source
 6767        {
 6768            let completion_insert_range = response
 6769                .old_insert_start
 6770                .and_then(deserialize_anchor)
 6771                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6772            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6773
 6774            if *resolved {
 6775                return Ok(());
 6776            }
 6777            anyhow::ensure!(
 6778                server_id == *completion_server_id,
 6779                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6780            );
 6781            **lsp_completion = resolved_lsp_completion;
 6782            *resolved = true;
 6783        }
 6784
 6785        let replace_range = response
 6786            .old_replace_start
 6787            .and_then(deserialize_anchor)
 6788            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6789        if let Some((old_replace_start, old_replace_end)) = replace_range
 6790            && !response.new_text.is_empty()
 6791        {
 6792            completion.new_text = response.new_text;
 6793            completion.replace_range = old_replace_start..old_replace_end;
 6794        }
 6795
 6796        Ok(())
 6797    }
 6798
 6799    pub fn apply_additional_edits_for_completion(
 6800        &self,
 6801        buffer_handle: Entity<Buffer>,
 6802        completions: Rc<RefCell<Box<[Completion]>>>,
 6803        completion_index: usize,
 6804        push_to_history: bool,
 6805        all_commit_ranges: Vec<Range<language::Anchor>>,
 6806        cx: &mut Context<Self>,
 6807    ) -> Task<Result<Option<Transaction>>> {
 6808        if let Some((client, project_id)) = self.upstream_client() {
 6809            let buffer = buffer_handle.read(cx);
 6810            let buffer_id = buffer.remote_id();
 6811            cx.spawn(async move |_, cx| {
 6812                let request = {
 6813                    let completion = completions.borrow()[completion_index].clone();
 6814                    proto::ApplyCompletionAdditionalEdits {
 6815                        project_id,
 6816                        buffer_id: buffer_id.into(),
 6817                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6818                            replace_range: completion.replace_range,
 6819                            new_text: completion.new_text,
 6820                            source: completion.source,
 6821                        })),
 6822                        all_commit_ranges: all_commit_ranges
 6823                            .iter()
 6824                            .cloned()
 6825                            .map(language::proto::serialize_anchor_range)
 6826                            .collect(),
 6827                    }
 6828                };
 6829
 6830                let Some(transaction) = client.request(request).await?.transaction else {
 6831                    return Ok(None);
 6832                };
 6833
 6834                let transaction = language::proto::deserialize_transaction(transaction)?;
 6835                buffer_handle
 6836                    .update(cx, |buffer, _| {
 6837                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6838                    })
 6839                    .await?;
 6840                if push_to_history {
 6841                    buffer_handle.update(cx, |buffer, _| {
 6842                        buffer.push_transaction(transaction.clone(), Instant::now());
 6843                        buffer.finalize_last_transaction();
 6844                    });
 6845                }
 6846                Ok(Some(transaction))
 6847            })
 6848        } else {
 6849            let request_timeout = ProjectSettings::get_global(cx)
 6850                .global_lsp_settings
 6851                .get_request_timeout();
 6852
 6853            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6854                let completion = &completions.borrow()[completion_index];
 6855                let server_id = completion.source.server_id()?;
 6856                Some(
 6857                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6858                        .1
 6859                        .clone(),
 6860                )
 6861            }) else {
 6862                return Task::ready(Ok(None));
 6863            };
 6864
 6865            cx.spawn(async move |this, cx| {
 6866                Self::resolve_completion_local(
 6867                    server.clone(),
 6868                    completions.clone(),
 6869                    completion_index,
 6870                    request_timeout,
 6871                )
 6872                .await
 6873                .context("resolving completion")?;
 6874                let completion = completions.borrow()[completion_index].clone();
 6875                let additional_text_edits = completion
 6876                    .source
 6877                    .lsp_completion(true)
 6878                    .as_ref()
 6879                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6880                if let Some(edits) = additional_text_edits {
 6881                    let edits = this
 6882                        .update(cx, |this, cx| {
 6883                            this.as_local_mut().unwrap().edits_from_lsp(
 6884                                &buffer_handle,
 6885                                edits,
 6886                                server.server_id(),
 6887                                None,
 6888                                cx,
 6889                            )
 6890                        })?
 6891                        .await?;
 6892
 6893                    buffer_handle.update(cx, |buffer, cx| {
 6894                        buffer.finalize_last_transaction();
 6895                        buffer.start_transaction();
 6896
 6897                        for (range, text) in edits {
 6898                            let primary = &completion.replace_range;
 6899
 6900                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6901                            // and the primary completion is just an insertion (empty range), then this is likely
 6902                            // an auto-import scenario and should not be considered overlapping
 6903                            // https://github.com/zed-industries/zed/issues/26136
 6904                            let is_file_start_auto_import = {
 6905                                let snapshot = buffer.snapshot();
 6906                                let primary_start_point = primary.start.to_point(&snapshot);
 6907                                let range_start_point = range.start.to_point(&snapshot);
 6908
 6909                                let result = primary_start_point.row == 0
 6910                                    && primary_start_point.column == 0
 6911                                    && range_start_point.row == 0
 6912                                    && range_start_point.column == 0;
 6913
 6914                                result
 6915                            };
 6916
 6917                            let has_overlap = if is_file_start_auto_import {
 6918                                false
 6919                            } else {
 6920                                all_commit_ranges.iter().any(|commit_range| {
 6921                                    let start_within =
 6922                                        commit_range.start.cmp(&range.start, buffer).is_le()
 6923                                            && commit_range.end.cmp(&range.start, buffer).is_ge();
 6924                                    let end_within =
 6925                                        range.start.cmp(&commit_range.end, buffer).is_le()
 6926                                            && range.end.cmp(&commit_range.end, buffer).is_ge();
 6927                                    start_within || end_within
 6928                                })
 6929                            };
 6930
 6931                            //Skip additional edits which overlap with the primary completion edit
 6932                            //https://github.com/zed-industries/zed/pull/1871
 6933                            if !has_overlap {
 6934                                buffer.edit([(range, text)], None, cx);
 6935                            }
 6936                        }
 6937
 6938                        let transaction = if buffer.end_transaction(cx).is_some() {
 6939                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6940                            if !push_to_history {
 6941                                buffer.forget_transaction(transaction.id);
 6942                            }
 6943                            Some(transaction)
 6944                        } else {
 6945                            None
 6946                        };
 6947                        Ok(transaction)
 6948                    })
 6949                } else {
 6950                    Ok(None)
 6951                }
 6952            })
 6953        }
 6954    }
 6955
 6956    pub fn pull_diagnostics(
 6957        &mut self,
 6958        buffer: Entity<Buffer>,
 6959        cx: &mut Context<Self>,
 6960    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6961        let buffer_id = buffer.read(cx).remote_id();
 6962
 6963        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6964            let mut suitable_capabilities = None;
 6965            // Are we capable for proto request?
 6966            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6967                &buffer,
 6968                |capabilities| {
 6969                    if let Some(caps) = &capabilities.diagnostic_provider {
 6970                        suitable_capabilities = Some(caps.clone());
 6971                        true
 6972                    } else {
 6973                        false
 6974                    }
 6975                },
 6976                cx,
 6977            );
 6978            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6979            let Some(dynamic_caps) = suitable_capabilities else {
 6980                return Task::ready(Ok(None));
 6981            };
 6982            assert!(any_server_has_diagnostics_provider);
 6983
 6984            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6985            let request = GetDocumentDiagnostics {
 6986                previous_result_id: None,
 6987                identifier,
 6988                registration_id: None,
 6989            };
 6990            let request_timeout = ProjectSettings::get_global(cx)
 6991                .global_lsp_settings
 6992                .get_request_timeout();
 6993            let request_task = client.request_lsp(
 6994                upstream_project_id,
 6995                None,
 6996                request_timeout,
 6997                cx.background_executor().clone(),
 6998                request.to_proto(upstream_project_id, buffer.read(cx)),
 6999            );
 7000            cx.background_spawn(async move {
 7001                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 7002                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 7003                // Do not attempt to further process the dummy responses here.
 7004                let _response = request_task.await?;
 7005                Ok(None)
 7006            })
 7007        } else {
 7008            let servers = buffer.update(cx, |buffer, cx| {
 7009                self.running_language_servers_for_local_buffer(buffer, cx)
 7010                    .map(|(_, server)| server.clone())
 7011                    .collect::<Vec<_>>()
 7012            });
 7013
 7014            let pull_diagnostics = servers
 7015                .into_iter()
 7016                .flat_map(|server| {
 7017                    let result = maybe!({
 7018                        let local = self.as_local()?;
 7019                        let server_id = server.server_id();
 7020                        let providers_with_identifiers = local
 7021                            .language_server_dynamic_registrations
 7022                            .get(&server_id)
 7023                            .into_iter()
 7024                            .flat_map(|registrations| registrations.diagnostics.clone())
 7025                            .collect::<Vec<_>>();
 7026                        Some(
 7027                            providers_with_identifiers
 7028                                .into_iter()
 7029                                .map(|(registration_id, dynamic_caps)| {
 7030                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 7031                                    let registration_id = registration_id.map(SharedString::from);
 7032                                    let result_id = self.result_id_for_buffer_pull(
 7033                                        server_id,
 7034                                        buffer_id,
 7035                                        &registration_id,
 7036                                        cx,
 7037                                    );
 7038                                    self.request_lsp(
 7039                                        buffer.clone(),
 7040                                        LanguageServerToQuery::Other(server_id),
 7041                                        GetDocumentDiagnostics {
 7042                                            previous_result_id: result_id,
 7043                                            registration_id,
 7044                                            identifier,
 7045                                        },
 7046                                        cx,
 7047                                    )
 7048                                })
 7049                                .collect::<Vec<_>>(),
 7050                        )
 7051                    });
 7052
 7053                    result.unwrap_or_default()
 7054                })
 7055                .collect::<Vec<_>>();
 7056
 7057            cx.background_spawn(async move {
 7058                let mut responses = Vec::new();
 7059                for diagnostics in join_all(pull_diagnostics).await {
 7060                    responses.extend(diagnostics?);
 7061                }
 7062                Ok(Some(responses))
 7063            })
 7064        }
 7065    }
 7066
 7067    pub fn applicable_inlay_chunks(
 7068        &mut self,
 7069        buffer: &Entity<Buffer>,
 7070        ranges: &[Range<text::Anchor>],
 7071        cx: &mut Context<Self>,
 7072    ) -> Vec<Range<BufferRow>> {
 7073        let buffer_snapshot = buffer.read(cx).snapshot();
 7074        let ranges = ranges
 7075            .iter()
 7076            .map(|range| range.to_point(&buffer_snapshot))
 7077            .collect::<Vec<_>>();
 7078
 7079        self.latest_lsp_data(buffer, cx)
 7080            .inlay_hints
 7081            .applicable_chunks(ranges.as_slice())
 7082            .map(|chunk| chunk.row_range())
 7083            .collect()
 7084    }
 7085
 7086    pub fn invalidate_inlay_hints<'a>(
 7087        &'a mut self,
 7088        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 7089    ) {
 7090        for buffer_id in for_buffers {
 7091            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 7092                lsp_data.inlay_hints.clear();
 7093            }
 7094        }
 7095    }
 7096
 7097    pub fn inlay_hints(
 7098        &mut self,
 7099        invalidate: InvalidationStrategy,
 7100        buffer: Entity<Buffer>,
 7101        ranges: Vec<Range<text::Anchor>>,
 7102        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 7103        cx: &mut Context<Self>,
 7104    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 7105        let next_hint_id = self.next_hint_id.clone();
 7106        let lsp_data = self.latest_lsp_data(&buffer, cx);
 7107        let query_version = lsp_data.buffer_version.clone();
 7108        let mut lsp_refresh_requested = false;
 7109        let for_server = if let InvalidationStrategy::RefreshRequested {
 7110            server_id,
 7111            request_id,
 7112        } = invalidate
 7113        {
 7114            let invalidated = lsp_data
 7115                .inlay_hints
 7116                .invalidate_for_server_refresh(server_id, request_id);
 7117            lsp_refresh_requested = invalidated;
 7118            Some(server_id)
 7119        } else {
 7120            None
 7121        };
 7122        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 7123        let known_chunks = known_chunks
 7124            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 7125            .map(|(_, known_chunks)| known_chunks)
 7126            .unwrap_or_default();
 7127
 7128        let buffer_snapshot = buffer.read(cx).snapshot();
 7129        let ranges = ranges
 7130            .iter()
 7131            .map(|range| range.to_point(&buffer_snapshot))
 7132            .collect::<Vec<_>>();
 7133
 7134        let mut hint_fetch_tasks = Vec::new();
 7135        let mut cached_inlay_hints = None;
 7136        let mut ranges_to_query = None;
 7137        let applicable_chunks = existing_inlay_hints
 7138            .applicable_chunks(ranges.as_slice())
 7139            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7140            .collect::<Vec<_>>();
 7141        if applicable_chunks.is_empty() {
 7142            return HashMap::default();
 7143        }
 7144
 7145        for row_chunk in applicable_chunks {
 7146            match (
 7147                existing_inlay_hints
 7148                    .cached_hints(&row_chunk)
 7149                    .filter(|_| !lsp_refresh_requested)
 7150                    .cloned(),
 7151                existing_inlay_hints
 7152                    .fetched_hints(&row_chunk)
 7153                    .as_ref()
 7154                    .filter(|_| !lsp_refresh_requested)
 7155                    .cloned(),
 7156            ) {
 7157                (None, None) => {
 7158                    let chunk_range = row_chunk.anchor_range();
 7159                    ranges_to_query
 7160                        .get_or_insert_with(Vec::new)
 7161                        .push((row_chunk, chunk_range));
 7162                }
 7163                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7164                (Some(cached_hints), None) => {
 7165                    for (server_id, cached_hints) in cached_hints {
 7166                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7167                            cached_inlay_hints
 7168                                .get_or_insert_with(HashMap::default)
 7169                                .entry(row_chunk.row_range())
 7170                                .or_insert_with(HashMap::default)
 7171                                .entry(server_id)
 7172                                .or_insert_with(Vec::new)
 7173                                .extend(cached_hints);
 7174                        }
 7175                    }
 7176                }
 7177                (Some(cached_hints), Some(fetched_hints)) => {
 7178                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7179                    for (server_id, cached_hints) in cached_hints {
 7180                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7181                            cached_inlay_hints
 7182                                .get_or_insert_with(HashMap::default)
 7183                                .entry(row_chunk.row_range())
 7184                                .or_insert_with(HashMap::default)
 7185                                .entry(server_id)
 7186                                .or_insert_with(Vec::new)
 7187                                .extend(cached_hints);
 7188                        }
 7189                    }
 7190                }
 7191            }
 7192        }
 7193
 7194        if hint_fetch_tasks.is_empty()
 7195            && ranges_to_query
 7196                .as_ref()
 7197                .is_none_or(|ranges| ranges.is_empty())
 7198            && let Some(cached_inlay_hints) = cached_inlay_hints
 7199        {
 7200            cached_inlay_hints
 7201                .into_iter()
 7202                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7203                .collect()
 7204        } else {
 7205            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7206                // When a server refresh was requested, other servers' cached hints
 7207                // are unaffected by the refresh and must be included in the result.
 7208                // Otherwise apply_fetched_hints (with should_invalidate()=true)
 7209                // removes all visible hints but only adds back the requesting
 7210                // server's new hints, permanently losing other servers' hints.
 7211                let other_servers_cached: CacheInlayHints = if lsp_refresh_requested {
 7212                    lsp_data
 7213                        .inlay_hints
 7214                        .cached_hints(&chunk)
 7215                        .cloned()
 7216                        .unwrap_or_default()
 7217                } else {
 7218                    HashMap::default()
 7219                };
 7220
 7221                let next_hint_id = next_hint_id.clone();
 7222                let buffer = buffer.clone();
 7223                let query_version = query_version.clone();
 7224                let new_inlay_hints = cx
 7225                    .spawn(async move |lsp_store, cx| {
 7226                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7227                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7228                        })?;
 7229                        new_fetch_task
 7230                            .await
 7231                            .and_then(|new_hints_by_server| {
 7232                                lsp_store.update(cx, |lsp_store, cx| {
 7233                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7234                                    let update_cache = lsp_data.buffer_version == query_version;
 7235                                    if new_hints_by_server.is_empty() {
 7236                                        if update_cache {
 7237                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7238                                        }
 7239                                        other_servers_cached
 7240                                    } else {
 7241                                        let mut result = other_servers_cached;
 7242                                        for (server_id, new_hints) in new_hints_by_server {
 7243                                            let new_hints = new_hints
 7244                                                .into_iter()
 7245                                                .map(|new_hint| {
 7246                                                    (
 7247                                                        InlayId::Hint(next_hint_id.fetch_add(
 7248                                                            1,
 7249                                                            atomic::Ordering::AcqRel,
 7250                                                        )),
 7251                                                        new_hint,
 7252                                                    )
 7253                                                })
 7254                                                .collect::<Vec<_>>();
 7255                                            if update_cache {
 7256                                                lsp_data.inlay_hints.insert_new_hints(
 7257                                                    chunk,
 7258                                                    server_id,
 7259                                                    new_hints.clone(),
 7260                                                );
 7261                                            }
 7262                                            result.insert(server_id, new_hints);
 7263                                        }
 7264                                        result
 7265                                    }
 7266                                })
 7267                            })
 7268                            .map_err(Arc::new)
 7269                    })
 7270                    .shared();
 7271
 7272                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7273                *fetch_task = Some(new_inlay_hints.clone());
 7274                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7275            }
 7276
 7277            cached_inlay_hints
 7278                .unwrap_or_default()
 7279                .into_iter()
 7280                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7281                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7282                    (
 7283                        chunk.row_range(),
 7284                        cx.spawn(async move |_, _| {
 7285                            hints_fetch.await.map_err(|e| {
 7286                                if e.error_code() != ErrorCode::Internal {
 7287                                    anyhow!(e.error_code())
 7288                                } else {
 7289                                    anyhow!("{e:#}")
 7290                                }
 7291                            })
 7292                        }),
 7293                    )
 7294                }))
 7295                .collect()
 7296        }
 7297    }
 7298
 7299    fn fetch_inlay_hints(
 7300        &mut self,
 7301        for_server: Option<LanguageServerId>,
 7302        buffer: &Entity<Buffer>,
 7303        range: Range<Anchor>,
 7304        cx: &mut Context<Self>,
 7305    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7306        let request = InlayHints {
 7307            range: range.clone(),
 7308        };
 7309        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7310            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7311                return Task::ready(Ok(HashMap::default()));
 7312            }
 7313            let request_timeout = ProjectSettings::get_global(cx)
 7314                .global_lsp_settings
 7315                .get_request_timeout();
 7316            let request_task = upstream_client.request_lsp(
 7317                project_id,
 7318                for_server.map(|id| id.to_proto()),
 7319                request_timeout,
 7320                cx.background_executor().clone(),
 7321                request.to_proto(project_id, buffer.read(cx)),
 7322            );
 7323            let buffer = buffer.clone();
 7324            cx.spawn(async move |weak_lsp_store, cx| {
 7325                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7326                    return Ok(HashMap::default());
 7327                };
 7328                let Some(responses) = request_task.await? else {
 7329                    return Ok(HashMap::default());
 7330                };
 7331
 7332                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7333                    let lsp_store = lsp_store.clone();
 7334                    let buffer = buffer.clone();
 7335                    let cx = cx.clone();
 7336                    let request = request.clone();
 7337                    async move {
 7338                        (
 7339                            LanguageServerId::from_proto(response.server_id),
 7340                            request
 7341                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7342                                .await,
 7343                        )
 7344                    }
 7345                }))
 7346                .await;
 7347
 7348                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7349                let mut has_errors = false;
 7350                let inlay_hints = inlay_hints
 7351                    .into_iter()
 7352                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7353                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7354                        Err(e) => {
 7355                            has_errors = true;
 7356                            log::error!("{e:#}");
 7357                            None
 7358                        }
 7359                    })
 7360                    .map(|(server_id, mut new_hints)| {
 7361                        new_hints.retain(|hint| {
 7362                            hint.position.is_valid(&buffer_snapshot)
 7363                                && range.start.is_valid(&buffer_snapshot)
 7364                                && range.end.is_valid(&buffer_snapshot)
 7365                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7366                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7367                        });
 7368                        (server_id, new_hints)
 7369                    })
 7370                    .collect::<HashMap<_, _>>();
 7371                anyhow::ensure!(
 7372                    !has_errors || !inlay_hints.is_empty(),
 7373                    "Failed to fetch inlay hints"
 7374                );
 7375                Ok(inlay_hints)
 7376            })
 7377        } else {
 7378            let inlay_hints_task = match for_server {
 7379                Some(server_id) => {
 7380                    let server_task = self.request_lsp(
 7381                        buffer.clone(),
 7382                        LanguageServerToQuery::Other(server_id),
 7383                        request,
 7384                        cx,
 7385                    );
 7386                    cx.background_spawn(async move {
 7387                        let mut responses = Vec::new();
 7388                        match server_task.await {
 7389                            Ok(response) => responses.push((server_id, response)),
 7390                            // rust-analyzer likes to error with this when its still loading up
 7391                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7392                            Err(e) => log::error!(
 7393                                "Error handling response for inlay hints request: {e:#}"
 7394                            ),
 7395                        }
 7396                        responses
 7397                    })
 7398                }
 7399                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7400            };
 7401            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7402            cx.background_spawn(async move {
 7403                Ok(inlay_hints_task
 7404                    .await
 7405                    .into_iter()
 7406                    .map(|(server_id, mut new_hints)| {
 7407                        new_hints.retain(|hint| {
 7408                            hint.position.is_valid(&buffer_snapshot)
 7409                                && range.start.is_valid(&buffer_snapshot)
 7410                                && range.end.is_valid(&buffer_snapshot)
 7411                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7412                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7413                        });
 7414                        (server_id, new_hints)
 7415                    })
 7416                    .collect())
 7417            })
 7418        }
 7419    }
 7420
 7421    fn diagnostic_registration_exists(
 7422        &self,
 7423        server_id: LanguageServerId,
 7424        registration_id: &Option<SharedString>,
 7425    ) -> bool {
 7426        let Some(local) = self.as_local() else {
 7427            return false;
 7428        };
 7429        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7430        else {
 7431            return false;
 7432        };
 7433        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7434        registrations.diagnostics.contains_key(&registration_key)
 7435    }
 7436
 7437    pub fn pull_diagnostics_for_buffer(
 7438        &mut self,
 7439        buffer: Entity<Buffer>,
 7440        cx: &mut Context<Self>,
 7441    ) -> Task<anyhow::Result<()>> {
 7442        let diagnostics = self.pull_diagnostics(buffer, cx);
 7443        cx.spawn(async move |lsp_store, cx| {
 7444            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7445                return Ok(());
 7446            };
 7447            lsp_store.update(cx, |lsp_store, cx| {
 7448                if lsp_store.as_local().is_none() {
 7449                    return;
 7450                }
 7451
 7452                let mut unchanged_buffers = HashMap::default();
 7453                let server_diagnostics_updates = diagnostics
 7454                    .into_iter()
 7455                    .filter_map(|diagnostics_set| match diagnostics_set {
 7456                        LspPullDiagnostics::Response {
 7457                            server_id,
 7458                            uri,
 7459                            diagnostics,
 7460                            registration_id,
 7461                        } => Some((server_id, uri, diagnostics, registration_id)),
 7462                        LspPullDiagnostics::Default => None,
 7463                    })
 7464                    .filter(|(server_id, _, _, registration_id)| {
 7465                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7466                    })
 7467                    .fold(
 7468                        HashMap::default(),
 7469                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7470                            let (result_id, diagnostics) = match diagnostics {
 7471                                PulledDiagnostics::Unchanged { result_id } => {
 7472                                    unchanged_buffers
 7473                                        .entry(new_registration_id.clone())
 7474                                        .or_insert_with(HashSet::default)
 7475                                        .insert(uri.clone());
 7476                                    (Some(result_id), Vec::new())
 7477                                }
 7478                                PulledDiagnostics::Changed {
 7479                                    result_id,
 7480                                    diagnostics,
 7481                                } => (result_id, diagnostics),
 7482                            };
 7483                            let disk_based_sources = Cow::Owned(
 7484                                lsp_store
 7485                                    .language_server_adapter_for_id(server_id)
 7486                                    .as_ref()
 7487                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7488                                    .unwrap_or(&[])
 7489                                    .to_vec(),
 7490                            );
 7491                            acc.entry(server_id)
 7492                                .or_insert_with(HashMap::default)
 7493                                .entry(new_registration_id.clone())
 7494                                .or_insert_with(Vec::new)
 7495                                .push(DocumentDiagnosticsUpdate {
 7496                                    server_id,
 7497                                    diagnostics: lsp::PublishDiagnosticsParams {
 7498                                        uri,
 7499                                        diagnostics,
 7500                                        version: None,
 7501                                    },
 7502                                    result_id: result_id.map(SharedString::new),
 7503                                    disk_based_sources,
 7504                                    registration_id: new_registration_id,
 7505                                });
 7506                            acc
 7507                        },
 7508                    );
 7509
 7510                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7511                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7512                        lsp_store
 7513                            .merge_lsp_diagnostics(
 7514                                DiagnosticSourceKind::Pulled,
 7515                                diagnostic_updates,
 7516                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7517                                    DiagnosticSourceKind::Pulled => {
 7518                                        old_diagnostic.registration_id != registration_id
 7519                                            || unchanged_buffers
 7520                                                .get(&old_diagnostic.registration_id)
 7521                                                .is_some_and(|unchanged_buffers| {
 7522                                                    unchanged_buffers.contains(&document_uri)
 7523                                                })
 7524                                    }
 7525                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7526                                        true
 7527                                    }
 7528                                },
 7529                                cx,
 7530                            )
 7531                            .log_err();
 7532                    }
 7533                }
 7534            })
 7535        })
 7536    }
 7537
 7538    pub fn signature_help<T: ToPointUtf16>(
 7539        &mut self,
 7540        buffer: &Entity<Buffer>,
 7541        position: T,
 7542        cx: &mut Context<Self>,
 7543    ) -> Task<Option<Vec<SignatureHelp>>> {
 7544        let position = position.to_point_utf16(buffer.read(cx));
 7545
 7546        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7547            let request = GetSignatureHelp { position };
 7548            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7549                return Task::ready(None);
 7550            }
 7551            let request_timeout = ProjectSettings::get_global(cx)
 7552                .global_lsp_settings
 7553                .get_request_timeout();
 7554            let request_task = client.request_lsp(
 7555                upstream_project_id,
 7556                None,
 7557                request_timeout,
 7558                cx.background_executor().clone(),
 7559                request.to_proto(upstream_project_id, buffer.read(cx)),
 7560            );
 7561            let buffer = buffer.clone();
 7562            cx.spawn(async move |weak_lsp_store, cx| {
 7563                let lsp_store = weak_lsp_store.upgrade()?;
 7564                let signatures = join_all(
 7565                    request_task
 7566                        .await
 7567                        .log_err()
 7568                        .flatten()
 7569                        .map(|response| response.payload)
 7570                        .unwrap_or_default()
 7571                        .into_iter()
 7572                        .map(|response| {
 7573                            let response = GetSignatureHelp { position }.response_from_proto(
 7574                                response.response,
 7575                                lsp_store.clone(),
 7576                                buffer.clone(),
 7577                                cx.clone(),
 7578                            );
 7579                            async move { response.await.log_err().flatten() }
 7580                        }),
 7581                )
 7582                .await
 7583                .into_iter()
 7584                .flatten()
 7585                .collect();
 7586                Some(signatures)
 7587            })
 7588        } else {
 7589            let all_actions_task = self.request_multiple_lsp_locally(
 7590                buffer,
 7591                Some(position),
 7592                GetSignatureHelp { position },
 7593                cx,
 7594            );
 7595            cx.background_spawn(async move {
 7596                Some(
 7597                    all_actions_task
 7598                        .await
 7599                        .into_iter()
 7600                        .flat_map(|(_, actions)| actions)
 7601                        .collect::<Vec<_>>(),
 7602                )
 7603            })
 7604        }
 7605    }
 7606
 7607    pub fn hover(
 7608        &mut self,
 7609        buffer: &Entity<Buffer>,
 7610        position: PointUtf16,
 7611        cx: &mut Context<Self>,
 7612    ) -> Task<Option<Vec<Hover>>> {
 7613        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7614            let request = GetHover { position };
 7615            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7616                return Task::ready(None);
 7617            }
 7618            let request_timeout = ProjectSettings::get_global(cx)
 7619                .global_lsp_settings
 7620                .get_request_timeout();
 7621            let request_task = client.request_lsp(
 7622                upstream_project_id,
 7623                None,
 7624                request_timeout,
 7625                cx.background_executor().clone(),
 7626                request.to_proto(upstream_project_id, buffer.read(cx)),
 7627            );
 7628            let buffer = buffer.clone();
 7629            cx.spawn(async move |weak_lsp_store, cx| {
 7630                let lsp_store = weak_lsp_store.upgrade()?;
 7631                let hovers = join_all(
 7632                    request_task
 7633                        .await
 7634                        .log_err()
 7635                        .flatten()
 7636                        .map(|response| response.payload)
 7637                        .unwrap_or_default()
 7638                        .into_iter()
 7639                        .map(|response| {
 7640                            let response = GetHover { position }.response_from_proto(
 7641                                response.response,
 7642                                lsp_store.clone(),
 7643                                buffer.clone(),
 7644                                cx.clone(),
 7645                            );
 7646                            async move {
 7647                                response
 7648                                    .await
 7649                                    .log_err()
 7650                                    .flatten()
 7651                                    .and_then(remove_empty_hover_blocks)
 7652                            }
 7653                        }),
 7654                )
 7655                .await
 7656                .into_iter()
 7657                .flatten()
 7658                .collect();
 7659                Some(hovers)
 7660            })
 7661        } else {
 7662            let all_actions_task = self.request_multiple_lsp_locally(
 7663                buffer,
 7664                Some(position),
 7665                GetHover { position },
 7666                cx,
 7667            );
 7668            cx.background_spawn(async move {
 7669                Some(
 7670                    all_actions_task
 7671                        .await
 7672                        .into_iter()
 7673                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7674                        .collect::<Vec<Hover>>(),
 7675                )
 7676            })
 7677        }
 7678    }
 7679
 7680    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7681        let language_registry = self.languages.clone();
 7682
 7683        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7684            let request = upstream_client.request(proto::GetProjectSymbols {
 7685                project_id: *project_id,
 7686                query: query.to_string(),
 7687            });
 7688            cx.foreground_executor().spawn(async move {
 7689                let response = request.await?;
 7690                let mut symbols = Vec::new();
 7691                let core_symbols = response
 7692                    .symbols
 7693                    .into_iter()
 7694                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7695                    .collect::<Vec<_>>();
 7696                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7697                    .await;
 7698                Ok(symbols)
 7699            })
 7700        } else if let Some(local) = self.as_local() {
 7701            struct WorkspaceSymbolsResult {
 7702                server_id: LanguageServerId,
 7703                lsp_adapter: Arc<CachedLspAdapter>,
 7704                worktree: WeakEntity<Worktree>,
 7705                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7706            }
 7707
 7708            let mut requests = Vec::new();
 7709            let mut requested_servers = BTreeSet::new();
 7710            let request_timeout = ProjectSettings::get_global(cx)
 7711                .global_lsp_settings
 7712                .get_request_timeout();
 7713
 7714            for (seed, state) in local.language_server_ids.iter() {
 7715                let Some(worktree_handle) = self
 7716                    .worktree_store
 7717                    .read(cx)
 7718                    .worktree_for_id(seed.worktree_id, cx)
 7719                else {
 7720                    continue;
 7721                };
 7722
 7723                let worktree = worktree_handle.read(cx);
 7724                if !worktree.is_visible() {
 7725                    continue;
 7726                }
 7727
 7728                if !requested_servers.insert(state.id) {
 7729                    continue;
 7730                }
 7731
 7732                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7733                    Some(LanguageServerState::Running {
 7734                        adapter, server, ..
 7735                    }) => (adapter.clone(), server),
 7736
 7737                    _ => continue,
 7738                };
 7739
 7740                let supports_workspace_symbol_request =
 7741                    match server.capabilities().workspace_symbol_provider {
 7742                        Some(OneOf::Left(supported)) => supported,
 7743                        Some(OneOf::Right(_)) => true,
 7744                        None => false,
 7745                    };
 7746
 7747                if !supports_workspace_symbol_request {
 7748                    continue;
 7749                }
 7750
 7751                let worktree_handle = worktree_handle.clone();
 7752                let server_id = server.server_id();
 7753                requests.push(
 7754                    server
 7755                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7756                            lsp::WorkspaceSymbolParams {
 7757                                query: query.to_string(),
 7758                                ..Default::default()
 7759                            },
 7760                            request_timeout,
 7761                        )
 7762                        .map(move |response| {
 7763                            let lsp_symbols = response
 7764                                .into_response()
 7765                                .context("workspace symbols request")
 7766                                .log_err()
 7767                                .flatten()
 7768                                .map(|symbol_response| match symbol_response {
 7769                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7770                                        flat_responses
 7771                                            .into_iter()
 7772                                            .map(|lsp_symbol| {
 7773                                                (
 7774                                                    lsp_symbol.name,
 7775                                                    lsp_symbol.kind,
 7776                                                    lsp_symbol.location,
 7777                                                    lsp_symbol.container_name,
 7778                                                )
 7779                                            })
 7780                                            .collect::<Vec<_>>()
 7781                                    }
 7782                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7783                                        nested_responses
 7784                                            .into_iter()
 7785                                            .filter_map(|lsp_symbol| {
 7786                                                let location = match lsp_symbol.location {
 7787                                                    OneOf::Left(location) => location,
 7788                                                    OneOf::Right(_) => {
 7789                                                        log::error!(
 7790                                                            "Unexpected: client capabilities \
 7791                                                            forbid symbol resolutions in \
 7792                                                            workspace.symbol.resolveSupport"
 7793                                                        );
 7794                                                        return None;
 7795                                                    }
 7796                                                };
 7797                                                Some((
 7798                                                    lsp_symbol.name,
 7799                                                    lsp_symbol.kind,
 7800                                                    location,
 7801                                                    lsp_symbol.container_name,
 7802                                                ))
 7803                                            })
 7804                                            .collect::<Vec<_>>()
 7805                                    }
 7806                                })
 7807                                .unwrap_or_default();
 7808
 7809                            WorkspaceSymbolsResult {
 7810                                server_id,
 7811                                lsp_adapter,
 7812                                worktree: worktree_handle.downgrade(),
 7813                                lsp_symbols,
 7814                            }
 7815                        }),
 7816                );
 7817            }
 7818
 7819            cx.spawn(async move |this, cx| {
 7820                let responses = futures::future::join_all(requests).await;
 7821                let this = match this.upgrade() {
 7822                    Some(this) => this,
 7823                    None => return Ok(Vec::new()),
 7824                };
 7825
 7826                let mut symbols = Vec::new();
 7827                for result in responses {
 7828                    let core_symbols = this.update(cx, |this, cx| {
 7829                        result
 7830                            .lsp_symbols
 7831                            .into_iter()
 7832                            .filter_map(
 7833                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7834                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7835                                    let source_worktree = result.worktree.upgrade()?;
 7836                                    let source_worktree_id = source_worktree.read(cx).id();
 7837
 7838                                    let path = if let Some((tree, rel_path)) =
 7839                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7840                                    {
 7841                                        let worktree_id = tree.read(cx).id();
 7842                                        SymbolLocation::InProject(ProjectPath {
 7843                                            worktree_id,
 7844                                            path: rel_path,
 7845                                        })
 7846                                    } else {
 7847                                        SymbolLocation::OutsideProject {
 7848                                            signature: this.symbol_signature(&abs_path),
 7849                                            abs_path: abs_path.into(),
 7850                                        }
 7851                                    };
 7852
 7853                                    Some(CoreSymbol {
 7854                                        source_language_server_id: result.server_id,
 7855                                        language_server_name: result.lsp_adapter.name.clone(),
 7856                                        source_worktree_id,
 7857                                        path,
 7858                                        kind: symbol_kind,
 7859                                        name: collapse_newlines(&symbol_name, ""),
 7860                                        range: range_from_lsp(symbol_location.range),
 7861                                        container_name: container_name
 7862                                            .map(|c| collapse_newlines(&c, "")),
 7863                                    })
 7864                                },
 7865                            )
 7866                            .collect::<Vec<_>>()
 7867                    });
 7868
 7869                    populate_labels_for_symbols(
 7870                        core_symbols,
 7871                        &language_registry,
 7872                        Some(result.lsp_adapter),
 7873                        &mut symbols,
 7874                    )
 7875                    .await;
 7876                }
 7877
 7878                Ok(symbols)
 7879            })
 7880        } else {
 7881            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7882        }
 7883    }
 7884
 7885    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7886        let mut summary = DiagnosticSummary::default();
 7887        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7888            summary.error_count += path_summary.error_count;
 7889            summary.warning_count += path_summary.warning_count;
 7890        }
 7891        summary
 7892    }
 7893
 7894    /// Returns the diagnostic summary for a specific project path.
 7895    pub fn diagnostic_summary_for_path(
 7896        &self,
 7897        project_path: &ProjectPath,
 7898        _: &App,
 7899    ) -> DiagnosticSummary {
 7900        if let Some(summaries) = self
 7901            .diagnostic_summaries
 7902            .get(&project_path.worktree_id)
 7903            .and_then(|map| map.get(&project_path.path))
 7904        {
 7905            let (error_count, warning_count) = summaries.iter().fold(
 7906                (0, 0),
 7907                |(error_count, warning_count), (_language_server_id, summary)| {
 7908                    (
 7909                        error_count + summary.error_count,
 7910                        warning_count + summary.warning_count,
 7911                    )
 7912                },
 7913            );
 7914
 7915            DiagnosticSummary {
 7916                error_count,
 7917                warning_count,
 7918            }
 7919        } else {
 7920            DiagnosticSummary::default()
 7921        }
 7922    }
 7923
 7924    pub fn diagnostic_summaries<'a>(
 7925        &'a self,
 7926        include_ignored: bool,
 7927        cx: &'a App,
 7928    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7929        self.worktree_store
 7930            .read(cx)
 7931            .visible_worktrees(cx)
 7932            .filter_map(|worktree| {
 7933                let worktree = worktree.read(cx);
 7934                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7935            })
 7936            .flat_map(move |(worktree, summaries)| {
 7937                let worktree_id = worktree.id();
 7938                summaries
 7939                    .iter()
 7940                    .filter(move |(path, _)| {
 7941                        include_ignored
 7942                            || worktree
 7943                                .entry_for_path(path.as_ref())
 7944                                .is_some_and(|entry| !entry.is_ignored)
 7945                    })
 7946                    .flat_map(move |(path, summaries)| {
 7947                        summaries.iter().map(move |(server_id, summary)| {
 7948                            (
 7949                                ProjectPath {
 7950                                    worktree_id,
 7951                                    path: path.clone(),
 7952                                },
 7953                                *server_id,
 7954                                *summary,
 7955                            )
 7956                        })
 7957                    })
 7958            })
 7959    }
 7960
 7961    pub fn on_buffer_edited(
 7962        &mut self,
 7963        buffer: Entity<Buffer>,
 7964        cx: &mut Context<Self>,
 7965    ) -> Option<()> {
 7966        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7967            Some(
 7968                self.as_local()?
 7969                    .language_servers_for_buffer(buffer, cx)
 7970                    .map(|i| i.1.clone())
 7971                    .collect(),
 7972            )
 7973        })?;
 7974
 7975        let buffer = buffer.read(cx);
 7976        let file = File::from_dyn(buffer.file())?;
 7977        let abs_path = file.as_local()?.abs_path(cx);
 7978        let uri = lsp::Uri::from_file_path(&abs_path)
 7979            .ok()
 7980            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7981            .log_err()?;
 7982        let next_snapshot = buffer.text_snapshot();
 7983        for language_server in language_servers {
 7984            let language_server = language_server.clone();
 7985
 7986            let buffer_snapshots = self
 7987                .as_local_mut()?
 7988                .buffer_snapshots
 7989                .get_mut(&buffer.remote_id())
 7990                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7991            let previous_snapshot = buffer_snapshots.last()?;
 7992
 7993            let build_incremental_change = || {
 7994                buffer
 7995                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7996                        previous_snapshot.snapshot.version(),
 7997                    )
 7998                    .map(|edit| {
 7999                        let edit_start = edit.new.start.0;
 8000                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 8001                        let new_text = next_snapshot
 8002                            .text_for_range(edit.new.start.1..edit.new.end.1)
 8003                            .collect();
 8004                        lsp::TextDocumentContentChangeEvent {
 8005                            range: Some(lsp::Range::new(
 8006                                point_to_lsp(edit_start),
 8007                                point_to_lsp(edit_end),
 8008                            )),
 8009                            range_length: None,
 8010                            text: new_text,
 8011                        }
 8012                    })
 8013                    .collect()
 8014            };
 8015
 8016            let document_sync_kind = language_server
 8017                .capabilities()
 8018                .text_document_sync
 8019                .as_ref()
 8020                .and_then(|sync| match sync {
 8021                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 8022                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 8023                });
 8024
 8025            let content_changes: Vec<_> = match document_sync_kind {
 8026                Some(lsp::TextDocumentSyncKind::FULL) => {
 8027                    vec![lsp::TextDocumentContentChangeEvent {
 8028                        range: None,
 8029                        range_length: None,
 8030                        text: next_snapshot.text(),
 8031                    }]
 8032                }
 8033                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8034                _ => {
 8035                    #[cfg(any(test, feature = "test-support"))]
 8036                    {
 8037                        build_incremental_change()
 8038                    }
 8039
 8040                    #[cfg(not(any(test, feature = "test-support")))]
 8041                    {
 8042                        continue;
 8043                    }
 8044                }
 8045            };
 8046
 8047            let next_version = previous_snapshot.version + 1;
 8048            buffer_snapshots.push(LspBufferSnapshot {
 8049                version: next_version,
 8050                snapshot: next_snapshot.clone(),
 8051            });
 8052
 8053            language_server
 8054                .notify::<lsp::notification::DidChangeTextDocument>(
 8055                    lsp::DidChangeTextDocumentParams {
 8056                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8057                            uri.clone(),
 8058                            next_version,
 8059                        ),
 8060                        content_changes,
 8061                    },
 8062                )
 8063                .ok();
 8064            self.pull_workspace_diagnostics(language_server.server_id());
 8065        }
 8066
 8067        None
 8068    }
 8069
 8070    pub fn on_buffer_saved(
 8071        &mut self,
 8072        buffer: Entity<Buffer>,
 8073        cx: &mut Context<Self>,
 8074    ) -> Option<()> {
 8075        let file = File::from_dyn(buffer.read(cx).file())?;
 8076        let worktree_id = file.worktree_id(cx);
 8077        let abs_path = file.as_local()?.abs_path(cx);
 8078        let text_document = lsp::TextDocumentIdentifier {
 8079            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8080        };
 8081        let local = self.as_local()?;
 8082
 8083        for server in local.language_servers_for_worktree(worktree_id) {
 8084            if let Some(include_text) = include_text(server.as_ref()) {
 8085                let text = if include_text {
 8086                    Some(buffer.read(cx).text())
 8087                } else {
 8088                    None
 8089                };
 8090                server
 8091                    .notify::<lsp::notification::DidSaveTextDocument>(
 8092                        lsp::DidSaveTextDocumentParams {
 8093                            text_document: text_document.clone(),
 8094                            text,
 8095                        },
 8096                    )
 8097                    .ok();
 8098            }
 8099        }
 8100
 8101        let language_servers = buffer.update(cx, |buffer, cx| {
 8102            local.language_server_ids_for_buffer(buffer, cx)
 8103        });
 8104        for language_server_id in language_servers {
 8105            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8106        }
 8107
 8108        None
 8109    }
 8110
 8111    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8112        maybe!(async move {
 8113            let mut refreshed_servers = HashSet::default();
 8114            let servers = lsp_store
 8115                .update(cx, |lsp_store, cx| {
 8116                    let local = lsp_store.as_local()?;
 8117
 8118                    let servers = local
 8119                        .language_server_ids
 8120                        .iter()
 8121                        .filter_map(|(seed, state)| {
 8122                            let worktree = lsp_store
 8123                                .worktree_store
 8124                                .read(cx)
 8125                                .worktree_for_id(seed.worktree_id, cx);
 8126                            let delegate: Arc<dyn LspAdapterDelegate> =
 8127                                worktree.map(|worktree| {
 8128                                    LocalLspAdapterDelegate::new(
 8129                                        local.languages.clone(),
 8130                                        &local.environment,
 8131                                        cx.weak_entity(),
 8132                                        &worktree,
 8133                                        local.http_client.clone(),
 8134                                        local.fs.clone(),
 8135                                        cx,
 8136                                    )
 8137                                })?;
 8138                            let server_id = state.id;
 8139
 8140                            let states = local.language_servers.get(&server_id)?;
 8141
 8142                            match states {
 8143                                LanguageServerState::Starting { .. } => None,
 8144                                LanguageServerState::Running {
 8145                                    adapter, server, ..
 8146                                } => {
 8147                                    let adapter = adapter.clone();
 8148                                    let server = server.clone();
 8149                                    refreshed_servers.insert(server.name());
 8150                                    let toolchain = seed.toolchain.clone();
 8151                                    Some(cx.spawn(async move |_, cx| {
 8152                                        let settings =
 8153                                            LocalLspStore::workspace_configuration_for_adapter(
 8154                                                adapter.adapter.clone(),
 8155                                                &delegate,
 8156                                                toolchain,
 8157                                                None,
 8158                                                cx,
 8159                                            )
 8160                                            .await
 8161                                            .ok()?;
 8162                                        server
 8163                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8164                                                lsp::DidChangeConfigurationParams { settings },
 8165                                            )
 8166                                            .ok()?;
 8167                                        Some(())
 8168                                    }))
 8169                                }
 8170                            }
 8171                        })
 8172                        .collect::<Vec<_>>();
 8173
 8174                    Some(servers)
 8175                })
 8176                .ok()
 8177                .flatten()?;
 8178
 8179            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8180            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8181            // to stop and unregister its language server wrapper.
 8182            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8183            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8184            let _: Vec<Option<()>> = join_all(servers).await;
 8185
 8186            Some(())
 8187        })
 8188        .await;
 8189    }
 8190
 8191    fn maintain_workspace_config(
 8192        external_refresh_requests: watch::Receiver<()>,
 8193        cx: &mut Context<Self>,
 8194    ) -> Task<Result<()>> {
 8195        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8196        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8197
 8198        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8199            *settings_changed_tx.borrow_mut() = ();
 8200        });
 8201
 8202        let mut joint_future =
 8203            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8204        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8205        // - 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).
 8206        // - 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.
 8207        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8208        // - 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,
 8209        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8210        cx.spawn(async move |this, cx| {
 8211            while let Some(()) = joint_future.next().await {
 8212                this.update(cx, |this, cx| {
 8213                    this.refresh_server_tree(cx);
 8214                })
 8215                .ok();
 8216
 8217                Self::refresh_workspace_configurations(&this, cx).await;
 8218            }
 8219
 8220            drop(settings_observation);
 8221            anyhow::Ok(())
 8222        })
 8223    }
 8224
 8225    pub fn running_language_servers_for_local_buffer<'a>(
 8226        &'a self,
 8227        buffer: &Buffer,
 8228        cx: &mut App,
 8229    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8230        let local = self.as_local();
 8231        let language_server_ids = local
 8232            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8233            .unwrap_or_default();
 8234
 8235        language_server_ids
 8236            .into_iter()
 8237            .filter_map(
 8238                move |server_id| match local?.language_servers.get(&server_id)? {
 8239                    LanguageServerState::Running {
 8240                        adapter, server, ..
 8241                    } => Some((adapter, server)),
 8242                    _ => None,
 8243                },
 8244            )
 8245    }
 8246
 8247    pub fn language_servers_for_local_buffer(
 8248        &self,
 8249        buffer: &Buffer,
 8250        cx: &mut App,
 8251    ) -> Vec<LanguageServerId> {
 8252        let local = self.as_local();
 8253        local
 8254            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8255            .unwrap_or_default()
 8256    }
 8257
 8258    pub fn language_server_for_local_buffer<'a>(
 8259        &'a self,
 8260        buffer: &'a Buffer,
 8261        server_id: LanguageServerId,
 8262        cx: &'a mut App,
 8263    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8264        self.as_local()?
 8265            .language_servers_for_buffer(buffer, cx)
 8266            .find(|(_, s)| s.server_id() == server_id)
 8267    }
 8268
 8269    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8270        self.diagnostic_summaries.remove(&id_to_remove);
 8271        if let Some(local) = self.as_local_mut() {
 8272            let to_remove = local.remove_worktree(id_to_remove, cx);
 8273            for server in to_remove {
 8274                self.language_server_statuses.remove(&server);
 8275            }
 8276        }
 8277    }
 8278
 8279    fn invalidate_diagnostic_summaries_for_removed_entries(
 8280        &mut self,
 8281        worktree_id: WorktreeId,
 8282        changes: &UpdatedEntriesSet,
 8283        cx: &mut Context<Self>,
 8284    ) {
 8285        let Some(summaries_for_tree) = self.diagnostic_summaries.get_mut(&worktree_id) else {
 8286            return;
 8287        };
 8288
 8289        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
 8290        let mut cleared_server_ids: HashSet<LanguageServerId> = HashSet::default();
 8291        let downstream = self.downstream_client.clone();
 8292
 8293        for (path, _, _) in changes
 8294            .iter()
 8295            .filter(|(_, _, change)| *change == PathChange::Removed)
 8296        {
 8297            if let Some(summaries_by_server_id) = summaries_for_tree.remove(path) {
 8298                for (server_id, _) in &summaries_by_server_id {
 8299                    cleared_server_ids.insert(*server_id);
 8300                    if let Some((client, project_id)) = &downstream {
 8301                        client
 8302                            .send(proto::UpdateDiagnosticSummary {
 8303                                project_id: *project_id,
 8304                                worktree_id: worktree_id.to_proto(),
 8305                                summary: Some(proto::DiagnosticSummary {
 8306                                    path: path.as_ref().to_proto(),
 8307                                    language_server_id: server_id.0 as u64,
 8308                                    error_count: 0,
 8309                                    warning_count: 0,
 8310                                }),
 8311                                more_summaries: Vec::new(),
 8312                            })
 8313                            .ok();
 8314                    }
 8315                }
 8316                cleared_paths.push(ProjectPath {
 8317                    worktree_id,
 8318                    path: path.clone(),
 8319                });
 8320            }
 8321        }
 8322
 8323        if !cleared_paths.is_empty() {
 8324            for server_id in cleared_server_ids {
 8325                cx.emit(LspStoreEvent::DiagnosticsUpdated {
 8326                    server_id,
 8327                    paths: cleared_paths.clone(),
 8328                });
 8329            }
 8330        }
 8331    }
 8332
 8333    pub fn shared(
 8334        &mut self,
 8335        project_id: u64,
 8336        downstream_client: AnyProtoClient,
 8337        _: &mut Context<Self>,
 8338    ) {
 8339        self.downstream_client = Some((downstream_client.clone(), project_id));
 8340
 8341        for (server_id, status) in &self.language_server_statuses {
 8342            if let Some(server) = self.language_server_for_id(*server_id) {
 8343                downstream_client
 8344                    .send(proto::StartLanguageServer {
 8345                        project_id,
 8346                        server: Some(proto::LanguageServer {
 8347                            id: server_id.to_proto(),
 8348                            name: status.name.to_string(),
 8349                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8350                        }),
 8351                        capabilities: serde_json::to_string(&server.capabilities())
 8352                            .expect("serializing server LSP capabilities"),
 8353                    })
 8354                    .log_err();
 8355            }
 8356        }
 8357    }
 8358
 8359    pub fn disconnected_from_host(&mut self) {
 8360        self.downstream_client.take();
 8361    }
 8362
 8363    pub fn disconnected_from_ssh_remote(&mut self) {
 8364        if let LspStoreMode::Remote(RemoteLspStore {
 8365            upstream_client, ..
 8366        }) = &mut self.mode
 8367        {
 8368            upstream_client.take();
 8369        }
 8370    }
 8371
 8372    pub(crate) fn set_language_server_statuses_from_proto(
 8373        &mut self,
 8374        project: WeakEntity<Project>,
 8375        language_servers: Vec<proto::LanguageServer>,
 8376        server_capabilities: Vec<String>,
 8377        cx: &mut Context<Self>,
 8378    ) {
 8379        let lsp_logs = cx
 8380            .try_global::<GlobalLogStore>()
 8381            .map(|lsp_store| lsp_store.0.clone());
 8382
 8383        self.language_server_statuses = language_servers
 8384            .into_iter()
 8385            .zip(server_capabilities)
 8386            .map(|(server, server_capabilities)| {
 8387                let server_id = LanguageServerId(server.id as usize);
 8388                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8389                    self.lsp_server_capabilities
 8390                        .insert(server_id, server_capabilities);
 8391                }
 8392
 8393                let name = LanguageServerName::from_proto(server.name);
 8394                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8395
 8396                if let Some(lsp_logs) = &lsp_logs {
 8397                    lsp_logs.update(cx, |lsp_logs, cx| {
 8398                        lsp_logs.add_language_server(
 8399                            // Only remote clients get their language servers set from proto
 8400                            LanguageServerKind::Remote {
 8401                                project: project.clone(),
 8402                            },
 8403                            server_id,
 8404                            Some(name.clone()),
 8405                            worktree,
 8406                            None,
 8407                            cx,
 8408                        );
 8409                    });
 8410                }
 8411
 8412                (
 8413                    server_id,
 8414                    LanguageServerStatus {
 8415                        name,
 8416                        server_version: None,
 8417                        server_readable_version: None,
 8418                        pending_work: Default::default(),
 8419                        has_pending_diagnostic_updates: false,
 8420                        progress_tokens: Default::default(),
 8421                        worktree,
 8422                        binary: None,
 8423                        configuration: None,
 8424                        workspace_folders: BTreeSet::new(),
 8425                        process_id: None,
 8426                    },
 8427                )
 8428            })
 8429            .collect();
 8430    }
 8431
 8432    #[cfg(feature = "test-support")]
 8433    pub fn update_diagnostic_entries(
 8434        &mut self,
 8435        server_id: LanguageServerId,
 8436        abs_path: PathBuf,
 8437        result_id: Option<SharedString>,
 8438        version: Option<i32>,
 8439        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8440        cx: &mut Context<Self>,
 8441    ) -> anyhow::Result<()> {
 8442        self.merge_diagnostic_entries(
 8443            vec![DocumentDiagnosticsUpdate {
 8444                diagnostics: DocumentDiagnostics {
 8445                    diagnostics,
 8446                    document_abs_path: abs_path,
 8447                    version,
 8448                },
 8449                result_id,
 8450                server_id,
 8451                disk_based_sources: Cow::Borrowed(&[]),
 8452                registration_id: None,
 8453            }],
 8454            |_, _, _| false,
 8455            cx,
 8456        )?;
 8457        Ok(())
 8458    }
 8459
 8460    pub fn merge_diagnostic_entries<'a>(
 8461        &mut self,
 8462        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8463        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8464        cx: &mut Context<Self>,
 8465    ) -> anyhow::Result<()> {
 8466        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8467        let mut updated_diagnostics_paths = HashMap::default();
 8468        for mut update in diagnostic_updates {
 8469            let abs_path = &update.diagnostics.document_abs_path;
 8470            let server_id = update.server_id;
 8471            let Some((worktree, relative_path)) =
 8472                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8473            else {
 8474                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8475                return Ok(());
 8476            };
 8477
 8478            let worktree_id = worktree.read(cx).id();
 8479            let project_path = ProjectPath {
 8480                worktree_id,
 8481                path: relative_path,
 8482            };
 8483
 8484            let document_uri = lsp::Uri::from_file_path(abs_path)
 8485                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8486            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8487                let snapshot = buffer_handle.read(cx).snapshot();
 8488                let buffer = buffer_handle.read(cx);
 8489                let reused_diagnostics = buffer
 8490                    .buffer_diagnostics(Some(server_id))
 8491                    .iter()
 8492                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8493                    .map(|v| {
 8494                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8495                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8496                        DiagnosticEntry {
 8497                            range: start..end,
 8498                            diagnostic: v.diagnostic.clone(),
 8499                        }
 8500                    })
 8501                    .collect::<Vec<_>>();
 8502
 8503                self.as_local_mut()
 8504                    .context("cannot merge diagnostics on a remote LspStore")?
 8505                    .update_buffer_diagnostics(
 8506                        &buffer_handle,
 8507                        server_id,
 8508                        Some(update.registration_id),
 8509                        update.result_id,
 8510                        update.diagnostics.version,
 8511                        update.diagnostics.diagnostics.clone(),
 8512                        reused_diagnostics.clone(),
 8513                        cx,
 8514                    )?;
 8515
 8516                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8517            } else if let Some(local) = self.as_local() {
 8518                let reused_diagnostics = local
 8519                    .diagnostics
 8520                    .get(&worktree_id)
 8521                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8522                    .and_then(|diagnostics_by_server_id| {
 8523                        diagnostics_by_server_id
 8524                            .binary_search_by_key(&server_id, |e| e.0)
 8525                            .ok()
 8526                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8527                    })
 8528                    .into_iter()
 8529                    .flatten()
 8530                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8531
 8532                update
 8533                    .diagnostics
 8534                    .diagnostics
 8535                    .extend(reused_diagnostics.cloned());
 8536            }
 8537
 8538            let updated = worktree.update(cx, |worktree, cx| {
 8539                self.update_worktree_diagnostics(
 8540                    worktree.id(),
 8541                    server_id,
 8542                    project_path.path.clone(),
 8543                    update.diagnostics.diagnostics,
 8544                    cx,
 8545                )
 8546            })?;
 8547            match updated {
 8548                ControlFlow::Continue(new_summary) => {
 8549                    if let Some((project_id, new_summary)) = new_summary {
 8550                        match &mut diagnostics_summary {
 8551                            Some(diagnostics_summary) => {
 8552                                diagnostics_summary
 8553                                    .more_summaries
 8554                                    .push(proto::DiagnosticSummary {
 8555                                        path: project_path.path.as_ref().to_proto(),
 8556                                        language_server_id: server_id.0 as u64,
 8557                                        error_count: new_summary.error_count,
 8558                                        warning_count: new_summary.warning_count,
 8559                                    })
 8560                            }
 8561                            None => {
 8562                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8563                                    project_id,
 8564                                    worktree_id: worktree_id.to_proto(),
 8565                                    summary: Some(proto::DiagnosticSummary {
 8566                                        path: project_path.path.as_ref().to_proto(),
 8567                                        language_server_id: server_id.0 as u64,
 8568                                        error_count: new_summary.error_count,
 8569                                        warning_count: new_summary.warning_count,
 8570                                    }),
 8571                                    more_summaries: Vec::new(),
 8572                                })
 8573                            }
 8574                        }
 8575                    }
 8576                    updated_diagnostics_paths
 8577                        .entry(server_id)
 8578                        .or_insert_with(Vec::new)
 8579                        .push(project_path);
 8580                }
 8581                ControlFlow::Break(()) => {}
 8582            }
 8583        }
 8584
 8585        if let Some((diagnostics_summary, (downstream_client, _))) =
 8586            diagnostics_summary.zip(self.downstream_client.as_ref())
 8587        {
 8588            downstream_client.send(diagnostics_summary).log_err();
 8589        }
 8590        for (server_id, paths) in updated_diagnostics_paths {
 8591            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8592        }
 8593        Ok(())
 8594    }
 8595
 8596    fn update_worktree_diagnostics(
 8597        &mut self,
 8598        worktree_id: WorktreeId,
 8599        server_id: LanguageServerId,
 8600        path_in_worktree: Arc<RelPath>,
 8601        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8602        _: &mut Context<Worktree>,
 8603    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8604        let local = match &mut self.mode {
 8605            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8606            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8607        };
 8608
 8609        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8610        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8611        let summaries_by_server_id = summaries_for_tree
 8612            .entry(path_in_worktree.clone())
 8613            .or_default();
 8614
 8615        let old_summary = summaries_by_server_id
 8616            .remove(&server_id)
 8617            .unwrap_or_default();
 8618
 8619        let new_summary = DiagnosticSummary::new(&diagnostics);
 8620        if diagnostics.is_empty() {
 8621            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8622            {
 8623                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8624                    diagnostics_by_server_id.remove(ix);
 8625                }
 8626                if diagnostics_by_server_id.is_empty() {
 8627                    diagnostics_for_tree.remove(&path_in_worktree);
 8628                }
 8629            }
 8630        } else {
 8631            summaries_by_server_id.insert(server_id, new_summary);
 8632            let diagnostics_by_server_id = diagnostics_for_tree
 8633                .entry(path_in_worktree.clone())
 8634                .or_default();
 8635            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8636                Ok(ix) => {
 8637                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8638                }
 8639                Err(ix) => {
 8640                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8641                }
 8642            }
 8643        }
 8644
 8645        if !old_summary.is_empty() || !new_summary.is_empty() {
 8646            if let Some((_, project_id)) = &self.downstream_client {
 8647                Ok(ControlFlow::Continue(Some((
 8648                    *project_id,
 8649                    proto::DiagnosticSummary {
 8650                        path: path_in_worktree.to_proto(),
 8651                        language_server_id: server_id.0 as u64,
 8652                        error_count: new_summary.error_count as u32,
 8653                        warning_count: new_summary.warning_count as u32,
 8654                    },
 8655                ))))
 8656            } else {
 8657                Ok(ControlFlow::Continue(None))
 8658            }
 8659        } else {
 8660            Ok(ControlFlow::Break(()))
 8661        }
 8662    }
 8663
 8664    pub fn open_buffer_for_symbol(
 8665        &mut self,
 8666        symbol: &Symbol,
 8667        cx: &mut Context<Self>,
 8668    ) -> Task<Result<Entity<Buffer>>> {
 8669        if let Some((client, project_id)) = self.upstream_client() {
 8670            let request = client.request(proto::OpenBufferForSymbol {
 8671                project_id,
 8672                symbol: Some(Self::serialize_symbol(symbol)),
 8673            });
 8674            cx.spawn(async move |this, cx| {
 8675                let response = request.await?;
 8676                let buffer_id = BufferId::new(response.buffer_id)?;
 8677                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8678                    .await
 8679            })
 8680        } else if let Some(local) = self.as_local() {
 8681            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8682                seed.worktree_id == symbol.source_worktree_id
 8683                    && state.id == symbol.source_language_server_id
 8684                    && symbol.language_server_name == seed.name
 8685            });
 8686            if !is_valid {
 8687                return Task::ready(Err(anyhow!(
 8688                    "language server for worktree and language not found"
 8689                )));
 8690            };
 8691
 8692            let symbol_abs_path = match &symbol.path {
 8693                SymbolLocation::InProject(project_path) => self
 8694                    .worktree_store
 8695                    .read(cx)
 8696                    .absolutize(&project_path, cx)
 8697                    .context("no such worktree"),
 8698                SymbolLocation::OutsideProject {
 8699                    abs_path,
 8700                    signature: _,
 8701                } => Ok(abs_path.to_path_buf()),
 8702            };
 8703            let symbol_abs_path = match symbol_abs_path {
 8704                Ok(abs_path) => abs_path,
 8705                Err(err) => return Task::ready(Err(err)),
 8706            };
 8707            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8708                uri
 8709            } else {
 8710                return Task::ready(Err(anyhow!("invalid symbol path")));
 8711            };
 8712
 8713            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8714        } else {
 8715            Task::ready(Err(anyhow!("no upstream client or local store")))
 8716        }
 8717    }
 8718
 8719    pub(crate) fn open_local_buffer_via_lsp(
 8720        &mut self,
 8721        abs_path: lsp::Uri,
 8722        language_server_id: LanguageServerId,
 8723        cx: &mut Context<Self>,
 8724    ) -> Task<Result<Entity<Buffer>>> {
 8725        let path_style = self.worktree_store.read(cx).path_style();
 8726        cx.spawn(async move |lsp_store, cx| {
 8727            // Escape percent-encoded string.
 8728            let current_scheme = abs_path.scheme().to_owned();
 8729            // Uri is immutable, so we can't modify the scheme
 8730
 8731            let abs_path = abs_path
 8732                .to_file_path_ext(path_style)
 8733                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8734            let p = abs_path.clone();
 8735            let yarn_worktree = lsp_store
 8736                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8737                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8738                        cx.spawn(async move |this, cx| {
 8739                            let t = this
 8740                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8741                                .ok()?;
 8742                            t.await
 8743                        })
 8744                    }),
 8745                    None => Task::ready(None),
 8746                })?
 8747                .await;
 8748            let (worktree_root_target, known_relative_path) =
 8749                if let Some((zip_root, relative_path)) = yarn_worktree {
 8750                    (zip_root, Some(relative_path))
 8751                } else {
 8752                    (Arc::<Path>::from(abs_path.as_path()), None)
 8753                };
 8754            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8755                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8756                    worktree_store.find_worktree(&worktree_root_target, cx)
 8757                })
 8758            })?;
 8759            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8760                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8761                (result.0, relative_path, None)
 8762            } else {
 8763                let worktree = lsp_store
 8764                    .update(cx, |lsp_store, cx| {
 8765                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8766                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8767                        })
 8768                    })?
 8769                    .await?;
 8770                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8771                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8772                    lsp_store
 8773                        .update(cx, |lsp_store, cx| {
 8774                            if let Some(local) = lsp_store.as_local_mut() {
 8775                                local.register_language_server_for_invisible_worktree(
 8776                                    &worktree,
 8777                                    language_server_id,
 8778                                    cx,
 8779                                )
 8780                            }
 8781                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8782                                Some(status) => status.worktree,
 8783                                None => None,
 8784                            }
 8785                        })
 8786                        .ok()
 8787                        .flatten()
 8788                        .zip(Some(worktree_root.clone()))
 8789                } else {
 8790                    None
 8791                };
 8792                let relative_path = if let Some(known_path) = known_relative_path {
 8793                    known_path
 8794                } else {
 8795                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8796                        .into_arc()
 8797                };
 8798                (worktree, relative_path, source_ws)
 8799            };
 8800            let project_path = ProjectPath {
 8801                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8802                path: relative_path,
 8803            };
 8804            let buffer = lsp_store
 8805                .update(cx, |lsp_store, cx| {
 8806                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8807                        buffer_store.open_buffer(project_path, cx)
 8808                    })
 8809                })?
 8810                .await?;
 8811            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8812            if let Some((source_ws, worktree_root)) = source_ws {
 8813                buffer.update(cx, |buffer, cx| {
 8814                    let settings = WorktreeSettings::get(
 8815                        Some(
 8816                            (&ProjectPath {
 8817                                worktree_id: source_ws,
 8818                                path: Arc::from(RelPath::empty()),
 8819                            })
 8820                                .into(),
 8821                        ),
 8822                        cx,
 8823                    );
 8824                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8825                    if is_read_only {
 8826                        buffer.set_capability(Capability::ReadOnly, cx);
 8827                    }
 8828                });
 8829            }
 8830            Ok(buffer)
 8831        })
 8832    }
 8833
 8834    fn local_lsp_servers_for_buffer(
 8835        &self,
 8836        buffer: &Entity<Buffer>,
 8837        cx: &mut Context<Self>,
 8838    ) -> Vec<LanguageServerId> {
 8839        let Some(local) = self.as_local() else {
 8840            return Vec::new();
 8841        };
 8842
 8843        let snapshot = buffer.read(cx).snapshot();
 8844
 8845        buffer.update(cx, |buffer, cx| {
 8846            local
 8847                .language_servers_for_buffer(buffer, cx)
 8848                .map(|(_, server)| server.server_id())
 8849                .filter(|server_id| {
 8850                    self.as_local().is_none_or(|local| {
 8851                        local
 8852                            .buffers_opened_in_servers
 8853                            .get(&snapshot.remote_id())
 8854                            .is_some_and(|servers| servers.contains(server_id))
 8855                    })
 8856                })
 8857                .collect()
 8858        })
 8859    }
 8860
 8861    fn request_multiple_lsp_locally<P, R>(
 8862        &mut self,
 8863        buffer: &Entity<Buffer>,
 8864        position: Option<P>,
 8865        request: R,
 8866        cx: &mut Context<Self>,
 8867    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8868    where
 8869        P: ToOffset,
 8870        R: LspCommand + Clone,
 8871        <R::LspRequest as lsp::request::Request>::Result: Send,
 8872        <R::LspRequest as lsp::request::Request>::Params: Send,
 8873    {
 8874        let Some(local) = self.as_local() else {
 8875            return Task::ready(Vec::new());
 8876        };
 8877
 8878        let snapshot = buffer.read(cx).snapshot();
 8879        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8880
 8881        let server_ids = buffer.update(cx, |buffer, cx| {
 8882            local
 8883                .language_servers_for_buffer(buffer, cx)
 8884                .filter(|(adapter, _)| {
 8885                    scope
 8886                        .as_ref()
 8887                        .map(|scope| scope.language_allowed(&adapter.name))
 8888                        .unwrap_or(true)
 8889                })
 8890                .map(|(_, server)| server.server_id())
 8891                .filter(|server_id| {
 8892                    self.as_local().is_none_or(|local| {
 8893                        local
 8894                            .buffers_opened_in_servers
 8895                            .get(&snapshot.remote_id())
 8896                            .is_some_and(|servers| servers.contains(server_id))
 8897                    })
 8898                })
 8899                .collect::<Vec<_>>()
 8900        });
 8901
 8902        let mut response_results = server_ids
 8903            .into_iter()
 8904            .map(|server_id| {
 8905                let task = self.request_lsp(
 8906                    buffer.clone(),
 8907                    LanguageServerToQuery::Other(server_id),
 8908                    request.clone(),
 8909                    cx,
 8910                );
 8911                async move { (server_id, task.await) }
 8912            })
 8913            .collect::<FuturesUnordered<_>>();
 8914
 8915        cx.background_spawn(async move {
 8916            let mut responses = Vec::with_capacity(response_results.len());
 8917            while let Some((server_id, response_result)) = response_results.next().await {
 8918                match response_result {
 8919                    Ok(response) => responses.push((server_id, response)),
 8920                    // rust-analyzer likes to error with this when its still loading up
 8921                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8922                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8923                }
 8924            }
 8925            responses
 8926        })
 8927    }
 8928
 8929    async fn handle_lsp_get_completions(
 8930        this: Entity<Self>,
 8931        envelope: TypedEnvelope<proto::GetCompletions>,
 8932        mut cx: AsyncApp,
 8933    ) -> Result<proto::GetCompletionsResponse> {
 8934        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8935
 8936        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8937        let buffer_handle = this.update(&mut cx, |this, cx| {
 8938            this.buffer_store.read(cx).get_existing(buffer_id)
 8939        })?;
 8940        let request = GetCompletions::from_proto(
 8941            envelope.payload,
 8942            this.clone(),
 8943            buffer_handle.clone(),
 8944            cx.clone(),
 8945        )
 8946        .await?;
 8947
 8948        let server_to_query = match request.server_id {
 8949            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8950            None => LanguageServerToQuery::FirstCapable,
 8951        };
 8952
 8953        let response = this
 8954            .update(&mut cx, |this, cx| {
 8955                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8956            })
 8957            .await?;
 8958        this.update(&mut cx, |this, cx| {
 8959            Ok(GetCompletions::response_to_proto(
 8960                response,
 8961                this,
 8962                sender_id,
 8963                &buffer_handle.read(cx).version(),
 8964                cx,
 8965            ))
 8966        })
 8967    }
 8968
 8969    async fn handle_lsp_command<T: LspCommand>(
 8970        this: Entity<Self>,
 8971        envelope: TypedEnvelope<T::ProtoRequest>,
 8972        mut cx: AsyncApp,
 8973    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8974    where
 8975        <T::LspRequest as lsp::request::Request>::Params: Send,
 8976        <T::LspRequest as lsp::request::Request>::Result: Send,
 8977    {
 8978        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8979        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8980        let buffer_handle = this.update(&mut cx, |this, cx| {
 8981            this.buffer_store.read(cx).get_existing(buffer_id)
 8982        })?;
 8983        let request = T::from_proto(
 8984            envelope.payload,
 8985            this.clone(),
 8986            buffer_handle.clone(),
 8987            cx.clone(),
 8988        )
 8989        .await?;
 8990        let response = this
 8991            .update(&mut cx, |this, cx| {
 8992                this.request_lsp(
 8993                    buffer_handle.clone(),
 8994                    LanguageServerToQuery::FirstCapable,
 8995                    request,
 8996                    cx,
 8997                )
 8998            })
 8999            .await?;
 9000        this.update(&mut cx, |this, cx| {
 9001            Ok(T::response_to_proto(
 9002                response,
 9003                this,
 9004                sender_id,
 9005                &buffer_handle.read(cx).version(),
 9006                cx,
 9007            ))
 9008        })
 9009    }
 9010
 9011    async fn handle_lsp_query(
 9012        lsp_store: Entity<Self>,
 9013        envelope: TypedEnvelope<proto::LspQuery>,
 9014        mut cx: AsyncApp,
 9015    ) -> Result<proto::Ack> {
 9016        use proto::lsp_query::Request;
 9017        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9018        let lsp_query = envelope.payload;
 9019        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 9020        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 9021        match lsp_query.request.context("invalid LSP query request")? {
 9022            Request::GetReferences(get_references) => {
 9023                let position = get_references.position.clone().and_then(deserialize_anchor);
 9024                Self::query_lsp_locally::<GetReferences>(
 9025                    lsp_store,
 9026                    server_id,
 9027                    sender_id,
 9028                    lsp_request_id,
 9029                    get_references,
 9030                    position,
 9031                    &mut cx,
 9032                )
 9033                .await?;
 9034            }
 9035            Request::GetDocumentColor(get_document_color) => {
 9036                Self::query_lsp_locally::<GetDocumentColor>(
 9037                    lsp_store,
 9038                    server_id,
 9039                    sender_id,
 9040                    lsp_request_id,
 9041                    get_document_color,
 9042                    None,
 9043                    &mut cx,
 9044                )
 9045                .await?;
 9046            }
 9047            Request::GetFoldingRanges(get_folding_ranges) => {
 9048                Self::query_lsp_locally::<GetFoldingRanges>(
 9049                    lsp_store,
 9050                    server_id,
 9051                    sender_id,
 9052                    lsp_request_id,
 9053                    get_folding_ranges,
 9054                    None,
 9055                    &mut cx,
 9056                )
 9057                .await?;
 9058            }
 9059            Request::GetDocumentSymbols(get_document_symbols) => {
 9060                Self::query_lsp_locally::<GetDocumentSymbols>(
 9061                    lsp_store,
 9062                    server_id,
 9063                    sender_id,
 9064                    lsp_request_id,
 9065                    get_document_symbols,
 9066                    None,
 9067                    &mut cx,
 9068                )
 9069                .await?;
 9070            }
 9071            Request::GetHover(get_hover) => {
 9072                let position = get_hover.position.clone().and_then(deserialize_anchor);
 9073                Self::query_lsp_locally::<GetHover>(
 9074                    lsp_store,
 9075                    server_id,
 9076                    sender_id,
 9077                    lsp_request_id,
 9078                    get_hover,
 9079                    position,
 9080                    &mut cx,
 9081                )
 9082                .await?;
 9083            }
 9084            Request::GetCodeActions(get_code_actions) => {
 9085                Self::query_lsp_locally::<GetCodeActions>(
 9086                    lsp_store,
 9087                    server_id,
 9088                    sender_id,
 9089                    lsp_request_id,
 9090                    get_code_actions,
 9091                    None,
 9092                    &mut cx,
 9093                )
 9094                .await?;
 9095            }
 9096            Request::GetSignatureHelp(get_signature_help) => {
 9097                let position = get_signature_help
 9098                    .position
 9099                    .clone()
 9100                    .and_then(deserialize_anchor);
 9101                Self::query_lsp_locally::<GetSignatureHelp>(
 9102                    lsp_store,
 9103                    server_id,
 9104                    sender_id,
 9105                    lsp_request_id,
 9106                    get_signature_help,
 9107                    position,
 9108                    &mut cx,
 9109                )
 9110                .await?;
 9111            }
 9112            Request::GetCodeLens(get_code_lens) => {
 9113                Self::query_lsp_locally::<GetCodeLens>(
 9114                    lsp_store,
 9115                    server_id,
 9116                    sender_id,
 9117                    lsp_request_id,
 9118                    get_code_lens,
 9119                    None,
 9120                    &mut cx,
 9121                )
 9122                .await?;
 9123            }
 9124            Request::GetDefinition(get_definition) => {
 9125                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9126                Self::query_lsp_locally::<GetDefinitions>(
 9127                    lsp_store,
 9128                    server_id,
 9129                    sender_id,
 9130                    lsp_request_id,
 9131                    get_definition,
 9132                    position,
 9133                    &mut cx,
 9134                )
 9135                .await?;
 9136            }
 9137            Request::GetDeclaration(get_declaration) => {
 9138                let position = get_declaration
 9139                    .position
 9140                    .clone()
 9141                    .and_then(deserialize_anchor);
 9142                Self::query_lsp_locally::<GetDeclarations>(
 9143                    lsp_store,
 9144                    server_id,
 9145                    sender_id,
 9146                    lsp_request_id,
 9147                    get_declaration,
 9148                    position,
 9149                    &mut cx,
 9150                )
 9151                .await?;
 9152            }
 9153            Request::GetTypeDefinition(get_type_definition) => {
 9154                let position = get_type_definition
 9155                    .position
 9156                    .clone()
 9157                    .and_then(deserialize_anchor);
 9158                Self::query_lsp_locally::<GetTypeDefinitions>(
 9159                    lsp_store,
 9160                    server_id,
 9161                    sender_id,
 9162                    lsp_request_id,
 9163                    get_type_definition,
 9164                    position,
 9165                    &mut cx,
 9166                )
 9167                .await?;
 9168            }
 9169            Request::GetImplementation(get_implementation) => {
 9170                let position = get_implementation
 9171                    .position
 9172                    .clone()
 9173                    .and_then(deserialize_anchor);
 9174                Self::query_lsp_locally::<GetImplementations>(
 9175                    lsp_store,
 9176                    server_id,
 9177                    sender_id,
 9178                    lsp_request_id,
 9179                    get_implementation,
 9180                    position,
 9181                    &mut cx,
 9182                )
 9183                .await?;
 9184            }
 9185            Request::InlayHints(inlay_hints) => {
 9186                let query_start = inlay_hints
 9187                    .start
 9188                    .clone()
 9189                    .and_then(deserialize_anchor)
 9190                    .context("invalid inlay hints range start")?;
 9191                let query_end = inlay_hints
 9192                    .end
 9193                    .clone()
 9194                    .and_then(deserialize_anchor)
 9195                    .context("invalid inlay hints range end")?;
 9196                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9197                    &lsp_store,
 9198                    server_id,
 9199                    lsp_request_id,
 9200                    &inlay_hints,
 9201                    query_start..query_end,
 9202                    &mut cx,
 9203                )
 9204                .await
 9205                .context("preparing inlay hints request")?;
 9206                Self::query_lsp_locally::<InlayHints>(
 9207                    lsp_store,
 9208                    server_id,
 9209                    sender_id,
 9210                    lsp_request_id,
 9211                    inlay_hints,
 9212                    None,
 9213                    &mut cx,
 9214                )
 9215                .await
 9216                .context("querying for inlay hints")?
 9217            }
 9218            //////////////////////////////
 9219            // Below are LSP queries that need to fetch more data,
 9220            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 9221            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9222                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 9223                    &lsp_store,
 9224                    &get_document_diagnostics,
 9225                    &mut cx,
 9226                )
 9227                .await?;
 9228                lsp_store.update(&mut cx, |lsp_store, cx| {
 9229                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9230                    let key = LspKey {
 9231                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9232                        server_queried: server_id,
 9233                    };
 9234                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9235                    ) {
 9236                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9237                            lsp_requests.clear();
 9238                        };
 9239                    }
 9240
 9241                    lsp_data.lsp_requests.entry(key).or_default().insert(
 9242                        lsp_request_id,
 9243                        cx.spawn(async move |lsp_store, cx| {
 9244                            let diagnostics_pull = lsp_store
 9245                                .update(cx, |lsp_store, cx| {
 9246                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9247                                })
 9248                                .ok();
 9249                            if let Some(diagnostics_pull) = diagnostics_pull {
 9250                                match diagnostics_pull.await {
 9251                                    Ok(()) => {}
 9252                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9253                                };
 9254                            }
 9255                        }),
 9256                    );
 9257                });
 9258            }
 9259            Request::SemanticTokens(semantic_tokens) => {
 9260                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9261                    &lsp_store,
 9262                    &semantic_tokens,
 9263                    &mut cx,
 9264                )
 9265                .await?;
 9266                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9267                lsp_store.update(&mut cx, |lsp_store, cx| {
 9268                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9269                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9270                        let key = LspKey {
 9271                            request_type: TypeId::of::<SemanticTokensFull>(),
 9272                            server_queried: server_id,
 9273                        };
 9274                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9275                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9276                                lsp_requests.clear();
 9277                            };
 9278                        }
 9279
 9280                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9281                            lsp_request_id,
 9282                            cx.spawn(async move |lsp_store, cx| {
 9283                                let tokens_fetch = lsp_store
 9284                                    .update(cx, |lsp_store, cx| {
 9285                                        lsp_store
 9286                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9287                                    })
 9288                                    .ok();
 9289                                if let Some(tokens_fetch) = tokens_fetch {
 9290                                    let new_tokens = tokens_fetch.await;
 9291                                    if let Some(new_tokens) = new_tokens {
 9292                                        lsp_store
 9293                                            .update(cx, |lsp_store, cx| {
 9294                                                let response = new_tokens
 9295                                                    .into_iter()
 9296                                                    .map(|(server_id, response)| {
 9297                                                        (
 9298                                                            server_id.to_proto(),
 9299                                                            SemanticTokensFull::response_to_proto(
 9300                                                                response,
 9301                                                                lsp_store,
 9302                                                                sender_id,
 9303                                                                &buffer_version,
 9304                                                                cx,
 9305                                                            ),
 9306                                                        )
 9307                                                    })
 9308                                                    .collect::<HashMap<_, _>>();
 9309                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9310                                                    project_id,
 9311                                                    lsp_request_id,
 9312                                                    response,
 9313                                                ) {
 9314                                                    Ok(()) => {}
 9315                                                    Err(e) => {
 9316                                                        log::error!(
 9317                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9318                                                        )
 9319                                                    }
 9320                                                }
 9321                                            })
 9322                                            .ok();
 9323                                    }
 9324                                }
 9325                            }),
 9326                        );
 9327                    }
 9328                });
 9329            }
 9330        }
 9331        Ok(proto::Ack {})
 9332    }
 9333
 9334    async fn handle_lsp_query_response(
 9335        lsp_store: Entity<Self>,
 9336        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9337        cx: AsyncApp,
 9338    ) -> Result<()> {
 9339        lsp_store.read_with(&cx, |lsp_store, _| {
 9340            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9341                upstream_client.handle_lsp_response(envelope.clone());
 9342            }
 9343        });
 9344        Ok(())
 9345    }
 9346
 9347    async fn handle_apply_code_action(
 9348        this: Entity<Self>,
 9349        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9350        mut cx: AsyncApp,
 9351    ) -> Result<proto::ApplyCodeActionResponse> {
 9352        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9353        let action =
 9354            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9355        let apply_code_action = this.update(&mut cx, |this, cx| {
 9356            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9357            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9358            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9359        })?;
 9360
 9361        let project_transaction = apply_code_action.await?;
 9362        let project_transaction = this.update(&mut cx, |this, cx| {
 9363            this.buffer_store.update(cx, |buffer_store, cx| {
 9364                buffer_store.serialize_project_transaction_for_peer(
 9365                    project_transaction,
 9366                    sender_id,
 9367                    cx,
 9368                )
 9369            })
 9370        });
 9371        Ok(proto::ApplyCodeActionResponse {
 9372            transaction: Some(project_transaction),
 9373        })
 9374    }
 9375
 9376    async fn handle_register_buffer_with_language_servers(
 9377        this: Entity<Self>,
 9378        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9379        mut cx: AsyncApp,
 9380    ) -> Result<proto::Ack> {
 9381        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9382        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9383        this.update(&mut cx, |this, cx| {
 9384            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9385                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9386                    project_id: upstream_project_id,
 9387                    buffer_id: buffer_id.to_proto(),
 9388                    only_servers: envelope.payload.only_servers,
 9389                });
 9390            }
 9391
 9392            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9393                anyhow::bail!("buffer is not open");
 9394            };
 9395
 9396            let handle = this.register_buffer_with_language_servers(
 9397                &buffer,
 9398                envelope
 9399                    .payload
 9400                    .only_servers
 9401                    .into_iter()
 9402                    .filter_map(|selector| {
 9403                        Some(match selector.selector? {
 9404                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9405                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9406                            }
 9407                            proto::language_server_selector::Selector::Name(name) => {
 9408                                LanguageServerSelector::Name(LanguageServerName(
 9409                                    SharedString::from(name),
 9410                                ))
 9411                            }
 9412                        })
 9413                    })
 9414                    .collect(),
 9415                false,
 9416                cx,
 9417            );
 9418            // Pull diagnostics for the buffer even if it was already registered.
 9419            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9420            // but it's unclear if we need it.
 9421            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9422                .detach();
 9423            this.buffer_store().update(cx, |buffer_store, _| {
 9424                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9425            });
 9426
 9427            Ok(())
 9428        })?;
 9429        Ok(proto::Ack {})
 9430    }
 9431
 9432    async fn handle_rename_project_entry(
 9433        this: Entity<Self>,
 9434        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9435        mut cx: AsyncApp,
 9436    ) -> Result<proto::ProjectEntryResponse> {
 9437        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9438        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9439        let new_path =
 9440            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9441
 9442        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9443            .update(&mut cx, |this, cx| {
 9444                let (worktree, entry) = this
 9445                    .worktree_store
 9446                    .read(cx)
 9447                    .worktree_and_entry_for_id(entry_id, cx)?;
 9448                let new_worktree = this
 9449                    .worktree_store
 9450                    .read(cx)
 9451                    .worktree_for_id(new_worktree_id, cx)?;
 9452                Some((
 9453                    this.worktree_store.clone(),
 9454                    worktree,
 9455                    new_worktree,
 9456                    entry.clone(),
 9457                ))
 9458            })
 9459            .context("worktree not found")?;
 9460        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9461            (worktree.absolutize(&old_entry.path), worktree.id())
 9462        });
 9463        let new_abs_path =
 9464            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9465
 9466        let _transaction = Self::will_rename_entry(
 9467            this.downgrade(),
 9468            old_worktree_id,
 9469            &old_abs_path,
 9470            &new_abs_path,
 9471            old_entry.is_dir(),
 9472            cx.clone(),
 9473        )
 9474        .await;
 9475        let response = WorktreeStore::handle_rename_project_entry(
 9476            worktree_store,
 9477            envelope.payload,
 9478            cx.clone(),
 9479        )
 9480        .await;
 9481        this.read_with(&cx, |this, _| {
 9482            this.did_rename_entry(
 9483                old_worktree_id,
 9484                &old_abs_path,
 9485                &new_abs_path,
 9486                old_entry.is_dir(),
 9487            );
 9488        });
 9489        response
 9490    }
 9491
 9492    async fn handle_update_diagnostic_summary(
 9493        this: Entity<Self>,
 9494        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9495        mut cx: AsyncApp,
 9496    ) -> Result<()> {
 9497        this.update(&mut cx, |lsp_store, cx| {
 9498            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9499            let mut updated_diagnostics_paths = HashMap::default();
 9500            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9501            for message_summary in envelope
 9502                .payload
 9503                .summary
 9504                .into_iter()
 9505                .chain(envelope.payload.more_summaries)
 9506            {
 9507                let project_path = ProjectPath {
 9508                    worktree_id,
 9509                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9510                };
 9511                let path = project_path.path.clone();
 9512                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9513                let summary = DiagnosticSummary {
 9514                    error_count: message_summary.error_count as usize,
 9515                    warning_count: message_summary.warning_count as usize,
 9516                };
 9517
 9518                if summary.is_empty() {
 9519                    if let Some(worktree_summaries) =
 9520                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9521                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9522                    {
 9523                        summaries.remove(&server_id);
 9524                        if summaries.is_empty() {
 9525                            worktree_summaries.remove(&path);
 9526                        }
 9527                    }
 9528                } else {
 9529                    lsp_store
 9530                        .diagnostic_summaries
 9531                        .entry(worktree_id)
 9532                        .or_default()
 9533                        .entry(path)
 9534                        .or_default()
 9535                        .insert(server_id, summary);
 9536                }
 9537
 9538                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9539                    match &mut diagnostics_summary {
 9540                        Some(diagnostics_summary) => {
 9541                            diagnostics_summary
 9542                                .more_summaries
 9543                                .push(proto::DiagnosticSummary {
 9544                                    path: project_path.path.as_ref().to_proto(),
 9545                                    language_server_id: server_id.0 as u64,
 9546                                    error_count: summary.error_count as u32,
 9547                                    warning_count: summary.warning_count as u32,
 9548                                })
 9549                        }
 9550                        None => {
 9551                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9552                                project_id: *project_id,
 9553                                worktree_id: worktree_id.to_proto(),
 9554                                summary: Some(proto::DiagnosticSummary {
 9555                                    path: project_path.path.as_ref().to_proto(),
 9556                                    language_server_id: server_id.0 as u64,
 9557                                    error_count: summary.error_count as u32,
 9558                                    warning_count: summary.warning_count as u32,
 9559                                }),
 9560                                more_summaries: Vec::new(),
 9561                            })
 9562                        }
 9563                    }
 9564                }
 9565                updated_diagnostics_paths
 9566                    .entry(server_id)
 9567                    .or_insert_with(Vec::new)
 9568                    .push(project_path);
 9569            }
 9570
 9571            if let Some((diagnostics_summary, (downstream_client, _))) =
 9572                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9573            {
 9574                downstream_client.send(diagnostics_summary).log_err();
 9575            }
 9576            for (server_id, paths) in updated_diagnostics_paths {
 9577                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9578            }
 9579            Ok(())
 9580        })
 9581    }
 9582
 9583    async fn handle_start_language_server(
 9584        lsp_store: Entity<Self>,
 9585        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9586        mut cx: AsyncApp,
 9587    ) -> Result<()> {
 9588        let server = envelope.payload.server.context("invalid server")?;
 9589        let server_capabilities =
 9590            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9591                .with_context(|| {
 9592                    format!(
 9593                        "incorrect server capabilities {}",
 9594                        envelope.payload.capabilities
 9595                    )
 9596                })?;
 9597        lsp_store.update(&mut cx, |lsp_store, cx| {
 9598            let server_id = LanguageServerId(server.id as usize);
 9599            let server_name = LanguageServerName::from_proto(server.name.clone());
 9600            lsp_store
 9601                .lsp_server_capabilities
 9602                .insert(server_id, server_capabilities);
 9603            lsp_store.language_server_statuses.insert(
 9604                server_id,
 9605                LanguageServerStatus {
 9606                    name: server_name.clone(),
 9607                    server_version: None,
 9608                    server_readable_version: None,
 9609                    pending_work: Default::default(),
 9610                    has_pending_diagnostic_updates: false,
 9611                    progress_tokens: Default::default(),
 9612                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9613                    binary: None,
 9614                    configuration: None,
 9615                    workspace_folders: BTreeSet::new(),
 9616                    process_id: None,
 9617                },
 9618            );
 9619            cx.emit(LspStoreEvent::LanguageServerAdded(
 9620                server_id,
 9621                server_name,
 9622                server.worktree_id.map(WorktreeId::from_proto),
 9623            ));
 9624            cx.notify();
 9625        });
 9626        Ok(())
 9627    }
 9628
 9629    async fn handle_update_language_server(
 9630        lsp_store: Entity<Self>,
 9631        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9632        mut cx: AsyncApp,
 9633    ) -> Result<()> {
 9634        lsp_store.update(&mut cx, |lsp_store, cx| {
 9635            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9636
 9637            match envelope.payload.variant.context("invalid variant")? {
 9638                proto::update_language_server::Variant::WorkStart(payload) => {
 9639                    lsp_store.on_lsp_work_start(
 9640                        language_server_id,
 9641                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9642                            .context("invalid progress token value")?,
 9643                        LanguageServerProgress {
 9644                            title: payload.title,
 9645                            is_disk_based_diagnostics_progress: false,
 9646                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9647                            message: payload.message,
 9648                            percentage: payload.percentage.map(|p| p as usize),
 9649                            last_update_at: cx.background_executor().now(),
 9650                        },
 9651                        cx,
 9652                    );
 9653                }
 9654                proto::update_language_server::Variant::WorkProgress(payload) => {
 9655                    lsp_store.on_lsp_work_progress(
 9656                        language_server_id,
 9657                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9658                            .context("invalid progress token value")?,
 9659                        LanguageServerProgress {
 9660                            title: None,
 9661                            is_disk_based_diagnostics_progress: false,
 9662                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9663                            message: payload.message,
 9664                            percentage: payload.percentage.map(|p| p as usize),
 9665                            last_update_at: cx.background_executor().now(),
 9666                        },
 9667                        cx,
 9668                    );
 9669                }
 9670
 9671                proto::update_language_server::Variant::WorkEnd(payload) => {
 9672                    lsp_store.on_lsp_work_end(
 9673                        language_server_id,
 9674                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9675                            .context("invalid progress token value")?,
 9676                        cx,
 9677                    );
 9678                }
 9679
 9680                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9681                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9682                }
 9683
 9684                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9685                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9686                }
 9687
 9688                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9689                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9690                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9691                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9692                        language_server_id,
 9693                        name: envelope
 9694                            .payload
 9695                            .server_name
 9696                            .map(SharedString::new)
 9697                            .map(LanguageServerName),
 9698                        message: non_lsp,
 9699                    });
 9700                }
 9701            }
 9702
 9703            Ok(())
 9704        })
 9705    }
 9706
 9707    async fn handle_language_server_log(
 9708        this: Entity<Self>,
 9709        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9710        mut cx: AsyncApp,
 9711    ) -> Result<()> {
 9712        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9713        let log_type = envelope
 9714            .payload
 9715            .log_type
 9716            .map(LanguageServerLogType::from_proto)
 9717            .context("invalid language server log type")?;
 9718
 9719        let message = envelope.payload.message;
 9720
 9721        this.update(&mut cx, |_, cx| {
 9722            cx.emit(LspStoreEvent::LanguageServerLog(
 9723                language_server_id,
 9724                log_type,
 9725                message,
 9726            ));
 9727        });
 9728        Ok(())
 9729    }
 9730
 9731    async fn handle_lsp_ext_cancel_flycheck(
 9732        lsp_store: Entity<Self>,
 9733        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9734        cx: AsyncApp,
 9735    ) -> Result<proto::Ack> {
 9736        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9737        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9738            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9739                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9740            } else {
 9741                None
 9742            }
 9743        });
 9744        if let Some(task) = task {
 9745            task.context("handling lsp ext cancel flycheck")?;
 9746        }
 9747
 9748        Ok(proto::Ack {})
 9749    }
 9750
 9751    async fn handle_lsp_ext_run_flycheck(
 9752        lsp_store: Entity<Self>,
 9753        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9754        mut cx: AsyncApp,
 9755    ) -> Result<proto::Ack> {
 9756        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9757        lsp_store.update(&mut cx, |lsp_store, cx| {
 9758            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9759                let text_document = if envelope.payload.current_file_only {
 9760                    let buffer_id = envelope
 9761                        .payload
 9762                        .buffer_id
 9763                        .map(|id| BufferId::new(id))
 9764                        .transpose()?;
 9765                    buffer_id
 9766                        .and_then(|buffer_id| {
 9767                            lsp_store
 9768                                .buffer_store()
 9769                                .read(cx)
 9770                                .get(buffer_id)
 9771                                .and_then(|buffer| {
 9772                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9773                                })
 9774                                .map(|path| make_text_document_identifier(&path))
 9775                        })
 9776                        .transpose()?
 9777                } else {
 9778                    None
 9779                };
 9780                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9781                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9782                )?;
 9783            }
 9784            anyhow::Ok(())
 9785        })?;
 9786
 9787        Ok(proto::Ack {})
 9788    }
 9789
 9790    async fn handle_lsp_ext_clear_flycheck(
 9791        lsp_store: Entity<Self>,
 9792        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9793        cx: AsyncApp,
 9794    ) -> Result<proto::Ack> {
 9795        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9796        lsp_store.read_with(&cx, |lsp_store, _| {
 9797            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9798                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9799            } else {
 9800                None
 9801            }
 9802        });
 9803
 9804        Ok(proto::Ack {})
 9805    }
 9806
 9807    pub fn disk_based_diagnostics_started(
 9808        &mut self,
 9809        language_server_id: LanguageServerId,
 9810        cx: &mut Context<Self>,
 9811    ) {
 9812        if let Some(language_server_status) =
 9813            self.language_server_statuses.get_mut(&language_server_id)
 9814        {
 9815            language_server_status.has_pending_diagnostic_updates = true;
 9816        }
 9817
 9818        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9819        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9820            language_server_id,
 9821            name: self
 9822                .language_server_adapter_for_id(language_server_id)
 9823                .map(|adapter| adapter.name()),
 9824            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9825                Default::default(),
 9826            ),
 9827        })
 9828    }
 9829
 9830    pub fn disk_based_diagnostics_finished(
 9831        &mut self,
 9832        language_server_id: LanguageServerId,
 9833        cx: &mut Context<Self>,
 9834    ) {
 9835        if let Some(language_server_status) =
 9836            self.language_server_statuses.get_mut(&language_server_id)
 9837        {
 9838            language_server_status.has_pending_diagnostic_updates = false;
 9839        }
 9840
 9841        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9842        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9843            language_server_id,
 9844            name: self
 9845                .language_server_adapter_for_id(language_server_id)
 9846                .map(|adapter| adapter.name()),
 9847            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9848                Default::default(),
 9849            ),
 9850        })
 9851    }
 9852
 9853    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9854    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9855    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9856    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9857    // the language server might take some time to publish diagnostics.
 9858    fn simulate_disk_based_diagnostics_events_if_needed(
 9859        &mut self,
 9860        language_server_id: LanguageServerId,
 9861        cx: &mut Context<Self>,
 9862    ) {
 9863        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9864
 9865        let Some(LanguageServerState::Running {
 9866            simulate_disk_based_diagnostics_completion,
 9867            adapter,
 9868            ..
 9869        }) = self
 9870            .as_local_mut()
 9871            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9872        else {
 9873            return;
 9874        };
 9875
 9876        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9877            return;
 9878        }
 9879
 9880        let prev_task =
 9881            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9882                cx.background_executor()
 9883                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9884                    .await;
 9885
 9886                this.update(cx, |this, cx| {
 9887                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9888
 9889                    if let Some(LanguageServerState::Running {
 9890                        simulate_disk_based_diagnostics_completion,
 9891                        ..
 9892                    }) = this.as_local_mut().and_then(|local_store| {
 9893                        local_store.language_servers.get_mut(&language_server_id)
 9894                    }) {
 9895                        *simulate_disk_based_diagnostics_completion = None;
 9896                    }
 9897                })
 9898                .ok();
 9899            }));
 9900
 9901        if prev_task.is_none() {
 9902            self.disk_based_diagnostics_started(language_server_id, cx);
 9903        }
 9904    }
 9905
 9906    pub fn language_server_statuses(
 9907        &self,
 9908    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9909        self.language_server_statuses
 9910            .iter()
 9911            .map(|(key, value)| (*key, value))
 9912    }
 9913
 9914    pub(super) fn did_rename_entry(
 9915        &self,
 9916        worktree_id: WorktreeId,
 9917        old_path: &Path,
 9918        new_path: &Path,
 9919        is_dir: bool,
 9920    ) {
 9921        maybe!({
 9922            let local_store = self.as_local()?;
 9923
 9924            let old_uri = lsp::Uri::from_file_path(old_path)
 9925                .ok()
 9926                .map(|uri| uri.to_string())?;
 9927            let new_uri = lsp::Uri::from_file_path(new_path)
 9928                .ok()
 9929                .map(|uri| uri.to_string())?;
 9930
 9931            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9932                let Some(filter) = local_store
 9933                    .language_server_paths_watched_for_rename
 9934                    .get(&language_server.server_id())
 9935                else {
 9936                    continue;
 9937                };
 9938
 9939                if filter.should_send_did_rename(&old_uri, is_dir) {
 9940                    language_server
 9941                        .notify::<DidRenameFiles>(RenameFilesParams {
 9942                            files: vec![FileRename {
 9943                                old_uri: old_uri.clone(),
 9944                                new_uri: new_uri.clone(),
 9945                            }],
 9946                        })
 9947                        .ok();
 9948                }
 9949            }
 9950            Some(())
 9951        });
 9952    }
 9953
 9954    pub(super) fn will_rename_entry(
 9955        this: WeakEntity<Self>,
 9956        worktree_id: WorktreeId,
 9957        old_path: &Path,
 9958        new_path: &Path,
 9959        is_dir: bool,
 9960        cx: AsyncApp,
 9961    ) -> Task<ProjectTransaction> {
 9962        let old_uri = lsp::Uri::from_file_path(old_path)
 9963            .ok()
 9964            .map(|uri| uri.to_string());
 9965        let new_uri = lsp::Uri::from_file_path(new_path)
 9966            .ok()
 9967            .map(|uri| uri.to_string());
 9968        cx.spawn(async move |cx| {
 9969            let mut tasks = vec![];
 9970            this.update(cx, |this, cx| {
 9971                let local_store = this.as_local()?;
 9972                let old_uri = old_uri?;
 9973                let new_uri = new_uri?;
 9974                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9975                    let Some(filter) = local_store
 9976                        .language_server_paths_watched_for_rename
 9977                        .get(&language_server.server_id())
 9978                    else {
 9979                        continue;
 9980                    };
 9981
 9982                    if !filter.should_send_will_rename(&old_uri, is_dir) {
 9983                        continue;
 9984                    }
 9985                    let request_timeout = ProjectSettings::get_global(cx)
 9986                        .global_lsp_settings
 9987                        .get_request_timeout();
 9988
 9989                    let apply_edit = cx.spawn({
 9990                        let old_uri = old_uri.clone();
 9991                        let new_uri = new_uri.clone();
 9992                        let language_server = language_server.clone();
 9993                        async move |this, cx| {
 9994                            let edit = language_server
 9995                                .request::<WillRenameFiles>(
 9996                                    RenameFilesParams {
 9997                                        files: vec![FileRename { old_uri, new_uri }],
 9998                                    },
 9999                                    request_timeout,
10000                                )
10001                                .await
10002                                .into_response()
10003                                .context("will rename files")
10004                                .log_err()
10005                                .flatten()?;
10006
10007                            LocalLspStore::deserialize_workspace_edit(
10008                                this.upgrade()?,
10009                                edit,
10010                                false,
10011                                language_server.clone(),
10012                                cx,
10013                            )
10014                            .await
10015                            .ok()
10016                        }
10017                    });
10018                    tasks.push(apply_edit);
10019                }
10020                Some(())
10021            })
10022            .ok()
10023            .flatten();
10024            let mut merged_transaction = ProjectTransaction::default();
10025            for task in tasks {
10026                // Await on tasks sequentially so that the order of application of edits is deterministic
10027                // (at least with regards to the order of registration of language servers)
10028                if let Some(transaction) = task.await {
10029                    for (buffer, buffer_transaction) in transaction.0 {
10030                        merged_transaction.0.insert(buffer, buffer_transaction);
10031                    }
10032                }
10033            }
10034            merged_transaction
10035        })
10036    }
10037
10038    fn lsp_notify_abs_paths_changed(
10039        &mut self,
10040        server_id: LanguageServerId,
10041        changes: Vec<PathEvent>,
10042    ) {
10043        maybe!({
10044            let server = self.language_server_for_id(server_id)?;
10045            let changes = changes
10046                .into_iter()
10047                .filter_map(|event| {
10048                    let typ = match event.kind? {
10049                        PathEventKind::Created => lsp::FileChangeType::CREATED,
10050                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
10051                        PathEventKind::Changed | PathEventKind::Rescan => {
10052                            lsp::FileChangeType::CHANGED
10053                        }
10054                    };
10055                    Some(lsp::FileEvent {
10056                        uri: file_path_to_lsp_url(&event.path).log_err()?,
10057                        typ,
10058                    })
10059                })
10060                .collect::<Vec<_>>();
10061            if !changes.is_empty() {
10062                server
10063                    .notify::<lsp::notification::DidChangeWatchedFiles>(
10064                        lsp::DidChangeWatchedFilesParams { changes },
10065                    )
10066                    .ok();
10067            }
10068            Some(())
10069        });
10070    }
10071
10072    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
10073        self.as_local()?.language_server_for_id(id)
10074    }
10075
10076    fn on_lsp_progress(
10077        &mut self,
10078        progress_params: lsp::ProgressParams,
10079        language_server_id: LanguageServerId,
10080        disk_based_diagnostics_progress_token: Option<String>,
10081        cx: &mut Context<Self>,
10082    ) {
10083        match progress_params.value {
10084            lsp::ProgressParamsValue::WorkDone(progress) => {
10085                self.handle_work_done_progress(
10086                    progress,
10087                    language_server_id,
10088                    disk_based_diagnostics_progress_token,
10089                    ProgressToken::from_lsp(progress_params.token),
10090                    cx,
10091                );
10092            }
10093            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
10094                let registration_id = match progress_params.token {
10095                    lsp::NumberOrString::Number(_) => None,
10096                    lsp::NumberOrString::String(token) => token
10097                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
10098                        .map(|(_, id)| id.to_owned()),
10099                };
10100                if let Some(LanguageServerState::Running {
10101                    workspace_diagnostics_refresh_tasks,
10102                    ..
10103                }) = self
10104                    .as_local_mut()
10105                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
10106                    && let Some(workspace_diagnostics) =
10107                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
10108                {
10109                    workspace_diagnostics.progress_tx.try_send(()).ok();
10110                    self.apply_workspace_diagnostic_report(
10111                        language_server_id,
10112                        report,
10113                        registration_id.map(SharedString::from),
10114                        cx,
10115                    )
10116                }
10117            }
10118        }
10119    }
10120
10121    fn handle_work_done_progress(
10122        &mut self,
10123        progress: lsp::WorkDoneProgress,
10124        language_server_id: LanguageServerId,
10125        disk_based_diagnostics_progress_token: Option<String>,
10126        token: ProgressToken,
10127        cx: &mut Context<Self>,
10128    ) {
10129        let language_server_status =
10130            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10131                status
10132            } else {
10133                return;
10134            };
10135
10136        if !language_server_status.progress_tokens.contains(&token) {
10137            return;
10138        }
10139
10140        let is_disk_based_diagnostics_progress =
10141            if let (Some(disk_based_token), ProgressToken::String(token)) =
10142                (&disk_based_diagnostics_progress_token, &token)
10143            {
10144                token.starts_with(disk_based_token)
10145            } else {
10146                false
10147            };
10148
10149        match progress {
10150            lsp::WorkDoneProgress::Begin(report) => {
10151                if is_disk_based_diagnostics_progress {
10152                    self.disk_based_diagnostics_started(language_server_id, cx);
10153                }
10154                self.on_lsp_work_start(
10155                    language_server_id,
10156                    token.clone(),
10157                    LanguageServerProgress {
10158                        title: Some(report.title),
10159                        is_disk_based_diagnostics_progress,
10160                        is_cancellable: report.cancellable.unwrap_or(false),
10161                        message: report.message.clone(),
10162                        percentage: report.percentage.map(|p| p as usize),
10163                        last_update_at: cx.background_executor().now(),
10164                    },
10165                    cx,
10166                );
10167            }
10168            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10169                language_server_id,
10170                token,
10171                LanguageServerProgress {
10172                    title: None,
10173                    is_disk_based_diagnostics_progress,
10174                    is_cancellable: report.cancellable.unwrap_or(false),
10175                    message: report.message,
10176                    percentage: report.percentage.map(|p| p as usize),
10177                    last_update_at: cx.background_executor().now(),
10178                },
10179                cx,
10180            ),
10181            lsp::WorkDoneProgress::End(_) => {
10182                language_server_status.progress_tokens.remove(&token);
10183                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10184                if is_disk_based_diagnostics_progress {
10185                    self.disk_based_diagnostics_finished(language_server_id, cx);
10186                }
10187            }
10188        }
10189    }
10190
10191    fn on_lsp_work_start(
10192        &mut self,
10193        language_server_id: LanguageServerId,
10194        token: ProgressToken,
10195        progress: LanguageServerProgress,
10196        cx: &mut Context<Self>,
10197    ) {
10198        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10199            status.pending_work.insert(token.clone(), progress.clone());
10200            cx.notify();
10201        }
10202        cx.emit(LspStoreEvent::LanguageServerUpdate {
10203            language_server_id,
10204            name: self
10205                .language_server_adapter_for_id(language_server_id)
10206                .map(|adapter| adapter.name()),
10207            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10208                token: Some(token.to_proto()),
10209                title: progress.title,
10210                message: progress.message,
10211                percentage: progress.percentage.map(|p| p as u32),
10212                is_cancellable: Some(progress.is_cancellable),
10213            }),
10214        })
10215    }
10216
10217    fn on_lsp_work_progress(
10218        &mut self,
10219        language_server_id: LanguageServerId,
10220        token: ProgressToken,
10221        progress: LanguageServerProgress,
10222        cx: &mut Context<Self>,
10223    ) {
10224        let mut did_update = false;
10225        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10226            match status.pending_work.entry(token.clone()) {
10227                btree_map::Entry::Vacant(entry) => {
10228                    entry.insert(progress.clone());
10229                    did_update = true;
10230                }
10231                btree_map::Entry::Occupied(mut entry) => {
10232                    let entry = entry.get_mut();
10233                    if (progress.last_update_at - entry.last_update_at)
10234                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10235                    {
10236                        entry.last_update_at = progress.last_update_at;
10237                        if progress.message.is_some() {
10238                            entry.message = progress.message.clone();
10239                        }
10240                        if progress.percentage.is_some() {
10241                            entry.percentage = progress.percentage;
10242                        }
10243                        if progress.is_cancellable != entry.is_cancellable {
10244                            entry.is_cancellable = progress.is_cancellable;
10245                        }
10246                        did_update = true;
10247                    }
10248                }
10249            }
10250        }
10251
10252        if did_update {
10253            cx.emit(LspStoreEvent::LanguageServerUpdate {
10254                language_server_id,
10255                name: self
10256                    .language_server_adapter_for_id(language_server_id)
10257                    .map(|adapter| adapter.name()),
10258                message: proto::update_language_server::Variant::WorkProgress(
10259                    proto::LspWorkProgress {
10260                        token: Some(token.to_proto()),
10261                        message: progress.message,
10262                        percentage: progress.percentage.map(|p| p as u32),
10263                        is_cancellable: Some(progress.is_cancellable),
10264                    },
10265                ),
10266            })
10267        }
10268    }
10269
10270    fn on_lsp_work_end(
10271        &mut self,
10272        language_server_id: LanguageServerId,
10273        token: ProgressToken,
10274        cx: &mut Context<Self>,
10275    ) {
10276        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10277            if let Some(work) = status.pending_work.remove(&token)
10278                && !work.is_disk_based_diagnostics_progress
10279            {
10280                cx.emit(LspStoreEvent::RefreshInlayHints {
10281                    server_id: language_server_id,
10282                    request_id: None,
10283                });
10284            }
10285            cx.notify();
10286        }
10287
10288        cx.emit(LspStoreEvent::LanguageServerUpdate {
10289            language_server_id,
10290            name: self
10291                .language_server_adapter_for_id(language_server_id)
10292                .map(|adapter| adapter.name()),
10293            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10294                token: Some(token.to_proto()),
10295            }),
10296        })
10297    }
10298
10299    pub async fn handle_resolve_completion_documentation(
10300        this: Entity<Self>,
10301        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10302        mut cx: AsyncApp,
10303    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10304        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10305
10306        let completion = this
10307            .read_with(&cx, |this, cx| {
10308                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10309                let server = this
10310                    .language_server_for_id(id)
10311                    .with_context(|| format!("No language server {id}"))?;
10312
10313                let request_timeout = ProjectSettings::get_global(cx)
10314                    .global_lsp_settings
10315                    .get_request_timeout();
10316
10317                anyhow::Ok(cx.background_spawn(async move {
10318                    let can_resolve = server
10319                        .capabilities()
10320                        .completion_provider
10321                        .as_ref()
10322                        .and_then(|options| options.resolve_provider)
10323                        .unwrap_or(false);
10324                    if can_resolve {
10325                        server
10326                            .request::<lsp::request::ResolveCompletionItem>(
10327                                lsp_completion,
10328                                request_timeout,
10329                            )
10330                            .await
10331                            .into_response()
10332                            .context("resolve completion item")
10333                    } else {
10334                        anyhow::Ok(lsp_completion)
10335                    }
10336                }))
10337            })?
10338            .await?;
10339
10340        let mut documentation_is_markdown = false;
10341        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10342        let documentation = match completion.documentation {
10343            Some(lsp::Documentation::String(text)) => text,
10344
10345            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10346                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10347                value
10348            }
10349
10350            _ => String::new(),
10351        };
10352
10353        // If we have a new buffer_id, that means we're talking to a new client
10354        // and want to check for new text_edits in the completion too.
10355        let mut old_replace_start = None;
10356        let mut old_replace_end = None;
10357        let mut old_insert_start = None;
10358        let mut old_insert_end = None;
10359        let mut new_text = String::default();
10360        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10361            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10362                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10363                anyhow::Ok(buffer.read(cx).snapshot())
10364            })?;
10365
10366            if let Some(text_edit) = completion.text_edit.as_ref() {
10367                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10368
10369                if let Some(mut edit) = edit {
10370                    LineEnding::normalize(&mut edit.new_text);
10371
10372                    new_text = edit.new_text;
10373                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10374                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10375                    if let Some(insert_range) = edit.insert_range {
10376                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10377                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10378                    }
10379                }
10380            }
10381        }
10382
10383        Ok(proto::ResolveCompletionDocumentationResponse {
10384            documentation,
10385            documentation_is_markdown,
10386            old_replace_start,
10387            old_replace_end,
10388            new_text,
10389            lsp_completion,
10390            old_insert_start,
10391            old_insert_end,
10392        })
10393    }
10394
10395    async fn handle_on_type_formatting(
10396        this: Entity<Self>,
10397        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10398        mut cx: AsyncApp,
10399    ) -> Result<proto::OnTypeFormattingResponse> {
10400        let on_type_formatting = this.update(&mut cx, |this, cx| {
10401            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10402            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10403            let position = envelope
10404                .payload
10405                .position
10406                .and_then(deserialize_anchor)
10407                .context("invalid position")?;
10408            anyhow::Ok(this.apply_on_type_formatting(
10409                buffer,
10410                position,
10411                envelope.payload.trigger.clone(),
10412                cx,
10413            ))
10414        })?;
10415
10416        let transaction = on_type_formatting
10417            .await?
10418            .as_ref()
10419            .map(language::proto::serialize_transaction);
10420        Ok(proto::OnTypeFormattingResponse { transaction })
10421    }
10422
10423    async fn handle_pull_workspace_diagnostics(
10424        lsp_store: Entity<Self>,
10425        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10426        mut cx: AsyncApp,
10427    ) -> Result<proto::Ack> {
10428        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10429        lsp_store.update(&mut cx, |lsp_store, _| {
10430            lsp_store.pull_workspace_diagnostics(server_id);
10431        });
10432        Ok(proto::Ack {})
10433    }
10434
10435    async fn handle_open_buffer_for_symbol(
10436        this: Entity<Self>,
10437        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10438        mut cx: AsyncApp,
10439    ) -> Result<proto::OpenBufferForSymbolResponse> {
10440        let peer_id = envelope.original_sender_id().unwrap_or_default();
10441        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10442        let symbol = Self::deserialize_symbol(symbol)?;
10443        this.read_with(&cx, |this, _| {
10444            if let SymbolLocation::OutsideProject {
10445                abs_path,
10446                signature,
10447            } = &symbol.path
10448            {
10449                let new_signature = this.symbol_signature(&abs_path);
10450                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10451            }
10452            Ok(())
10453        })?;
10454        let buffer = this
10455            .update(&mut cx, |this, cx| {
10456                this.open_buffer_for_symbol(
10457                    &Symbol {
10458                        language_server_name: symbol.language_server_name,
10459                        source_worktree_id: symbol.source_worktree_id,
10460                        source_language_server_id: symbol.source_language_server_id,
10461                        path: symbol.path,
10462                        name: symbol.name,
10463                        kind: symbol.kind,
10464                        range: symbol.range,
10465                        label: CodeLabel::default(),
10466                        container_name: symbol.container_name,
10467                    },
10468                    cx,
10469                )
10470            })
10471            .await?;
10472
10473        this.update(&mut cx, |this, cx| {
10474            let is_private = buffer
10475                .read(cx)
10476                .file()
10477                .map(|f| f.is_private())
10478                .unwrap_or_default();
10479            if is_private {
10480                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10481            } else {
10482                this.buffer_store
10483                    .update(cx, |buffer_store, cx| {
10484                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10485                    })
10486                    .detach_and_log_err(cx);
10487                let buffer_id = buffer.read(cx).remote_id().to_proto();
10488                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10489            }
10490        })
10491    }
10492
10493    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10494        let mut hasher = Sha256::new();
10495        hasher.update(abs_path.to_string_lossy().as_bytes());
10496        hasher.update(self.nonce.to_be_bytes());
10497        hasher.finalize().as_slice().try_into().unwrap()
10498    }
10499
10500    pub async fn handle_get_project_symbols(
10501        this: Entity<Self>,
10502        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10503        mut cx: AsyncApp,
10504    ) -> Result<proto::GetProjectSymbolsResponse> {
10505        let symbols = this
10506            .update(&mut cx, |this, cx| {
10507                this.symbols(&envelope.payload.query, cx)
10508            })
10509            .await?;
10510
10511        Ok(proto::GetProjectSymbolsResponse {
10512            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10513        })
10514    }
10515
10516    pub async fn handle_restart_language_servers(
10517        this: Entity<Self>,
10518        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10519        mut cx: AsyncApp,
10520    ) -> Result<proto::Ack> {
10521        this.update(&mut cx, |lsp_store, cx| {
10522            let buffers =
10523                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10524            lsp_store.restart_language_servers_for_buffers(
10525                buffers,
10526                envelope
10527                    .payload
10528                    .only_servers
10529                    .into_iter()
10530                    .filter_map(|selector| {
10531                        Some(match selector.selector? {
10532                            proto::language_server_selector::Selector::ServerId(server_id) => {
10533                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10534                            }
10535                            proto::language_server_selector::Selector::Name(name) => {
10536                                LanguageServerSelector::Name(LanguageServerName(
10537                                    SharedString::from(name),
10538                                ))
10539                            }
10540                        })
10541                    })
10542                    .collect(),
10543                cx,
10544            );
10545        });
10546
10547        Ok(proto::Ack {})
10548    }
10549
10550    pub async fn handle_stop_language_servers(
10551        lsp_store: Entity<Self>,
10552        envelope: TypedEnvelope<proto::StopLanguageServers>,
10553        mut cx: AsyncApp,
10554    ) -> Result<proto::Ack> {
10555        lsp_store.update(&mut cx, |lsp_store, cx| {
10556            if envelope.payload.all
10557                && envelope.payload.also_servers.is_empty()
10558                && envelope.payload.buffer_ids.is_empty()
10559            {
10560                lsp_store.stop_all_language_servers(cx);
10561            } else {
10562                let buffers =
10563                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10564                lsp_store
10565                    .stop_language_servers_for_buffers(
10566                        buffers,
10567                        envelope
10568                            .payload
10569                            .also_servers
10570                            .into_iter()
10571                            .filter_map(|selector| {
10572                                Some(match selector.selector? {
10573                                    proto::language_server_selector::Selector::ServerId(
10574                                        server_id,
10575                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10576                                        server_id,
10577                                    )),
10578                                    proto::language_server_selector::Selector::Name(name) => {
10579                                        LanguageServerSelector::Name(LanguageServerName(
10580                                            SharedString::from(name),
10581                                        ))
10582                                    }
10583                                })
10584                            })
10585                            .collect(),
10586                        cx,
10587                    )
10588                    .detach_and_log_err(cx);
10589            }
10590        });
10591
10592        Ok(proto::Ack {})
10593    }
10594
10595    pub async fn handle_cancel_language_server_work(
10596        lsp_store: Entity<Self>,
10597        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10598        mut cx: AsyncApp,
10599    ) -> Result<proto::Ack> {
10600        lsp_store.update(&mut cx, |lsp_store, cx| {
10601            if let Some(work) = envelope.payload.work {
10602                match work {
10603                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10604                        let buffers =
10605                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10606                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10607                    }
10608                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10609                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10610                        let token = work
10611                            .token
10612                            .map(|token| {
10613                                ProgressToken::from_proto(token)
10614                                    .context("invalid work progress token")
10615                            })
10616                            .transpose()?;
10617                        lsp_store.cancel_language_server_work(server_id, token, cx);
10618                    }
10619                }
10620            }
10621            anyhow::Ok(())
10622        })?;
10623
10624        Ok(proto::Ack {})
10625    }
10626
10627    fn buffer_ids_to_buffers(
10628        &mut self,
10629        buffer_ids: impl Iterator<Item = u64>,
10630        cx: &mut Context<Self>,
10631    ) -> Vec<Entity<Buffer>> {
10632        buffer_ids
10633            .into_iter()
10634            .flat_map(|buffer_id| {
10635                self.buffer_store
10636                    .read(cx)
10637                    .get(BufferId::new(buffer_id).log_err()?)
10638            })
10639            .collect::<Vec<_>>()
10640    }
10641
10642    async fn handle_apply_additional_edits_for_completion(
10643        this: Entity<Self>,
10644        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10645        mut cx: AsyncApp,
10646    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10647        let (buffer, completion, all_commit_ranges) = this.update(&mut cx, |this, cx| {
10648            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10649            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10650            let completion = Self::deserialize_completion(
10651                envelope.payload.completion.context("invalid completion")?,
10652            )?;
10653            let all_commit_ranges = envelope
10654                .payload
10655                .all_commit_ranges
10656                .into_iter()
10657                .map(language::proto::deserialize_anchor_range)
10658                .collect::<Result<Vec<_>, _>>()?;
10659            anyhow::Ok((buffer, completion, all_commit_ranges))
10660        })?;
10661
10662        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10663            this.apply_additional_edits_for_completion(
10664                buffer,
10665                Rc::new(RefCell::new(Box::new([Completion {
10666                    replace_range: completion.replace_range,
10667                    new_text: completion.new_text,
10668                    source: completion.source,
10669                    documentation: None,
10670                    label: CodeLabel::default(),
10671                    match_start: None,
10672                    snippet_deduplication_key: None,
10673                    insert_text_mode: None,
10674                    icon_path: None,
10675                    confirm: None,
10676                }]))),
10677                0,
10678                false,
10679                all_commit_ranges,
10680                cx,
10681            )
10682        });
10683
10684        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10685            transaction: apply_additional_edits
10686                .await?
10687                .as_ref()
10688                .map(language::proto::serialize_transaction),
10689        })
10690    }
10691
10692    pub fn last_formatting_failure(&self) -> Option<&str> {
10693        self.last_formatting_failure.as_deref()
10694    }
10695
10696    pub fn reset_last_formatting_failure(&mut self) {
10697        self.last_formatting_failure = None;
10698    }
10699
10700    pub fn environment_for_buffer(
10701        &self,
10702        buffer: &Entity<Buffer>,
10703        cx: &mut Context<Self>,
10704    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10705        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10706            environment.update(cx, |env, cx| {
10707                env.buffer_environment(buffer, &self.worktree_store, cx)
10708            })
10709        } else {
10710            Task::ready(None).shared()
10711        }
10712    }
10713
10714    pub fn format(
10715        &mut self,
10716        buffers: HashSet<Entity<Buffer>>,
10717        target: LspFormatTarget,
10718        push_to_history: bool,
10719        trigger: FormatTrigger,
10720        cx: &mut Context<Self>,
10721    ) -> Task<anyhow::Result<ProjectTransaction>> {
10722        let logger = zlog::scoped!("format");
10723        if self.as_local().is_some() {
10724            zlog::trace!(logger => "Formatting locally");
10725            let logger = zlog::scoped!(logger => "local");
10726            let buffers = buffers
10727                .into_iter()
10728                .map(|buffer_handle| {
10729                    let buffer = buffer_handle.read(cx);
10730                    let buffer_abs_path = File::from_dyn(buffer.file())
10731                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10732
10733                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10734                })
10735                .collect::<Vec<_>>();
10736
10737            cx.spawn(async move |lsp_store, cx| {
10738                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10739
10740                for (handle, abs_path, id) in buffers {
10741                    let env = lsp_store
10742                        .update(cx, |lsp_store, cx| {
10743                            lsp_store.environment_for_buffer(&handle, cx)
10744                        })?
10745                        .await;
10746
10747                    let ranges = match &target {
10748                        LspFormatTarget::Buffers => None,
10749                        LspFormatTarget::Ranges(ranges) => {
10750                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10751                        }
10752                    };
10753
10754                    formattable_buffers.push(FormattableBuffer {
10755                        handle,
10756                        abs_path,
10757                        env,
10758                        ranges,
10759                    });
10760                }
10761                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10762
10763                let format_timer = zlog::time!(logger => "Formatting buffers");
10764                let result = LocalLspStore::format_locally(
10765                    lsp_store.clone(),
10766                    formattable_buffers,
10767                    push_to_history,
10768                    trigger,
10769                    logger,
10770                    cx,
10771                )
10772                .await;
10773                format_timer.end();
10774
10775                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10776
10777                lsp_store.update(cx, |lsp_store, _| {
10778                    lsp_store.update_last_formatting_failure(&result);
10779                })?;
10780
10781                result
10782            })
10783        } else if let Some((client, project_id)) = self.upstream_client() {
10784            zlog::trace!(logger => "Formatting remotely");
10785            let logger = zlog::scoped!(logger => "remote");
10786
10787            let buffer_ranges = match &target {
10788                LspFormatTarget::Buffers => Vec::new(),
10789                LspFormatTarget::Ranges(ranges) => ranges
10790                    .iter()
10791                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10792                        buffer_id: buffer_id.to_proto(),
10793                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10794                    })
10795                    .collect(),
10796            };
10797
10798            let buffer_store = self.buffer_store();
10799            cx.spawn(async move |lsp_store, cx| {
10800                zlog::trace!(logger => "Sending remote format request");
10801                let request_timer = zlog::time!(logger => "remote format request");
10802                let result = client
10803                    .request(proto::FormatBuffers {
10804                        project_id,
10805                        trigger: trigger as i32,
10806                        buffer_ids: buffers
10807                            .iter()
10808                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10809                            .collect(),
10810                        buffer_ranges,
10811                    })
10812                    .await
10813                    .and_then(|result| result.transaction.context("missing transaction"));
10814                request_timer.end();
10815
10816                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10817
10818                lsp_store.update(cx, |lsp_store, _| {
10819                    lsp_store.update_last_formatting_failure(&result);
10820                })?;
10821
10822                let transaction_response = result?;
10823                let _timer = zlog::time!(logger => "deserializing project transaction");
10824                buffer_store
10825                    .update(cx, |buffer_store, cx| {
10826                        buffer_store.deserialize_project_transaction(
10827                            transaction_response,
10828                            push_to_history,
10829                            cx,
10830                        )
10831                    })
10832                    .await
10833            })
10834        } else {
10835            zlog::trace!(logger => "Not formatting");
10836            Task::ready(Ok(ProjectTransaction::default()))
10837        }
10838    }
10839
10840    async fn handle_format_buffers(
10841        this: Entity<Self>,
10842        envelope: TypedEnvelope<proto::FormatBuffers>,
10843        mut cx: AsyncApp,
10844    ) -> Result<proto::FormatBuffersResponse> {
10845        let sender_id = envelope.original_sender_id().unwrap_or_default();
10846        let format = this.update(&mut cx, |this, cx| {
10847            let mut buffers = HashSet::default();
10848            for buffer_id in &envelope.payload.buffer_ids {
10849                let buffer_id = BufferId::new(*buffer_id)?;
10850                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10851            }
10852
10853            let target = if envelope.payload.buffer_ranges.is_empty() {
10854                LspFormatTarget::Buffers
10855            } else {
10856                let mut ranges_map = BTreeMap::new();
10857                for buffer_range in &envelope.payload.buffer_ranges {
10858                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10859                    let ranges: Result<Vec<_>> = buffer_range
10860                        .ranges
10861                        .iter()
10862                        .map(|range| {
10863                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10864                        })
10865                        .collect();
10866                    ranges_map.insert(buffer_id, ranges?);
10867                }
10868                LspFormatTarget::Ranges(ranges_map)
10869            };
10870
10871            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10872            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10873        })?;
10874
10875        let project_transaction = format.await?;
10876        let project_transaction = this.update(&mut cx, |this, cx| {
10877            this.buffer_store.update(cx, |buffer_store, cx| {
10878                buffer_store.serialize_project_transaction_for_peer(
10879                    project_transaction,
10880                    sender_id,
10881                    cx,
10882                )
10883            })
10884        });
10885        Ok(proto::FormatBuffersResponse {
10886            transaction: Some(project_transaction),
10887        })
10888    }
10889
10890    async fn handle_apply_code_action_kind(
10891        this: Entity<Self>,
10892        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10893        mut cx: AsyncApp,
10894    ) -> Result<proto::ApplyCodeActionKindResponse> {
10895        let sender_id = envelope.original_sender_id().unwrap_or_default();
10896        let format = this.update(&mut cx, |this, cx| {
10897            let mut buffers = HashSet::default();
10898            for buffer_id in &envelope.payload.buffer_ids {
10899                let buffer_id = BufferId::new(*buffer_id)?;
10900                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10901            }
10902            let kind = match envelope.payload.kind.as_str() {
10903                "" => CodeActionKind::EMPTY,
10904                "quickfix" => CodeActionKind::QUICKFIX,
10905                "refactor" => CodeActionKind::REFACTOR,
10906                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10907                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10908                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10909                "source" => CodeActionKind::SOURCE,
10910                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10911                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10912                _ => anyhow::bail!(
10913                    "Invalid code action kind {}",
10914                    envelope.payload.kind.as_str()
10915                ),
10916            };
10917            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10918        })?;
10919
10920        let project_transaction = format.await?;
10921        let project_transaction = this.update(&mut cx, |this, cx| {
10922            this.buffer_store.update(cx, |buffer_store, cx| {
10923                buffer_store.serialize_project_transaction_for_peer(
10924                    project_transaction,
10925                    sender_id,
10926                    cx,
10927                )
10928            })
10929        });
10930        Ok(proto::ApplyCodeActionKindResponse {
10931            transaction: Some(project_transaction),
10932        })
10933    }
10934
10935    async fn shutdown_language_server(
10936        server_state: Option<LanguageServerState>,
10937        name: LanguageServerName,
10938        cx: &mut AsyncApp,
10939    ) {
10940        let server = match server_state {
10941            Some(LanguageServerState::Starting { startup, .. }) => {
10942                let mut timer = cx
10943                    .background_executor()
10944                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10945                    .fuse();
10946
10947                select! {
10948                    server = startup.fuse() => server,
10949                    () = timer => {
10950                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10951                        None
10952                    },
10953                }
10954            }
10955
10956            Some(LanguageServerState::Running { server, .. }) => Some(server),
10957
10958            None => None,
10959        };
10960
10961        let Some(server) = server else { return };
10962        if let Some(shutdown) = server.shutdown() {
10963            shutdown.await;
10964        }
10965    }
10966
10967    // Returns a list of all of the worktrees which no longer have a language server and the root path
10968    // for the stopped server
10969    fn stop_local_language_server(
10970        &mut self,
10971        server_id: LanguageServerId,
10972        cx: &mut Context<Self>,
10973    ) -> Task<()> {
10974        let local = match &mut self.mode {
10975            LspStoreMode::Local(local) => local,
10976            _ => {
10977                return Task::ready(());
10978            }
10979        };
10980
10981        // Remove this server ID from all entries in the given worktree.
10982        local
10983            .language_server_ids
10984            .retain(|_, state| state.id != server_id);
10985        self.buffer_store.update(cx, |buffer_store, cx| {
10986            for buffer in buffer_store.buffers() {
10987                buffer.update(cx, |buffer, cx| {
10988                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10989                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10990                });
10991            }
10992        });
10993
10994        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
10995        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10996            summaries.retain(|path, summaries_by_server_id| {
10997                if summaries_by_server_id.remove(&server_id).is_some() {
10998                    if let Some((client, project_id)) = self.downstream_client.clone() {
10999                        client
11000                            .send(proto::UpdateDiagnosticSummary {
11001                                project_id,
11002                                worktree_id: worktree_id.to_proto(),
11003                                summary: Some(proto::DiagnosticSummary {
11004                                    path: path.as_ref().to_proto(),
11005                                    language_server_id: server_id.0 as u64,
11006                                    error_count: 0,
11007                                    warning_count: 0,
11008                                }),
11009                                more_summaries: Vec::new(),
11010                            })
11011                            .log_err();
11012                    }
11013                    cleared_paths.push(ProjectPath {
11014                        worktree_id: *worktree_id,
11015                        path: path.clone(),
11016                    });
11017                    !summaries_by_server_id.is_empty()
11018                } else {
11019                    true
11020                }
11021            });
11022        }
11023        if !cleared_paths.is_empty() {
11024            cx.emit(LspStoreEvent::DiagnosticsUpdated {
11025                server_id,
11026                paths: cleared_paths,
11027            });
11028        }
11029
11030        let local = self.as_local_mut().unwrap();
11031        for diagnostics in local.diagnostics.values_mut() {
11032            diagnostics.retain(|_, diagnostics_by_server_id| {
11033                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
11034                    diagnostics_by_server_id.remove(ix);
11035                    !diagnostics_by_server_id.is_empty()
11036                } else {
11037                    true
11038                }
11039            });
11040        }
11041        local.language_server_watched_paths.remove(&server_id);
11042
11043        let server_state = local.language_servers.remove(&server_id);
11044        self.cleanup_lsp_data(server_id);
11045        let name = self
11046            .language_server_statuses
11047            .remove(&server_id)
11048            .map(|status| status.name)
11049            .or_else(|| {
11050                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
11051                    Some(adapter.name())
11052                } else {
11053                    None
11054                }
11055            });
11056
11057        if let Some(name) = name {
11058            log::info!("stopping language server {name}");
11059            self.languages
11060                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
11061            cx.notify();
11062
11063            return cx.spawn(async move |lsp_store, cx| {
11064                Self::shutdown_language_server(server_state, name.clone(), cx).await;
11065                lsp_store
11066                    .update(cx, |lsp_store, cx| {
11067                        lsp_store
11068                            .languages
11069                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
11070                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11071                        cx.notify();
11072                    })
11073                    .ok();
11074            });
11075        }
11076
11077        if server_state.is_some() {
11078            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11079        }
11080        Task::ready(())
11081    }
11082
11083    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
11084        self.shutdown_all_language_servers(cx).detach();
11085    }
11086
11087    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
11088        if let Some((client, project_id)) = self.upstream_client() {
11089            let request = client.request(proto::StopLanguageServers {
11090                project_id,
11091                buffer_ids: Vec::new(),
11092                also_servers: Vec::new(),
11093                all: true,
11094            });
11095            cx.background_spawn(async move {
11096                request.await.ok();
11097            })
11098        } else {
11099            let Some(local) = self.as_local_mut() else {
11100                return Task::ready(());
11101            };
11102            let language_servers_to_stop = local
11103                .language_server_ids
11104                .values()
11105                .map(|state| state.id)
11106                .collect();
11107            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11108            let tasks = language_servers_to_stop
11109                .into_iter()
11110                .map(|server| self.stop_local_language_server(server, cx))
11111                .collect::<Vec<_>>();
11112            cx.background_spawn(async move {
11113                futures::future::join_all(tasks).await;
11114            })
11115        }
11116    }
11117
11118    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
11119        let buffers = self.buffer_store.read(cx).buffers().collect();
11120        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
11121    }
11122
11123    pub fn restart_language_servers_for_buffers(
11124        &mut self,
11125        buffers: Vec<Entity<Buffer>>,
11126        only_restart_servers: HashSet<LanguageServerSelector>,
11127        cx: &mut Context<Self>,
11128    ) {
11129        if let Some((client, project_id)) = self.upstream_client() {
11130            let request = client.request(proto::RestartLanguageServers {
11131                project_id,
11132                buffer_ids: buffers
11133                    .into_iter()
11134                    .map(|b| b.read(cx).remote_id().to_proto())
11135                    .collect(),
11136                only_servers: only_restart_servers
11137                    .into_iter()
11138                    .map(|selector| {
11139                        let selector = match selector {
11140                            LanguageServerSelector::Id(language_server_id) => {
11141                                proto::language_server_selector::Selector::ServerId(
11142                                    language_server_id.to_proto(),
11143                                )
11144                            }
11145                            LanguageServerSelector::Name(language_server_name) => {
11146                                proto::language_server_selector::Selector::Name(
11147                                    language_server_name.to_string(),
11148                                )
11149                            }
11150                        };
11151                        proto::LanguageServerSelector {
11152                            selector: Some(selector),
11153                        }
11154                    })
11155                    .collect(),
11156                all: false,
11157            });
11158            cx.background_spawn(request).detach_and_log_err(cx);
11159        } else {
11160            let stop_task = if only_restart_servers.is_empty() {
11161                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11162            } else {
11163                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11164            };
11165            cx.spawn(async move |lsp_store, cx| {
11166                stop_task.await;
11167                lsp_store.update(cx, |lsp_store, cx| {
11168                    for buffer in buffers {
11169                        lsp_store.register_buffer_with_language_servers(
11170                            &buffer,
11171                            only_restart_servers.clone(),
11172                            true,
11173                            cx,
11174                        );
11175                    }
11176                })
11177            })
11178            .detach();
11179        }
11180    }
11181
11182    pub fn stop_language_servers_for_buffers(
11183        &mut self,
11184        buffers: Vec<Entity<Buffer>>,
11185        also_stop_servers: HashSet<LanguageServerSelector>,
11186        cx: &mut Context<Self>,
11187    ) -> Task<Result<()>> {
11188        if let Some((client, project_id)) = self.upstream_client() {
11189            let request = client.request(proto::StopLanguageServers {
11190                project_id,
11191                buffer_ids: buffers
11192                    .into_iter()
11193                    .map(|b| b.read(cx).remote_id().to_proto())
11194                    .collect(),
11195                also_servers: also_stop_servers
11196                    .into_iter()
11197                    .map(|selector| {
11198                        let selector = match selector {
11199                            LanguageServerSelector::Id(language_server_id) => {
11200                                proto::language_server_selector::Selector::ServerId(
11201                                    language_server_id.to_proto(),
11202                                )
11203                            }
11204                            LanguageServerSelector::Name(language_server_name) => {
11205                                proto::language_server_selector::Selector::Name(
11206                                    language_server_name.to_string(),
11207                                )
11208                            }
11209                        };
11210                        proto::LanguageServerSelector {
11211                            selector: Some(selector),
11212                        }
11213                    })
11214                    .collect(),
11215                all: false,
11216            });
11217            cx.background_spawn(async move {
11218                let _ = request.await?;
11219                Ok(())
11220            })
11221        } else {
11222            let task =
11223                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11224            cx.background_spawn(async move {
11225                task.await;
11226                Ok(())
11227            })
11228        }
11229    }
11230
11231    fn stop_local_language_servers_for_buffers(
11232        &mut self,
11233        buffers: &[Entity<Buffer>],
11234        also_stop_servers: HashSet<LanguageServerSelector>,
11235        cx: &mut Context<Self>,
11236    ) -> Task<()> {
11237        let Some(local) = self.as_local_mut() else {
11238            return Task::ready(());
11239        };
11240        let mut language_server_names_to_stop = BTreeSet::default();
11241        let mut language_servers_to_stop = also_stop_servers
11242            .into_iter()
11243            .flat_map(|selector| match selector {
11244                LanguageServerSelector::Id(id) => Some(id),
11245                LanguageServerSelector::Name(name) => {
11246                    language_server_names_to_stop.insert(name);
11247                    None
11248                }
11249            })
11250            .collect::<BTreeSet<_>>();
11251
11252        let mut covered_worktrees = HashSet::default();
11253        for buffer in buffers {
11254            buffer.update(cx, |buffer, cx| {
11255                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11256                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11257                    && covered_worktrees.insert(worktree_id)
11258                {
11259                    language_server_names_to_stop.retain(|name| {
11260                        let old_ids_count = language_servers_to_stop.len();
11261                        let all_language_servers_with_this_name = local
11262                            .language_server_ids
11263                            .iter()
11264                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11265                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11266                        old_ids_count == language_servers_to_stop.len()
11267                    });
11268                }
11269            });
11270        }
11271        for name in language_server_names_to_stop {
11272            language_servers_to_stop.extend(
11273                local
11274                    .language_server_ids
11275                    .iter()
11276                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11277            );
11278        }
11279
11280        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11281        let tasks = language_servers_to_stop
11282            .into_iter()
11283            .map(|server| self.stop_local_language_server(server, cx))
11284            .collect::<Vec<_>>();
11285
11286        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11287    }
11288
11289    #[cfg(any(test, feature = "test-support"))]
11290    pub fn update_diagnostics(
11291        &mut self,
11292        server_id: LanguageServerId,
11293        diagnostics: lsp::PublishDiagnosticsParams,
11294        result_id: Option<SharedString>,
11295        source_kind: DiagnosticSourceKind,
11296        disk_based_sources: &[String],
11297        cx: &mut Context<Self>,
11298    ) -> Result<()> {
11299        self.merge_lsp_diagnostics(
11300            source_kind,
11301            vec![DocumentDiagnosticsUpdate {
11302                diagnostics,
11303                result_id,
11304                server_id,
11305                disk_based_sources: Cow::Borrowed(disk_based_sources),
11306                registration_id: None,
11307            }],
11308            |_, _, _| false,
11309            cx,
11310        )
11311    }
11312
11313    pub fn merge_lsp_diagnostics(
11314        &mut self,
11315        source_kind: DiagnosticSourceKind,
11316        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11317        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11318        cx: &mut Context<Self>,
11319    ) -> Result<()> {
11320        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11321        let updates = lsp_diagnostics
11322            .into_iter()
11323            .filter_map(|update| {
11324                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11325                Some(DocumentDiagnosticsUpdate {
11326                    diagnostics: self.lsp_to_document_diagnostics(
11327                        abs_path,
11328                        source_kind,
11329                        update.server_id,
11330                        update.diagnostics,
11331                        &update.disk_based_sources,
11332                        update.registration_id.clone(),
11333                    ),
11334                    result_id: update.result_id,
11335                    server_id: update.server_id,
11336                    disk_based_sources: update.disk_based_sources,
11337                    registration_id: update.registration_id,
11338                })
11339            })
11340            .collect();
11341        self.merge_diagnostic_entries(updates, merge, cx)?;
11342        Ok(())
11343    }
11344
11345    fn lsp_to_document_diagnostics(
11346        &mut self,
11347        document_abs_path: PathBuf,
11348        source_kind: DiagnosticSourceKind,
11349        server_id: LanguageServerId,
11350        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11351        disk_based_sources: &[String],
11352        registration_id: Option<SharedString>,
11353    ) -> DocumentDiagnostics {
11354        let mut diagnostics = Vec::default();
11355        let mut primary_diagnostic_group_ids = HashMap::default();
11356        let mut sources_by_group_id = HashMap::default();
11357        let mut supporting_diagnostics = HashMap::default();
11358
11359        let adapter = self.language_server_adapter_for_id(server_id);
11360
11361        // Ensure that primary diagnostics are always the most severe
11362        lsp_diagnostics
11363            .diagnostics
11364            .sort_by_key(|item| item.severity);
11365
11366        for diagnostic in &lsp_diagnostics.diagnostics {
11367            let source = diagnostic.source.as_ref();
11368            let range = range_from_lsp(diagnostic.range);
11369            let is_supporting = diagnostic
11370                .related_information
11371                .as_ref()
11372                .is_some_and(|infos| {
11373                    infos.iter().any(|info| {
11374                        primary_diagnostic_group_ids.contains_key(&(
11375                            source,
11376                            diagnostic.code.clone(),
11377                            range_from_lsp(info.location.range),
11378                        ))
11379                    })
11380                });
11381
11382            let is_unnecessary = diagnostic
11383                .tags
11384                .as_ref()
11385                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11386
11387            let underline = self
11388                .language_server_adapter_for_id(server_id)
11389                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11390
11391            if is_supporting {
11392                supporting_diagnostics.insert(
11393                    (source, diagnostic.code.clone(), range),
11394                    (diagnostic.severity, is_unnecessary),
11395                );
11396            } else {
11397                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11398                let is_disk_based =
11399                    source.is_some_and(|source| disk_based_sources.contains(source));
11400
11401                sources_by_group_id.insert(group_id, source);
11402                primary_diagnostic_group_ids
11403                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11404
11405                diagnostics.push(DiagnosticEntry {
11406                    range,
11407                    diagnostic: Diagnostic {
11408                        source: diagnostic.source.clone(),
11409                        source_kind,
11410                        code: diagnostic.code.clone(),
11411                        code_description: diagnostic
11412                            .code_description
11413                            .as_ref()
11414                            .and_then(|d| d.href.clone()),
11415                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11416                        markdown: adapter.as_ref().and_then(|adapter| {
11417                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11418                        }),
11419                        message: diagnostic.message.trim().to_string(),
11420                        group_id,
11421                        is_primary: true,
11422                        is_disk_based,
11423                        is_unnecessary,
11424                        underline,
11425                        data: diagnostic.data.clone(),
11426                        registration_id: registration_id.clone(),
11427                    },
11428                });
11429                if let Some(infos) = &diagnostic.related_information {
11430                    for info in infos {
11431                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11432                            let range = range_from_lsp(info.location.range);
11433                            diagnostics.push(DiagnosticEntry {
11434                                range,
11435                                diagnostic: Diagnostic {
11436                                    source: diagnostic.source.clone(),
11437                                    source_kind,
11438                                    code: diagnostic.code.clone(),
11439                                    code_description: diagnostic
11440                                        .code_description
11441                                        .as_ref()
11442                                        .and_then(|d| d.href.clone()),
11443                                    severity: DiagnosticSeverity::INFORMATION,
11444                                    markdown: adapter.as_ref().and_then(|adapter| {
11445                                        adapter.diagnostic_message_to_markdown(&info.message)
11446                                    }),
11447                                    message: info.message.trim().to_string(),
11448                                    group_id,
11449                                    is_primary: false,
11450                                    is_disk_based,
11451                                    is_unnecessary: false,
11452                                    underline,
11453                                    data: diagnostic.data.clone(),
11454                                    registration_id: registration_id.clone(),
11455                                },
11456                            });
11457                        }
11458                    }
11459                }
11460            }
11461        }
11462
11463        for entry in &mut diagnostics {
11464            let diagnostic = &mut entry.diagnostic;
11465            if !diagnostic.is_primary {
11466                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11467                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11468                    source,
11469                    diagnostic.code.clone(),
11470                    entry.range.clone(),
11471                )) {
11472                    if let Some(severity) = severity {
11473                        diagnostic.severity = severity;
11474                    }
11475                    diagnostic.is_unnecessary = is_unnecessary;
11476                }
11477            }
11478        }
11479
11480        DocumentDiagnostics {
11481            diagnostics,
11482            document_abs_path,
11483            version: lsp_diagnostics.version,
11484        }
11485    }
11486
11487    fn insert_newly_running_language_server(
11488        &mut self,
11489        adapter: Arc<CachedLspAdapter>,
11490        language_server: Arc<LanguageServer>,
11491        server_id: LanguageServerId,
11492        key: LanguageServerSeed,
11493        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11494        cx: &mut Context<Self>,
11495    ) {
11496        let Some(local) = self.as_local_mut() else {
11497            return;
11498        };
11499        // If the language server for this key doesn't match the server id, don't store the
11500        // server. Which will cause it to be dropped, killing the process
11501        if local
11502            .language_server_ids
11503            .get(&key)
11504            .map(|state| state.id != server_id)
11505            .unwrap_or(false)
11506        {
11507            return;
11508        }
11509
11510        // Update language_servers collection with Running variant of LanguageServerState
11511        // indicating that the server is up and running and ready
11512        let workspace_folders = workspace_folders.lock().clone();
11513        language_server.set_workspace_folders(workspace_folders);
11514
11515        let workspace_diagnostics_refresh_tasks = language_server
11516            .capabilities()
11517            .diagnostic_provider
11518            .and_then(|provider| {
11519                local
11520                    .language_server_dynamic_registrations
11521                    .entry(server_id)
11522                    .or_default()
11523                    .diagnostics
11524                    .entry(None)
11525                    .or_insert(provider.clone());
11526                let workspace_refresher =
11527                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11528
11529                Some((None, workspace_refresher))
11530            })
11531            .into_iter()
11532            .collect();
11533        local.language_servers.insert(
11534            server_id,
11535            LanguageServerState::Running {
11536                workspace_diagnostics_refresh_tasks,
11537                adapter: adapter.clone(),
11538                server: language_server.clone(),
11539                simulate_disk_based_diagnostics_completion: None,
11540            },
11541        );
11542        local
11543            .languages
11544            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11545        if let Some(file_ops_caps) = language_server
11546            .capabilities()
11547            .workspace
11548            .as_ref()
11549            .and_then(|ws| ws.file_operations.as_ref())
11550        {
11551            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11552            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11553            if did_rename_caps.or(will_rename_caps).is_some() {
11554                let watcher = RenamePathsWatchedForServer::default()
11555                    .with_did_rename_patterns(did_rename_caps)
11556                    .with_will_rename_patterns(will_rename_caps);
11557                local
11558                    .language_server_paths_watched_for_rename
11559                    .insert(server_id, watcher);
11560            }
11561        }
11562
11563        self.language_server_statuses.insert(
11564            server_id,
11565            LanguageServerStatus {
11566                name: language_server.name(),
11567                server_version: language_server.version(),
11568                server_readable_version: language_server.readable_version(),
11569                pending_work: Default::default(),
11570                has_pending_diagnostic_updates: false,
11571                progress_tokens: Default::default(),
11572                worktree: Some(key.worktree_id),
11573                binary: Some(language_server.binary().clone()),
11574                configuration: Some(language_server.configuration().clone()),
11575                workspace_folders: language_server.workspace_folders(),
11576                process_id: language_server.process_id(),
11577            },
11578        );
11579
11580        cx.emit(LspStoreEvent::LanguageServerAdded(
11581            server_id,
11582            language_server.name(),
11583            Some(key.worktree_id),
11584        ));
11585
11586        let server_capabilities = language_server.capabilities();
11587        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11588            downstream_client
11589                .send(proto::StartLanguageServer {
11590                    project_id: *project_id,
11591                    server: Some(proto::LanguageServer {
11592                        id: server_id.to_proto(),
11593                        name: language_server.name().to_string(),
11594                        worktree_id: Some(key.worktree_id.to_proto()),
11595                    }),
11596                    capabilities: serde_json::to_string(&server_capabilities)
11597                        .expect("serializing server LSP capabilities"),
11598                })
11599                .log_err();
11600        }
11601        self.lsp_server_capabilities
11602            .insert(server_id, server_capabilities);
11603
11604        // Tell the language server about every open buffer in the worktree that matches the language.
11605        // Also check for buffers in worktrees that reused this server
11606        let mut worktrees_using_server = vec![key.worktree_id];
11607        if let Some(local) = self.as_local() {
11608            // Find all worktrees that have this server in their language server tree
11609            for (worktree_id, servers) in &local.lsp_tree.instances {
11610                if *worktree_id != key.worktree_id {
11611                    for server_map in servers.roots.values() {
11612                        if server_map
11613                            .values()
11614                            .any(|(node, _)| node.id() == Some(server_id))
11615                        {
11616                            worktrees_using_server.push(*worktree_id);
11617                        }
11618                    }
11619                }
11620            }
11621        }
11622
11623        let mut buffer_paths_registered = Vec::new();
11624        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11625            let mut lsp_adapters = HashMap::default();
11626            for buffer_handle in buffer_store.buffers() {
11627                let buffer = buffer_handle.read(cx);
11628                let file = match File::from_dyn(buffer.file()) {
11629                    Some(file) => file,
11630                    None => continue,
11631                };
11632                let language = match buffer.language() {
11633                    Some(language) => language,
11634                    None => continue,
11635                };
11636
11637                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11638                    || !lsp_adapters
11639                        .entry(language.name())
11640                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11641                        .iter()
11642                        .any(|a| a.name == key.name)
11643                {
11644                    continue;
11645                }
11646                // didOpen
11647                let file = match file.as_local() {
11648                    Some(file) => file,
11649                    None => continue,
11650                };
11651
11652                let local = self.as_local_mut().unwrap();
11653
11654                let buffer_id = buffer.remote_id();
11655                if local.registered_buffers.contains_key(&buffer_id) {
11656                    let abs_path = file.abs_path(cx);
11657                    let uri = match lsp::Uri::from_file_path(&abs_path) {
11658                        Ok(uri) => uri,
11659                        Err(()) => {
11660                            log::error!("failed to convert path to URI: {:?}", abs_path);
11661                            continue;
11662                        }
11663                    };
11664
11665                    let versions = local
11666                        .buffer_snapshots
11667                        .entry(buffer_id)
11668                        .or_default()
11669                        .entry(server_id)
11670                        .and_modify(|_| {
11671                            assert!(
11672                            false,
11673                            "There should not be an existing snapshot for a newly inserted buffer"
11674                        )
11675                        })
11676                        .or_insert_with(|| {
11677                            vec![LspBufferSnapshot {
11678                                version: 0,
11679                                snapshot: buffer.text_snapshot(),
11680                            }]
11681                        });
11682
11683                    let snapshot = versions.last().unwrap();
11684                    let version = snapshot.version;
11685                    let initial_snapshot = &snapshot.snapshot;
11686                    language_server.register_buffer(
11687                        uri,
11688                        adapter.language_id(&language.name()),
11689                        version,
11690                        initial_snapshot.text(),
11691                    );
11692                    buffer_paths_registered.push((buffer_id, abs_path));
11693                    local
11694                        .buffers_opened_in_servers
11695                        .entry(buffer_id)
11696                        .or_default()
11697                        .insert(server_id);
11698                }
11699                buffer_handle.update(cx, |buffer, cx| {
11700                    buffer.set_completion_triggers(
11701                        server_id,
11702                        language_server
11703                            .capabilities()
11704                            .completion_provider
11705                            .as_ref()
11706                            .and_then(|provider| {
11707                                provider
11708                                    .trigger_characters
11709                                    .as_ref()
11710                                    .map(|characters| characters.iter().cloned().collect())
11711                            })
11712                            .unwrap_or_default(),
11713                        cx,
11714                    )
11715                });
11716            }
11717        });
11718
11719        for (buffer_id, abs_path) in buffer_paths_registered {
11720            cx.emit(LspStoreEvent::LanguageServerUpdate {
11721                language_server_id: server_id,
11722                name: Some(adapter.name()),
11723                message: proto::update_language_server::Variant::RegisteredForBuffer(
11724                    proto::RegisteredForBuffer {
11725                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11726                        buffer_id: buffer_id.to_proto(),
11727                    },
11728                ),
11729            });
11730        }
11731
11732        cx.notify();
11733    }
11734
11735    pub fn language_servers_running_disk_based_diagnostics(
11736        &self,
11737    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11738        self.language_server_statuses
11739            .iter()
11740            .filter_map(|(id, status)| {
11741                if status.has_pending_diagnostic_updates {
11742                    Some(*id)
11743                } else {
11744                    None
11745                }
11746            })
11747    }
11748
11749    pub(crate) fn cancel_language_server_work_for_buffers(
11750        &mut self,
11751        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11752        cx: &mut Context<Self>,
11753    ) {
11754        if let Some((client, project_id)) = self.upstream_client() {
11755            let request = client.request(proto::CancelLanguageServerWork {
11756                project_id,
11757                work: Some(proto::cancel_language_server_work::Work::Buffers(
11758                    proto::cancel_language_server_work::Buffers {
11759                        buffer_ids: buffers
11760                            .into_iter()
11761                            .map(|b| b.read(cx).remote_id().to_proto())
11762                            .collect(),
11763                    },
11764                )),
11765            });
11766            cx.background_spawn(request).detach_and_log_err(cx);
11767        } else if let Some(local) = self.as_local() {
11768            let servers = buffers
11769                .into_iter()
11770                .flat_map(|buffer| {
11771                    buffer.update(cx, |buffer, cx| {
11772                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11773                    })
11774                })
11775                .collect::<HashSet<_>>();
11776            for server_id in servers {
11777                self.cancel_language_server_work(server_id, None, cx);
11778            }
11779        }
11780    }
11781
11782    pub(crate) fn cancel_language_server_work(
11783        &mut self,
11784        server_id: LanguageServerId,
11785        token_to_cancel: Option<ProgressToken>,
11786        cx: &mut Context<Self>,
11787    ) {
11788        if let Some(local) = self.as_local() {
11789            let status = self.language_server_statuses.get(&server_id);
11790            let server = local.language_servers.get(&server_id);
11791            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11792            {
11793                for (token, progress) in &status.pending_work {
11794                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11795                        && token != token_to_cancel
11796                    {
11797                        continue;
11798                    }
11799                    if progress.is_cancellable {
11800                        server
11801                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11802                                WorkDoneProgressCancelParams {
11803                                    token: token.to_lsp(),
11804                                },
11805                            )
11806                            .ok();
11807                    }
11808                }
11809            }
11810        } else if let Some((client, project_id)) = self.upstream_client() {
11811            let request = client.request(proto::CancelLanguageServerWork {
11812                project_id,
11813                work: Some(
11814                    proto::cancel_language_server_work::Work::LanguageServerWork(
11815                        proto::cancel_language_server_work::LanguageServerWork {
11816                            language_server_id: server_id.to_proto(),
11817                            token: token_to_cancel.map(|token| token.to_proto()),
11818                        },
11819                    ),
11820                ),
11821            });
11822            cx.background_spawn(request).detach_and_log_err(cx);
11823        }
11824    }
11825
11826    fn register_supplementary_language_server(
11827        &mut self,
11828        id: LanguageServerId,
11829        name: LanguageServerName,
11830        server: Arc<LanguageServer>,
11831        cx: &mut Context<Self>,
11832    ) {
11833        if let Some(local) = self.as_local_mut() {
11834            local
11835                .supplementary_language_servers
11836                .insert(id, (name.clone(), server));
11837            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11838        }
11839    }
11840
11841    fn unregister_supplementary_language_server(
11842        &mut self,
11843        id: LanguageServerId,
11844        cx: &mut Context<Self>,
11845    ) {
11846        if let Some(local) = self.as_local_mut() {
11847            local.supplementary_language_servers.remove(&id);
11848            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11849        }
11850    }
11851
11852    pub(crate) fn supplementary_language_servers(
11853        &self,
11854    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11855        self.as_local().into_iter().flat_map(|local| {
11856            local
11857                .supplementary_language_servers
11858                .iter()
11859                .map(|(id, (name, _))| (*id, name.clone()))
11860        })
11861    }
11862
11863    pub fn language_server_adapter_for_id(
11864        &self,
11865        id: LanguageServerId,
11866    ) -> Option<Arc<CachedLspAdapter>> {
11867        self.as_local()
11868            .and_then(|local| local.language_servers.get(&id))
11869            .and_then(|language_server_state| match language_server_state {
11870                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11871                _ => None,
11872            })
11873    }
11874
11875    pub(super) fn update_local_worktree_language_servers(
11876        &mut self,
11877        worktree_handle: &Entity<Worktree>,
11878        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11879        cx: &mut Context<Self>,
11880    ) {
11881        if changes.is_empty() {
11882            return;
11883        }
11884
11885        let Some(local) = self.as_local() else { return };
11886
11887        local.prettier_store.update(cx, |prettier_store, cx| {
11888            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11889        });
11890
11891        let worktree_id = worktree_handle.read(cx).id();
11892        let mut language_server_ids = local
11893            .language_server_ids
11894            .iter()
11895            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11896            .collect::<Vec<_>>();
11897        language_server_ids.sort();
11898        language_server_ids.dedup();
11899
11900        // let abs_path = worktree_handle.read(cx).abs_path();
11901        for server_id in &language_server_ids {
11902            if let Some(LanguageServerState::Running { server, .. }) =
11903                local.language_servers.get(server_id)
11904                && let Some(watched_paths) = local
11905                    .language_server_watched_paths
11906                    .get(server_id)
11907                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11908            {
11909                let params = lsp::DidChangeWatchedFilesParams {
11910                    changes: changes
11911                        .iter()
11912                        .filter_map(|(path, _, change)| {
11913                            if !watched_paths.is_match(path.as_std_path()) {
11914                                return None;
11915                            }
11916                            let typ = match change {
11917                                PathChange::Loaded => return None,
11918                                PathChange::Added => lsp::FileChangeType::CREATED,
11919                                PathChange::Removed => lsp::FileChangeType::DELETED,
11920                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11921                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11922                            };
11923                            let uri = lsp::Uri::from_file_path(
11924                                worktree_handle.read(cx).absolutize(&path),
11925                            )
11926                            .ok()?;
11927                            Some(lsp::FileEvent { uri, typ })
11928                        })
11929                        .collect(),
11930                };
11931                if !params.changes.is_empty() {
11932                    server
11933                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11934                        .ok();
11935                }
11936            }
11937        }
11938        for (path, _, _) in changes {
11939            if let Some(file_name) = path.file_name()
11940                && local.watched_manifest_filenames.contains(file_name)
11941            {
11942                self.request_workspace_config_refresh();
11943                break;
11944            }
11945        }
11946    }
11947
11948    pub fn wait_for_remote_buffer(
11949        &mut self,
11950        id: BufferId,
11951        cx: &mut Context<Self>,
11952    ) -> Task<Result<Entity<Buffer>>> {
11953        self.buffer_store.update(cx, |buffer_store, cx| {
11954            buffer_store.wait_for_remote_buffer(id, cx)
11955        })
11956    }
11957
11958    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11959        let mut result = proto::Symbol {
11960            language_server_name: symbol.language_server_name.0.to_string(),
11961            source_worktree_id: symbol.source_worktree_id.to_proto(),
11962            language_server_id: symbol.source_language_server_id.to_proto(),
11963            name: symbol.name.clone(),
11964            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11965            start: Some(proto::PointUtf16 {
11966                row: symbol.range.start.0.row,
11967                column: symbol.range.start.0.column,
11968            }),
11969            end: Some(proto::PointUtf16 {
11970                row: symbol.range.end.0.row,
11971                column: symbol.range.end.0.column,
11972            }),
11973            worktree_id: Default::default(),
11974            path: Default::default(),
11975            signature: Default::default(),
11976            container_name: symbol.container_name.clone(),
11977        };
11978        match &symbol.path {
11979            SymbolLocation::InProject(path) => {
11980                result.worktree_id = path.worktree_id.to_proto();
11981                result.path = path.path.to_proto();
11982            }
11983            SymbolLocation::OutsideProject {
11984                abs_path,
11985                signature,
11986            } => {
11987                result.path = abs_path.to_string_lossy().into_owned();
11988                result.signature = signature.to_vec();
11989            }
11990        }
11991        result
11992    }
11993
11994    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11995        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11996        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11997        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11998
11999        let path = if serialized_symbol.signature.is_empty() {
12000            SymbolLocation::InProject(ProjectPath {
12001                worktree_id,
12002                path: RelPath::from_proto(&serialized_symbol.path)
12003                    .context("invalid symbol path")?,
12004            })
12005        } else {
12006            SymbolLocation::OutsideProject {
12007                abs_path: Path::new(&serialized_symbol.path).into(),
12008                signature: serialized_symbol
12009                    .signature
12010                    .try_into()
12011                    .map_err(|_| anyhow!("invalid signature"))?,
12012            }
12013        };
12014
12015        let start = serialized_symbol.start.context("invalid start")?;
12016        let end = serialized_symbol.end.context("invalid end")?;
12017        Ok(CoreSymbol {
12018            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
12019            source_worktree_id,
12020            source_language_server_id: LanguageServerId::from_proto(
12021                serialized_symbol.language_server_id,
12022            ),
12023            path,
12024            name: serialized_symbol.name,
12025            range: Unclipped(PointUtf16::new(start.row, start.column))
12026                ..Unclipped(PointUtf16::new(end.row, end.column)),
12027            kind,
12028            container_name: serialized_symbol.container_name,
12029        })
12030    }
12031
12032    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
12033        let mut serialized_completion = proto::Completion {
12034            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
12035            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
12036            new_text: completion.new_text.clone(),
12037            ..proto::Completion::default()
12038        };
12039        match &completion.source {
12040            CompletionSource::Lsp {
12041                insert_range,
12042                server_id,
12043                lsp_completion,
12044                lsp_defaults,
12045                resolved,
12046            } => {
12047                let (old_insert_start, old_insert_end) = insert_range
12048                    .as_ref()
12049                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
12050                    .unzip();
12051
12052                serialized_completion.old_insert_start = old_insert_start;
12053                serialized_completion.old_insert_end = old_insert_end;
12054                serialized_completion.source = proto::completion::Source::Lsp as i32;
12055                serialized_completion.server_id = server_id.0 as u64;
12056                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
12057                serialized_completion.lsp_defaults = lsp_defaults
12058                    .as_deref()
12059                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
12060                serialized_completion.resolved = *resolved;
12061            }
12062            CompletionSource::BufferWord {
12063                word_range,
12064                resolved,
12065            } => {
12066                serialized_completion.source = proto::completion::Source::BufferWord as i32;
12067                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
12068                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
12069                serialized_completion.resolved = *resolved;
12070            }
12071            CompletionSource::Custom => {
12072                serialized_completion.source = proto::completion::Source::Custom as i32;
12073                serialized_completion.resolved = true;
12074            }
12075            CompletionSource::Dap { sort_text } => {
12076                serialized_completion.source = proto::completion::Source::Dap as i32;
12077                serialized_completion.sort_text = Some(sort_text.clone());
12078            }
12079        }
12080
12081        serialized_completion
12082    }
12083
12084    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
12085        let old_replace_start = completion
12086            .old_replace_start
12087            .and_then(deserialize_anchor)
12088            .context("invalid old start")?;
12089        let old_replace_end = completion
12090            .old_replace_end
12091            .and_then(deserialize_anchor)
12092            .context("invalid old end")?;
12093        let insert_range = {
12094            match completion.old_insert_start.zip(completion.old_insert_end) {
12095                Some((start, end)) => {
12096                    let start = deserialize_anchor(start).context("invalid insert old start")?;
12097                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12098                    Some(start..end)
12099                }
12100                None => None,
12101            }
12102        };
12103        Ok(CoreCompletion {
12104            replace_range: old_replace_start..old_replace_end,
12105            new_text: completion.new_text,
12106            source: match proto::completion::Source::from_i32(completion.source) {
12107                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12108                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12109                    insert_range,
12110                    server_id: LanguageServerId::from_proto(completion.server_id),
12111                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12112                    lsp_defaults: completion
12113                        .lsp_defaults
12114                        .as_deref()
12115                        .map(serde_json::from_slice)
12116                        .transpose()?,
12117                    resolved: completion.resolved,
12118                },
12119                Some(proto::completion::Source::BufferWord) => {
12120                    let word_range = completion
12121                        .buffer_word_start
12122                        .and_then(deserialize_anchor)
12123                        .context("invalid buffer word start")?
12124                        ..completion
12125                            .buffer_word_end
12126                            .and_then(deserialize_anchor)
12127                            .context("invalid buffer word end")?;
12128                    CompletionSource::BufferWord {
12129                        word_range,
12130                        resolved: completion.resolved,
12131                    }
12132                }
12133                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12134                    sort_text: completion
12135                        .sort_text
12136                        .context("expected sort text to exist")?,
12137                },
12138                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12139            },
12140        })
12141    }
12142
12143    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12144        let (kind, lsp_action) = match &action.lsp_action {
12145            LspAction::Action(code_action) => (
12146                proto::code_action::Kind::Action as i32,
12147                serde_json::to_vec(code_action).unwrap(),
12148            ),
12149            LspAction::Command(command) => (
12150                proto::code_action::Kind::Command as i32,
12151                serde_json::to_vec(command).unwrap(),
12152            ),
12153            LspAction::CodeLens(code_lens) => (
12154                proto::code_action::Kind::CodeLens as i32,
12155                serde_json::to_vec(code_lens).unwrap(),
12156            ),
12157        };
12158
12159        proto::CodeAction {
12160            server_id: action.server_id.0 as u64,
12161            start: Some(serialize_anchor(&action.range.start)),
12162            end: Some(serialize_anchor(&action.range.end)),
12163            lsp_action,
12164            kind,
12165            resolved: action.resolved,
12166        }
12167    }
12168
12169    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12170        let start = action
12171            .start
12172            .and_then(deserialize_anchor)
12173            .context("invalid start")?;
12174        let end = action
12175            .end
12176            .and_then(deserialize_anchor)
12177            .context("invalid end")?;
12178        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12179            Some(proto::code_action::Kind::Action) => {
12180                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12181            }
12182            Some(proto::code_action::Kind::Command) => {
12183                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12184            }
12185            Some(proto::code_action::Kind::CodeLens) => {
12186                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12187            }
12188            None => anyhow::bail!("Unknown action kind {}", action.kind),
12189        };
12190        Ok(CodeAction {
12191            server_id: LanguageServerId(action.server_id as usize),
12192            range: start..end,
12193            resolved: action.resolved,
12194            lsp_action,
12195        })
12196    }
12197
12198    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12199        match &formatting_result {
12200            Ok(_) => self.last_formatting_failure = None,
12201            Err(error) => {
12202                let error_string = format!("{error:#}");
12203                log::error!("Formatting failed: {error_string}");
12204                self.last_formatting_failure
12205                    .replace(error_string.lines().join(" "));
12206            }
12207        }
12208    }
12209
12210    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12211        self.lsp_server_capabilities.remove(&for_server);
12212        self.semantic_token_config.remove_server_data(for_server);
12213        for lsp_data in self.lsp_data.values_mut() {
12214            lsp_data.remove_server_data(for_server);
12215        }
12216        if let Some(local) = self.as_local_mut() {
12217            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12218            local
12219                .workspace_pull_diagnostics_result_ids
12220                .remove(&for_server);
12221            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12222                buffer_servers.remove(&for_server);
12223            }
12224        }
12225    }
12226
12227    pub fn result_id_for_buffer_pull(
12228        &self,
12229        server_id: LanguageServerId,
12230        buffer_id: BufferId,
12231        registration_id: &Option<SharedString>,
12232        cx: &App,
12233    ) -> Option<SharedString> {
12234        let abs_path = self
12235            .buffer_store
12236            .read(cx)
12237            .get(buffer_id)
12238            .and_then(|b| File::from_dyn(b.read(cx).file()))
12239            .map(|f| f.abs_path(cx))?;
12240        self.as_local()?
12241            .buffer_pull_diagnostics_result_ids
12242            .get(&server_id)?
12243            .get(registration_id)?
12244            .get(&abs_path)?
12245            .clone()
12246    }
12247
12248    /// Gets all result_ids for a workspace diagnostics pull request.
12249    /// 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.
12250    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12251    pub fn result_ids_for_workspace_refresh(
12252        &self,
12253        server_id: LanguageServerId,
12254        registration_id: &Option<SharedString>,
12255    ) -> HashMap<PathBuf, SharedString> {
12256        let Some(local) = self.as_local() else {
12257            return HashMap::default();
12258        };
12259        local
12260            .workspace_pull_diagnostics_result_ids
12261            .get(&server_id)
12262            .into_iter()
12263            .filter_map(|diagnostics| diagnostics.get(registration_id))
12264            .flatten()
12265            .filter_map(|(abs_path, result_id)| {
12266                let result_id = local
12267                    .buffer_pull_diagnostics_result_ids
12268                    .get(&server_id)
12269                    .and_then(|buffer_ids_result_ids| {
12270                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12271                    })
12272                    .cloned()
12273                    .flatten()
12274                    .or_else(|| result_id.clone())?;
12275                Some((abs_path.clone(), result_id))
12276            })
12277            .collect()
12278    }
12279
12280    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12281        if let Some(LanguageServerState::Running {
12282            workspace_diagnostics_refresh_tasks,
12283            ..
12284        }) = self
12285            .as_local_mut()
12286            .and_then(|local| local.language_servers.get_mut(&server_id))
12287        {
12288            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12289                diagnostics.refresh_tx.try_send(()).ok();
12290            }
12291        }
12292    }
12293
12294    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12295    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12296    /// which requires refreshing both workspace and document diagnostics.
12297    pub fn pull_document_diagnostics_for_server(
12298        &mut self,
12299        server_id: LanguageServerId,
12300        source_buffer_id: Option<BufferId>,
12301        cx: &mut Context<Self>,
12302    ) -> Shared<Task<()>> {
12303        let Some(local) = self.as_local_mut() else {
12304            return Task::ready(()).shared();
12305        };
12306        let mut buffers_to_refresh = HashSet::default();
12307        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12308            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12309                buffers_to_refresh.insert(*buffer_id);
12310            }
12311        }
12312
12313        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12314    }
12315
12316    pub fn pull_document_diagnostics_for_buffer_edit(
12317        &mut self,
12318        buffer_id: BufferId,
12319        cx: &mut Context<Self>,
12320    ) {
12321        let Some(local) = self.as_local_mut() else {
12322            return;
12323        };
12324        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12325        else {
12326            return;
12327        };
12328        for server_id in languages_servers {
12329            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12330        }
12331    }
12332
12333    fn apply_workspace_diagnostic_report(
12334        &mut self,
12335        server_id: LanguageServerId,
12336        report: lsp::WorkspaceDiagnosticReportResult,
12337        registration_id: Option<SharedString>,
12338        cx: &mut Context<Self>,
12339    ) {
12340        let mut workspace_diagnostics =
12341            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12342                report,
12343                server_id,
12344                registration_id,
12345            );
12346        workspace_diagnostics.retain(|d| match &d.diagnostics {
12347            LspPullDiagnostics::Response {
12348                server_id,
12349                registration_id,
12350                ..
12351            } => self.diagnostic_registration_exists(*server_id, registration_id),
12352            LspPullDiagnostics::Default => false,
12353        });
12354        let mut unchanged_buffers = HashMap::default();
12355        let workspace_diagnostics_updates = workspace_diagnostics
12356            .into_iter()
12357            .filter_map(
12358                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12359                    LspPullDiagnostics::Response {
12360                        server_id,
12361                        uri,
12362                        diagnostics,
12363                        registration_id,
12364                    } => Some((
12365                        server_id,
12366                        uri,
12367                        diagnostics,
12368                        workspace_diagnostics.version,
12369                        registration_id,
12370                    )),
12371                    LspPullDiagnostics::Default => None,
12372                },
12373            )
12374            .fold(
12375                HashMap::default(),
12376                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12377                    let (result_id, diagnostics) = match diagnostics {
12378                        PulledDiagnostics::Unchanged { result_id } => {
12379                            unchanged_buffers
12380                                .entry(new_registration_id.clone())
12381                                .or_insert_with(HashSet::default)
12382                                .insert(uri.clone());
12383                            (Some(result_id), Vec::new())
12384                        }
12385                        PulledDiagnostics::Changed {
12386                            result_id,
12387                            diagnostics,
12388                        } => (result_id, diagnostics),
12389                    };
12390                    let disk_based_sources = Cow::Owned(
12391                        self.language_server_adapter_for_id(server_id)
12392                            .as_ref()
12393                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12394                            .unwrap_or(&[])
12395                            .to_vec(),
12396                    );
12397
12398                    let Some(abs_path) = uri.to_file_path().ok() else {
12399                        return acc;
12400                    };
12401                    let Some((worktree, relative_path)) =
12402                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12403                    else {
12404                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12405                        return acc;
12406                    };
12407                    let worktree_id = worktree.read(cx).id();
12408                    let project_path = ProjectPath {
12409                        worktree_id,
12410                        path: relative_path,
12411                    };
12412                    if let Some(local_lsp_store) = self.as_local_mut() {
12413                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12414                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12415                    }
12416                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12417                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12418                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12419                        acc.entry(server_id)
12420                            .or_insert_with(HashMap::default)
12421                            .entry(new_registration_id.clone())
12422                            .or_insert_with(Vec::new)
12423                            .push(DocumentDiagnosticsUpdate {
12424                                server_id,
12425                                diagnostics: lsp::PublishDiagnosticsParams {
12426                                    uri,
12427                                    diagnostics,
12428                                    version,
12429                                },
12430                                result_id: result_id.map(SharedString::new),
12431                                disk_based_sources,
12432                                registration_id: new_registration_id,
12433                            });
12434                    }
12435                    acc
12436                },
12437            );
12438
12439        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12440            for (registration_id, diagnostic_updates) in diagnostic_updates {
12441                self.merge_lsp_diagnostics(
12442                    DiagnosticSourceKind::Pulled,
12443                    diagnostic_updates,
12444                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12445                        DiagnosticSourceKind::Pulled => {
12446                            old_diagnostic.registration_id != registration_id
12447                                || unchanged_buffers
12448                                    .get(&old_diagnostic.registration_id)
12449                                    .is_some_and(|unchanged_buffers| {
12450                                        unchanged_buffers.contains(&document_uri)
12451                                    })
12452                        }
12453                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12454                    },
12455                    cx,
12456                )
12457                .log_err();
12458            }
12459        }
12460    }
12461
12462    fn register_server_capabilities(
12463        &mut self,
12464        server_id: LanguageServerId,
12465        params: lsp::RegistrationParams,
12466        cx: &mut Context<Self>,
12467    ) -> anyhow::Result<()> {
12468        let server = self
12469            .language_server_for_id(server_id)
12470            .with_context(|| format!("no server {server_id} found"))?;
12471        for reg in params.registrations {
12472            match reg.method.as_str() {
12473                "workspace/didChangeWatchedFiles" => {
12474                    if let Some(options) = reg.register_options {
12475                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12476                            let caps = serde_json::from_value(options)?;
12477                            local_lsp_store
12478                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12479                            true
12480                        } else {
12481                            false
12482                        };
12483                        if notify {
12484                            notify_server_capabilities_updated(&server, cx);
12485                        }
12486                    }
12487                }
12488                "workspace/didChangeConfiguration" => {
12489                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12490                }
12491                "workspace/didChangeWorkspaceFolders" => {
12492                    // In this case register options is an empty object, we can ignore it
12493                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12494                        supported: Some(true),
12495                        change_notifications: Some(OneOf::Right(reg.id)),
12496                    };
12497                    server.update_capabilities(|capabilities| {
12498                        capabilities
12499                            .workspace
12500                            .get_or_insert_default()
12501                            .workspace_folders = Some(caps);
12502                    });
12503                    notify_server_capabilities_updated(&server, cx);
12504                }
12505                "workspace/symbol" => {
12506                    let options = parse_register_capabilities(reg)?;
12507                    server.update_capabilities(|capabilities| {
12508                        capabilities.workspace_symbol_provider = Some(options);
12509                    });
12510                    notify_server_capabilities_updated(&server, cx);
12511                }
12512                "workspace/fileOperations" => {
12513                    if let Some(options) = reg.register_options {
12514                        let caps = serde_json::from_value(options)?;
12515                        server.update_capabilities(|capabilities| {
12516                            capabilities
12517                                .workspace
12518                                .get_or_insert_default()
12519                                .file_operations = Some(caps);
12520                        });
12521                        notify_server_capabilities_updated(&server, cx);
12522                    }
12523                }
12524                "workspace/executeCommand" => {
12525                    if let Some(options) = reg.register_options {
12526                        let options = serde_json::from_value(options)?;
12527                        server.update_capabilities(|capabilities| {
12528                            capabilities.execute_command_provider = Some(options);
12529                        });
12530                        notify_server_capabilities_updated(&server, cx);
12531                    }
12532                }
12533                "textDocument/rangeFormatting" => {
12534                    let options = parse_register_capabilities(reg)?;
12535                    server.update_capabilities(|capabilities| {
12536                        capabilities.document_range_formatting_provider = Some(options);
12537                    });
12538                    notify_server_capabilities_updated(&server, cx);
12539                }
12540                "textDocument/onTypeFormatting" => {
12541                    if let Some(options) = reg
12542                        .register_options
12543                        .map(serde_json::from_value)
12544                        .transpose()?
12545                    {
12546                        server.update_capabilities(|capabilities| {
12547                            capabilities.document_on_type_formatting_provider = Some(options);
12548                        });
12549                        notify_server_capabilities_updated(&server, cx);
12550                    }
12551                }
12552                "textDocument/formatting" => {
12553                    let options = parse_register_capabilities(reg)?;
12554                    server.update_capabilities(|capabilities| {
12555                        capabilities.document_formatting_provider = Some(options);
12556                    });
12557                    notify_server_capabilities_updated(&server, cx);
12558                }
12559                "textDocument/rename" => {
12560                    let options = parse_register_capabilities(reg)?;
12561                    server.update_capabilities(|capabilities| {
12562                        capabilities.rename_provider = Some(options);
12563                    });
12564                    notify_server_capabilities_updated(&server, cx);
12565                }
12566                "textDocument/inlayHint" => {
12567                    let options = parse_register_capabilities(reg)?;
12568                    server.update_capabilities(|capabilities| {
12569                        capabilities.inlay_hint_provider = Some(options);
12570                    });
12571                    notify_server_capabilities_updated(&server, cx);
12572                }
12573                "textDocument/documentSymbol" => {
12574                    let options = parse_register_capabilities(reg)?;
12575                    server.update_capabilities(|capabilities| {
12576                        capabilities.document_symbol_provider = Some(options);
12577                    });
12578                    notify_server_capabilities_updated(&server, cx);
12579                }
12580                "textDocument/codeAction" => {
12581                    let options = parse_register_capabilities(reg)?;
12582                    let provider = match options {
12583                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12584                        OneOf::Right(caps) => caps,
12585                    };
12586                    server.update_capabilities(|capabilities| {
12587                        capabilities.code_action_provider = Some(provider);
12588                    });
12589                    notify_server_capabilities_updated(&server, cx);
12590                }
12591                "textDocument/definition" => {
12592                    let options = parse_register_capabilities(reg)?;
12593                    server.update_capabilities(|capabilities| {
12594                        capabilities.definition_provider = Some(options);
12595                    });
12596                    notify_server_capabilities_updated(&server, cx);
12597                }
12598                "textDocument/completion" => {
12599                    if let Some(caps) = reg
12600                        .register_options
12601                        .map(serde_json::from_value::<CompletionOptions>)
12602                        .transpose()?
12603                    {
12604                        server.update_capabilities(|capabilities| {
12605                            capabilities.completion_provider = Some(caps.clone());
12606                        });
12607
12608                        if let Some(local) = self.as_local() {
12609                            let mut buffers_with_language_server = Vec::new();
12610                            for handle in self.buffer_store.read(cx).buffers() {
12611                                let buffer_id = handle.read(cx).remote_id();
12612                                if local
12613                                    .buffers_opened_in_servers
12614                                    .get(&buffer_id)
12615                                    .filter(|s| s.contains(&server_id))
12616                                    .is_some()
12617                                {
12618                                    buffers_with_language_server.push(handle);
12619                                }
12620                            }
12621                            let triggers = caps
12622                                .trigger_characters
12623                                .unwrap_or_default()
12624                                .into_iter()
12625                                .collect::<BTreeSet<_>>();
12626                            for handle in buffers_with_language_server {
12627                                let triggers = triggers.clone();
12628                                let _ = handle.update(cx, move |buffer, cx| {
12629                                    buffer.set_completion_triggers(server_id, triggers, cx);
12630                                });
12631                            }
12632                        }
12633                        notify_server_capabilities_updated(&server, cx);
12634                    }
12635                }
12636                "textDocument/hover" => {
12637                    let options = parse_register_capabilities(reg)?;
12638                    let provider = match options {
12639                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12640                        OneOf::Right(caps) => caps,
12641                    };
12642                    server.update_capabilities(|capabilities| {
12643                        capabilities.hover_provider = Some(provider);
12644                    });
12645                    notify_server_capabilities_updated(&server, cx);
12646                }
12647                "textDocument/signatureHelp" => {
12648                    if let Some(caps) = reg
12649                        .register_options
12650                        .map(serde_json::from_value)
12651                        .transpose()?
12652                    {
12653                        server.update_capabilities(|capabilities| {
12654                            capabilities.signature_help_provider = Some(caps);
12655                        });
12656                        notify_server_capabilities_updated(&server, cx);
12657                    }
12658                }
12659                "textDocument/didChange" => {
12660                    if let Some(sync_kind) = reg
12661                        .register_options
12662                        .and_then(|opts| opts.get("syncKind").cloned())
12663                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12664                        .transpose()?
12665                    {
12666                        server.update_capabilities(|capabilities| {
12667                            let mut sync_options =
12668                                Self::take_text_document_sync_options(capabilities);
12669                            sync_options.change = Some(sync_kind);
12670                            capabilities.text_document_sync =
12671                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12672                        });
12673                        notify_server_capabilities_updated(&server, cx);
12674                    }
12675                }
12676                "textDocument/didSave" => {
12677                    if let Some(include_text) = reg
12678                        .register_options
12679                        .map(|opts| {
12680                            let transpose = opts
12681                                .get("includeText")
12682                                .cloned()
12683                                .map(serde_json::from_value::<Option<bool>>)
12684                                .transpose();
12685                            match transpose {
12686                                Ok(value) => Ok(value.flatten()),
12687                                Err(e) => Err(e),
12688                            }
12689                        })
12690                        .transpose()?
12691                    {
12692                        server.update_capabilities(|capabilities| {
12693                            let mut sync_options =
12694                                Self::take_text_document_sync_options(capabilities);
12695                            sync_options.save =
12696                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12697                                    include_text,
12698                                }));
12699                            capabilities.text_document_sync =
12700                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12701                        });
12702                        notify_server_capabilities_updated(&server, cx);
12703                    }
12704                }
12705                "textDocument/codeLens" => {
12706                    if let Some(caps) = reg
12707                        .register_options
12708                        .map(serde_json::from_value)
12709                        .transpose()?
12710                    {
12711                        server.update_capabilities(|capabilities| {
12712                            capabilities.code_lens_provider = Some(caps);
12713                        });
12714                        notify_server_capabilities_updated(&server, cx);
12715                    }
12716                }
12717                "textDocument/diagnostic" => {
12718                    if let Some(caps) = reg
12719                        .register_options
12720                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12721                        .transpose()?
12722                    {
12723                        let local = self
12724                            .as_local_mut()
12725                            .context("Expected LSP Store to be local")?;
12726                        let state = local
12727                            .language_servers
12728                            .get_mut(&server_id)
12729                            .context("Could not obtain Language Servers state")?;
12730                        local
12731                            .language_server_dynamic_registrations
12732                            .entry(server_id)
12733                            .or_default()
12734                            .diagnostics
12735                            .insert(Some(reg.id.clone()), caps.clone());
12736
12737                        let supports_workspace_diagnostics =
12738                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12739                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12740                                    diagnostic_options.workspace_diagnostics
12741                                }
12742                                DiagnosticServerCapabilities::RegistrationOptions(
12743                                    diagnostic_registration_options,
12744                                ) => {
12745                                    diagnostic_registration_options
12746                                        .diagnostic_options
12747                                        .workspace_diagnostics
12748                                }
12749                            };
12750
12751                        if supports_workspace_diagnostics(&caps) {
12752                            if let LanguageServerState::Running {
12753                                workspace_diagnostics_refresh_tasks,
12754                                ..
12755                            } = state
12756                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12757                                    Some(reg.id.clone()),
12758                                    caps.clone(),
12759                                    server.clone(),
12760                                    cx,
12761                                )
12762                            {
12763                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12764                            }
12765                        }
12766
12767                        server.update_capabilities(|capabilities| {
12768                            capabilities.diagnostic_provider = Some(caps);
12769                        });
12770
12771                        notify_server_capabilities_updated(&server, cx);
12772
12773                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12774                    }
12775                }
12776                "textDocument/documentColor" => {
12777                    let options = parse_register_capabilities(reg)?;
12778                    let provider = match options {
12779                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12780                        OneOf::Right(caps) => caps,
12781                    };
12782                    server.update_capabilities(|capabilities| {
12783                        capabilities.color_provider = Some(provider);
12784                    });
12785                    notify_server_capabilities_updated(&server, cx);
12786                }
12787                "textDocument/foldingRange" => {
12788                    let options = parse_register_capabilities(reg)?;
12789                    let provider = match options {
12790                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12791                        OneOf::Right(caps) => caps,
12792                    };
12793                    server.update_capabilities(|capabilities| {
12794                        capabilities.folding_range_provider = Some(provider);
12795                    });
12796                    notify_server_capabilities_updated(&server, cx);
12797                }
12798                _ => log::warn!("unhandled capability registration: {reg:?}"),
12799            }
12800        }
12801
12802        Ok(())
12803    }
12804
12805    fn unregister_server_capabilities(
12806        &mut self,
12807        server_id: LanguageServerId,
12808        params: lsp::UnregistrationParams,
12809        cx: &mut Context<Self>,
12810    ) -> anyhow::Result<()> {
12811        let server = self
12812            .language_server_for_id(server_id)
12813            .with_context(|| format!("no server {server_id} found"))?;
12814        for unreg in params.unregisterations.iter() {
12815            match unreg.method.as_str() {
12816                "workspace/didChangeWatchedFiles" => {
12817                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12818                        local_lsp_store
12819                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12820                        true
12821                    } else {
12822                        false
12823                    };
12824                    if notify {
12825                        notify_server_capabilities_updated(&server, cx);
12826                    }
12827                }
12828                "workspace/didChangeConfiguration" => {
12829                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12830                }
12831                "workspace/didChangeWorkspaceFolders" => {
12832                    server.update_capabilities(|capabilities| {
12833                        capabilities
12834                            .workspace
12835                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12836                                workspace_folders: None,
12837                                file_operations: None,
12838                            })
12839                            .workspace_folders = None;
12840                    });
12841                    notify_server_capabilities_updated(&server, cx);
12842                }
12843                "workspace/symbol" => {
12844                    server.update_capabilities(|capabilities| {
12845                        capabilities.workspace_symbol_provider = None
12846                    });
12847                    notify_server_capabilities_updated(&server, cx);
12848                }
12849                "workspace/fileOperations" => {
12850                    server.update_capabilities(|capabilities| {
12851                        capabilities
12852                            .workspace
12853                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12854                                workspace_folders: None,
12855                                file_operations: None,
12856                            })
12857                            .file_operations = None;
12858                    });
12859                    notify_server_capabilities_updated(&server, cx);
12860                }
12861                "workspace/executeCommand" => {
12862                    server.update_capabilities(|capabilities| {
12863                        capabilities.execute_command_provider = None;
12864                    });
12865                    notify_server_capabilities_updated(&server, cx);
12866                }
12867                "textDocument/rangeFormatting" => {
12868                    server.update_capabilities(|capabilities| {
12869                        capabilities.document_range_formatting_provider = None
12870                    });
12871                    notify_server_capabilities_updated(&server, cx);
12872                }
12873                "textDocument/onTypeFormatting" => {
12874                    server.update_capabilities(|capabilities| {
12875                        capabilities.document_on_type_formatting_provider = None;
12876                    });
12877                    notify_server_capabilities_updated(&server, cx);
12878                }
12879                "textDocument/formatting" => {
12880                    server.update_capabilities(|capabilities| {
12881                        capabilities.document_formatting_provider = None;
12882                    });
12883                    notify_server_capabilities_updated(&server, cx);
12884                }
12885                "textDocument/rename" => {
12886                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12887                    notify_server_capabilities_updated(&server, cx);
12888                }
12889                "textDocument/codeAction" => {
12890                    server.update_capabilities(|capabilities| {
12891                        capabilities.code_action_provider = None;
12892                    });
12893                    notify_server_capabilities_updated(&server, cx);
12894                }
12895                "textDocument/definition" => {
12896                    server.update_capabilities(|capabilities| {
12897                        capabilities.definition_provider = None;
12898                    });
12899                    notify_server_capabilities_updated(&server, cx);
12900                }
12901                "textDocument/completion" => {
12902                    server.update_capabilities(|capabilities| {
12903                        capabilities.completion_provider = None;
12904                    });
12905                    notify_server_capabilities_updated(&server, cx);
12906                }
12907                "textDocument/hover" => {
12908                    server.update_capabilities(|capabilities| {
12909                        capabilities.hover_provider = None;
12910                    });
12911                    notify_server_capabilities_updated(&server, cx);
12912                }
12913                "textDocument/signatureHelp" => {
12914                    server.update_capabilities(|capabilities| {
12915                        capabilities.signature_help_provider = None;
12916                    });
12917                    notify_server_capabilities_updated(&server, cx);
12918                }
12919                "textDocument/didChange" => {
12920                    server.update_capabilities(|capabilities| {
12921                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12922                        sync_options.change = None;
12923                        capabilities.text_document_sync =
12924                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12925                    });
12926                    notify_server_capabilities_updated(&server, cx);
12927                }
12928                "textDocument/didSave" => {
12929                    server.update_capabilities(|capabilities| {
12930                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12931                        sync_options.save = None;
12932                        capabilities.text_document_sync =
12933                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12934                    });
12935                    notify_server_capabilities_updated(&server, cx);
12936                }
12937                "textDocument/codeLens" => {
12938                    server.update_capabilities(|capabilities| {
12939                        capabilities.code_lens_provider = None;
12940                    });
12941                    notify_server_capabilities_updated(&server, cx);
12942                }
12943                "textDocument/diagnostic" => {
12944                    let local = self
12945                        .as_local_mut()
12946                        .context("Expected LSP Store to be local")?;
12947
12948                    let state = local
12949                        .language_servers
12950                        .get_mut(&server_id)
12951                        .context("Could not obtain Language Servers state")?;
12952                    let registrations = local
12953                        .language_server_dynamic_registrations
12954                        .get_mut(&server_id)
12955                        .with_context(|| {
12956                            format!("Expected dynamic registration to exist for server {server_id}")
12957                        })?;
12958                    registrations.diagnostics
12959                        .remove(&Some(unreg.id.clone()))
12960                        .with_context(|| format!(
12961                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12962                            unreg.id)
12963                        )?;
12964                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12965
12966                    if let LanguageServerState::Running {
12967                        workspace_diagnostics_refresh_tasks,
12968                        ..
12969                    } = state
12970                    {
12971                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12972                    }
12973
12974                    self.clear_unregistered_diagnostics(
12975                        server_id,
12976                        SharedString::from(unreg.id.clone()),
12977                        cx,
12978                    )?;
12979
12980                    if removed_last_diagnostic_provider {
12981                        server.update_capabilities(|capabilities| {
12982                            debug_assert!(capabilities.diagnostic_provider.is_some());
12983                            capabilities.diagnostic_provider = None;
12984                        });
12985                    }
12986
12987                    notify_server_capabilities_updated(&server, cx);
12988                }
12989                "textDocument/documentColor" => {
12990                    server.update_capabilities(|capabilities| {
12991                        capabilities.color_provider = None;
12992                    });
12993                    notify_server_capabilities_updated(&server, cx);
12994                }
12995                "textDocument/foldingRange" => {
12996                    server.update_capabilities(|capabilities| {
12997                        capabilities.folding_range_provider = None;
12998                    });
12999                    notify_server_capabilities_updated(&server, cx);
13000                }
13001                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
13002            }
13003        }
13004
13005        Ok(())
13006    }
13007
13008    fn clear_unregistered_diagnostics(
13009        &mut self,
13010        server_id: LanguageServerId,
13011        cleared_registration_id: SharedString,
13012        cx: &mut Context<Self>,
13013    ) -> anyhow::Result<()> {
13014        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
13015
13016        self.buffer_store.update(cx, |buffer_store, cx| {
13017            for buffer_handle in buffer_store.buffers() {
13018                let buffer = buffer_handle.read(cx);
13019                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
13020                let Some(abs_path) = abs_path else {
13021                    continue;
13022                };
13023                affected_abs_paths.insert(abs_path);
13024            }
13025        });
13026
13027        let local = self.as_local().context("Expected LSP Store to be local")?;
13028        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
13029            let Some(worktree) = self
13030                .worktree_store
13031                .read(cx)
13032                .worktree_for_id(*worktree_id, cx)
13033            else {
13034                continue;
13035            };
13036
13037            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
13038                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
13039                    let has_matching_registration =
13040                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
13041                            entry.diagnostic.registration_id.as_ref()
13042                                == Some(&cleared_registration_id)
13043                        });
13044                    if has_matching_registration {
13045                        let abs_path = worktree.read(cx).absolutize(rel_path);
13046                        affected_abs_paths.insert(abs_path);
13047                    }
13048                }
13049            }
13050        }
13051
13052        if affected_abs_paths.is_empty() {
13053            return Ok(());
13054        }
13055
13056        // Send a fake diagnostic update which clears the state for the registration ID
13057        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
13058            affected_abs_paths
13059                .into_iter()
13060                .map(|abs_path| DocumentDiagnosticsUpdate {
13061                    diagnostics: DocumentDiagnostics {
13062                        diagnostics: Vec::new(),
13063                        document_abs_path: abs_path,
13064                        version: None,
13065                    },
13066                    result_id: None,
13067                    registration_id: Some(cleared_registration_id.clone()),
13068                    server_id,
13069                    disk_based_sources: Cow::Borrowed(&[]),
13070                })
13071                .collect();
13072
13073        let merge_registration_id = cleared_registration_id.clone();
13074        self.merge_diagnostic_entries(
13075            clears,
13076            move |_, diagnostic, _| {
13077                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
13078                    diagnostic.registration_id != Some(merge_registration_id.clone())
13079                } else {
13080                    true
13081                }
13082            },
13083            cx,
13084        )?;
13085
13086        Ok(())
13087    }
13088
13089    async fn deduplicate_range_based_lsp_requests<T>(
13090        lsp_store: &Entity<Self>,
13091        server_id: Option<LanguageServerId>,
13092        lsp_request_id: LspRequestId,
13093        proto_request: &T::ProtoRequest,
13094        range: Range<Anchor>,
13095        cx: &mut AsyncApp,
13096    ) -> Result<()>
13097    where
13098        T: LspCommand,
13099        T::ProtoRequest: proto::LspRequestMessage,
13100    {
13101        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13102        let version = deserialize_version(proto_request.buffer_version());
13103        let buffer = lsp_store.update(cx, |this, cx| {
13104            this.buffer_store.read(cx).get_existing(buffer_id)
13105        })?;
13106        buffer
13107            .update(cx, |buffer, _| buffer.wait_for_version(version))
13108            .await?;
13109        lsp_store.update(cx, |lsp_store, cx| {
13110            let buffer_snapshot = buffer.read(cx).snapshot();
13111            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13112            let chunks_queried_for = lsp_data
13113                .inlay_hints
13114                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
13115                .collect::<Vec<_>>();
13116            match chunks_queried_for.as_slice() {
13117                &[chunk] => {
13118                    let key = LspKey {
13119                        request_type: TypeId::of::<T>(),
13120                        server_queried: server_id,
13121                    };
13122                    let previous_request = lsp_data
13123                        .chunk_lsp_requests
13124                        .entry(key)
13125                        .or_default()
13126                        .insert(chunk, lsp_request_id);
13127                    if let Some((previous_request, running_requests)) =
13128                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13129                    {
13130                        running_requests.remove(&previous_request);
13131                    }
13132                }
13133                _ambiguous_chunks => {
13134                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13135                    // there, a buffer version-based check will be performed and outdated requests discarded.
13136                }
13137            }
13138            anyhow::Ok(())
13139        })?;
13140
13141        Ok(())
13142    }
13143
13144    async fn query_lsp_locally<T>(
13145        lsp_store: Entity<Self>,
13146        for_server_id: Option<LanguageServerId>,
13147        sender_id: proto::PeerId,
13148        lsp_request_id: LspRequestId,
13149        proto_request: T::ProtoRequest,
13150        position: Option<Anchor>,
13151        cx: &mut AsyncApp,
13152    ) -> Result<()>
13153    where
13154        T: LspCommand + Clone,
13155        T::ProtoRequest: proto::LspRequestMessage,
13156        <T::ProtoRequest as proto::RequestMessage>::Response:
13157            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13158    {
13159        let (buffer_version, buffer) =
13160            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
13161        let request =
13162            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13163        let key = LspKey {
13164            request_type: TypeId::of::<T>(),
13165            server_queried: for_server_id,
13166        };
13167        lsp_store.update(cx, |lsp_store, cx| {
13168            let request_task = match for_server_id {
13169                Some(server_id) => {
13170                    let server_task = lsp_store.request_lsp(
13171                        buffer.clone(),
13172                        LanguageServerToQuery::Other(server_id),
13173                        request.clone(),
13174                        cx,
13175                    );
13176                    cx.background_spawn(async move {
13177                        let mut responses = Vec::new();
13178                        match server_task.await {
13179                            Ok(response) => responses.push((server_id, response)),
13180                            // rust-analyzer likes to error with this when its still loading up
13181                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13182                            Err(e) => log::error!(
13183                                "Error handling response for request {request:?}: {e:#}"
13184                            ),
13185                        }
13186                        responses
13187                    })
13188                }
13189                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13190            };
13191            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13192            if T::ProtoRequest::stop_previous_requests() {
13193                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13194                    lsp_requests.clear();
13195                }
13196            }
13197            lsp_data.lsp_requests.entry(key).or_default().insert(
13198                lsp_request_id,
13199                cx.spawn(async move |lsp_store, cx| {
13200                    let response = request_task.await;
13201                    lsp_store
13202                        .update(cx, |lsp_store, cx| {
13203                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13204                            {
13205                                let response = response
13206                                    .into_iter()
13207                                    .map(|(server_id, response)| {
13208                                        (
13209                                            server_id.to_proto(),
13210                                            T::response_to_proto(
13211                                                response,
13212                                                lsp_store,
13213                                                sender_id,
13214                                                &buffer_version,
13215                                                cx,
13216                                            )
13217                                            .into(),
13218                                        )
13219                                    })
13220                                    .collect::<HashMap<_, _>>();
13221                                match client.send_lsp_response::<T::ProtoRequest>(
13222                                    project_id,
13223                                    lsp_request_id,
13224                                    response,
13225                                ) {
13226                                    Ok(()) => {}
13227                                    Err(e) => {
13228                                        log::error!("Failed to send LSP response: {e:#}",)
13229                                    }
13230                                }
13231                            }
13232                        })
13233                        .ok();
13234                }),
13235            );
13236        });
13237        Ok(())
13238    }
13239
13240    async fn wait_for_buffer_version<T>(
13241        lsp_store: &Entity<Self>,
13242        proto_request: &T::ProtoRequest,
13243        cx: &mut AsyncApp,
13244    ) -> Result<(Global, Entity<Buffer>)>
13245    where
13246        T: LspCommand,
13247        T::ProtoRequest: proto::LspRequestMessage,
13248    {
13249        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13250        let version = deserialize_version(proto_request.buffer_version());
13251        let buffer = lsp_store.update(cx, |this, cx| {
13252            this.buffer_store.read(cx).get_existing(buffer_id)
13253        })?;
13254        buffer
13255            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13256            .await?;
13257        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13258        Ok((buffer_version, buffer))
13259    }
13260
13261    fn take_text_document_sync_options(
13262        capabilities: &mut lsp::ServerCapabilities,
13263    ) -> lsp::TextDocumentSyncOptions {
13264        match capabilities.text_document_sync.take() {
13265            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13266            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13267                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13268                sync_options.change = Some(sync_kind);
13269                sync_options
13270            }
13271            None => lsp::TextDocumentSyncOptions::default(),
13272        }
13273    }
13274
13275    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13276        self.downstream_client.clone()
13277    }
13278
13279    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13280        self.worktree_store.clone()
13281    }
13282
13283    /// Gets what's stored in the LSP data for the given buffer.
13284    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13285        self.lsp_data.get_mut(&buffer_id)
13286    }
13287
13288    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13289    /// new [`BufferLspData`] will be created to replace the previous state.
13290    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13291        let (buffer_id, buffer_version) =
13292            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13293        let lsp_data = self
13294            .lsp_data
13295            .entry(buffer_id)
13296            .or_insert_with(|| BufferLspData::new(buffer, cx));
13297        if buffer_version.changed_since(&lsp_data.buffer_version) {
13298            // To send delta requests for semantic tokens, the previous tokens
13299            // need to be kept between buffer changes.
13300            let semantic_tokens = lsp_data.semantic_tokens.take();
13301            *lsp_data = BufferLspData::new(buffer, cx);
13302            lsp_data.semantic_tokens = semantic_tokens;
13303        }
13304        lsp_data
13305    }
13306}
13307
13308// Registration with registerOptions as null, should fallback to true.
13309// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13310fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13311    reg: lsp::Registration,
13312) -> Result<OneOf<bool, T>> {
13313    Ok(match reg.register_options {
13314        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13315        None => OneOf::Left(true),
13316    })
13317}
13318
13319fn subscribe_to_binary_statuses(
13320    languages: &Arc<LanguageRegistry>,
13321    cx: &mut Context<'_, LspStore>,
13322) -> Task<()> {
13323    let mut server_statuses = languages.language_server_binary_statuses();
13324    cx.spawn(async move |lsp_store, cx| {
13325        while let Some((server_name, binary_status)) = server_statuses.next().await {
13326            if lsp_store
13327                .update(cx, |_, cx| {
13328                    let mut message = None;
13329                    let binary_status = match binary_status {
13330                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13331                        BinaryStatus::CheckingForUpdate => {
13332                            proto::ServerBinaryStatus::CheckingForUpdate
13333                        }
13334                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13335                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13336                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13337                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13338                        BinaryStatus::Failed { error } => {
13339                            message = Some(error);
13340                            proto::ServerBinaryStatus::Failed
13341                        }
13342                    };
13343                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13344                        // Binary updates are about the binary that might not have any language server id at that point.
13345                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13346                        language_server_id: LanguageServerId(0),
13347                        name: Some(server_name),
13348                        message: proto::update_language_server::Variant::StatusUpdate(
13349                            proto::StatusUpdate {
13350                                message,
13351                                status: Some(proto::status_update::Status::Binary(
13352                                    binary_status as i32,
13353                                )),
13354                            },
13355                        ),
13356                    });
13357                })
13358                .is_err()
13359            {
13360                break;
13361            }
13362        }
13363    })
13364}
13365
13366fn lsp_workspace_diagnostics_refresh(
13367    registration_id: Option<String>,
13368    options: DiagnosticServerCapabilities,
13369    server: Arc<LanguageServer>,
13370    cx: &mut Context<'_, LspStore>,
13371) -> Option<WorkspaceRefreshTask> {
13372    let identifier = workspace_diagnostic_identifier(&options)?;
13373    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13374
13375    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13376    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13377    refresh_tx.try_send(()).ok();
13378
13379    let request_timeout = ProjectSettings::get_global(cx)
13380        .global_lsp_settings
13381        .get_request_timeout();
13382
13383    // 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.
13384    // This allows users to increase the duration if need be
13385    let timeout = if request_timeout != Duration::ZERO {
13386        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13387    } else {
13388        request_timeout
13389    };
13390
13391    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13392        let mut attempts = 0;
13393        let max_attempts = 50;
13394        let mut requests = 0;
13395
13396        loop {
13397            let Some(()) = refresh_rx.recv().await else {
13398                return;
13399            };
13400
13401            'request: loop {
13402                requests += 1;
13403                if attempts > max_attempts {
13404                    log::error!(
13405                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13406                    );
13407                    return;
13408                }
13409                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13410                cx.background_executor()
13411                    .timer(Duration::from_millis(backoff_millis))
13412                    .await;
13413                attempts += 1;
13414
13415                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13416                    lsp_store
13417                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13418                        .into_iter()
13419                        .filter_map(|(abs_path, result_id)| {
13420                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13421                            Some(lsp::PreviousResultId {
13422                                uri,
13423                                value: result_id.to_string(),
13424                            })
13425                        })
13426                        .collect()
13427                }) else {
13428                    return;
13429                };
13430
13431                let token = if let Some(registration_id) = &registration_id {
13432                    format!(
13433                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13434                        server.server_id(),
13435                    )
13436                } else {
13437                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13438                };
13439
13440                progress_rx.try_recv().ok();
13441                let timer = server.request_timer(timeout).fuse();
13442                let progress = pin!(progress_rx.recv().fuse());
13443                let response_result = server
13444                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13445                        lsp::WorkspaceDiagnosticParams {
13446                            previous_result_ids,
13447                            identifier: identifier.clone(),
13448                            work_done_progress_params: Default::default(),
13449                            partial_result_params: lsp::PartialResultParams {
13450                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13451                            },
13452                        },
13453                        select(timer, progress).then(|either| match either {
13454                            Either::Left((message, ..)) => ready(message).left_future(),
13455                            Either::Right(..) => pending::<String>().right_future(),
13456                        }),
13457                    )
13458                    .await;
13459
13460                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13461                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13462                match response_result {
13463                    ConnectionResult::Timeout => {
13464                        log::error!("Timeout during workspace diagnostics pull");
13465                        continue 'request;
13466                    }
13467                    ConnectionResult::ConnectionReset => {
13468                        log::error!("Server closed a workspace diagnostics pull request");
13469                        continue 'request;
13470                    }
13471                    ConnectionResult::Result(Err(e)) => {
13472                        log::error!("Error during workspace diagnostics pull: {e:#}");
13473                        break 'request;
13474                    }
13475                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13476                        attempts = 0;
13477                        if lsp_store
13478                            .update(cx, |lsp_store, cx| {
13479                                lsp_store.apply_workspace_diagnostic_report(
13480                                    server.server_id(),
13481                                    pulled_diagnostics,
13482                                    registration_id_shared.clone(),
13483                                    cx,
13484                                )
13485                            })
13486                            .is_err()
13487                        {
13488                            return;
13489                        }
13490                        break 'request;
13491                    }
13492                }
13493            }
13494        }
13495    });
13496
13497    Some(WorkspaceRefreshTask {
13498        refresh_tx,
13499        progress_tx,
13500        task: workspace_query_language_server,
13501    })
13502}
13503
13504fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13505    match &options {
13506        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13507            .identifier
13508            .as_deref()
13509            .map(SharedString::new),
13510        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13511            let diagnostic_options = &registration_options.diagnostic_options;
13512            diagnostic_options
13513                .identifier
13514                .as_deref()
13515                .map(SharedString::new)
13516        }
13517    }
13518}
13519
13520fn workspace_diagnostic_identifier(
13521    options: &DiagnosticServerCapabilities,
13522) -> Option<Option<String>> {
13523    match &options {
13524        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13525            if !diagnostic_options.workspace_diagnostics {
13526                return None;
13527            }
13528            Some(diagnostic_options.identifier.clone())
13529        }
13530        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13531            let diagnostic_options = &registration_options.diagnostic_options;
13532            if !diagnostic_options.workspace_diagnostics {
13533                return None;
13534            }
13535            Some(diagnostic_options.identifier.clone())
13536        }
13537    }
13538}
13539
13540fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13541    let CompletionSource::BufferWord {
13542        word_range,
13543        resolved,
13544    } = &mut completion.source
13545    else {
13546        return;
13547    };
13548    if *resolved {
13549        return;
13550    }
13551
13552    if completion.new_text
13553        != snapshot
13554            .text_for_range(word_range.clone())
13555            .collect::<String>()
13556    {
13557        return;
13558    }
13559
13560    let mut offset = 0;
13561    for chunk in snapshot.chunks(word_range.clone(), true) {
13562        let end_offset = offset + chunk.text.len();
13563        if let Some(highlight_id) = chunk.syntax_highlight_id {
13564            completion
13565                .label
13566                .runs
13567                .push((offset..end_offset, highlight_id));
13568        }
13569        offset = end_offset;
13570    }
13571    *resolved = true;
13572}
13573
13574impl EventEmitter<LspStoreEvent> for LspStore {}
13575
13576fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13577    hover
13578        .contents
13579        .retain(|hover_block| !hover_block.text.trim().is_empty());
13580    if hover.contents.is_empty() {
13581        None
13582    } else {
13583        Some(hover)
13584    }
13585}
13586
13587async fn populate_labels_for_completions(
13588    new_completions: Vec<CoreCompletion>,
13589    language: Option<Arc<Language>>,
13590    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13591) -> Vec<Completion> {
13592    let lsp_completions = new_completions
13593        .iter()
13594        .filter_map(|new_completion| {
13595            new_completion
13596                .source
13597                .lsp_completion(true)
13598                .map(|lsp_completion| lsp_completion.into_owned())
13599        })
13600        .collect::<Vec<_>>();
13601
13602    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13603        lsp_adapter
13604            .labels_for_completions(&lsp_completions, language)
13605            .await
13606            .log_err()
13607            .unwrap_or_default()
13608    } else {
13609        Vec::new()
13610    }
13611    .into_iter()
13612    .fuse();
13613
13614    let mut completions = Vec::new();
13615    for completion in new_completions {
13616        match completion.source.lsp_completion(true) {
13617            Some(lsp_completion) => {
13618                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13619
13620                let mut label = labels.next().flatten().unwrap_or_else(|| {
13621                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13622                });
13623                ensure_uniform_list_compatible_label(&mut label);
13624                completions.push(Completion {
13625                    label,
13626                    documentation,
13627                    replace_range: completion.replace_range,
13628                    new_text: completion.new_text,
13629                    insert_text_mode: lsp_completion.insert_text_mode,
13630                    source: completion.source,
13631                    icon_path: None,
13632                    confirm: None,
13633                    match_start: None,
13634                    snippet_deduplication_key: None,
13635                });
13636            }
13637            None => {
13638                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13639                ensure_uniform_list_compatible_label(&mut label);
13640                completions.push(Completion {
13641                    label,
13642                    documentation: None,
13643                    replace_range: completion.replace_range,
13644                    new_text: completion.new_text,
13645                    source: completion.source,
13646                    insert_text_mode: None,
13647                    icon_path: None,
13648                    confirm: None,
13649                    match_start: None,
13650                    snippet_deduplication_key: None,
13651                });
13652            }
13653        }
13654    }
13655    completions
13656}
13657
13658#[derive(Debug)]
13659pub enum LanguageServerToQuery {
13660    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13661    FirstCapable,
13662    /// Query a specific language server.
13663    Other(LanguageServerId),
13664}
13665
13666#[derive(Default)]
13667struct RenamePathsWatchedForServer {
13668    did_rename: Vec<RenameActionPredicate>,
13669    will_rename: Vec<RenameActionPredicate>,
13670}
13671
13672impl RenamePathsWatchedForServer {
13673    fn with_did_rename_patterns(
13674        mut self,
13675        did_rename: Option<&FileOperationRegistrationOptions>,
13676    ) -> Self {
13677        if let Some(did_rename) = did_rename {
13678            self.did_rename = did_rename
13679                .filters
13680                .iter()
13681                .filter_map(|filter| filter.try_into().log_err())
13682                .collect();
13683        }
13684        self
13685    }
13686    fn with_will_rename_patterns(
13687        mut self,
13688        will_rename: Option<&FileOperationRegistrationOptions>,
13689    ) -> Self {
13690        if let Some(will_rename) = will_rename {
13691            self.will_rename = will_rename
13692                .filters
13693                .iter()
13694                .filter_map(|filter| filter.try_into().log_err())
13695                .collect();
13696        }
13697        self
13698    }
13699
13700    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13701        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13702    }
13703    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13704        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13705    }
13706}
13707
13708impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13709    type Error = globset::Error;
13710    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13711        Ok(Self {
13712            kind: ops.pattern.matches.clone(),
13713            glob: GlobBuilder::new(&ops.pattern.glob)
13714                .case_insensitive(
13715                    ops.pattern
13716                        .options
13717                        .as_ref()
13718                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13719                )
13720                .build()?
13721                .compile_matcher(),
13722        })
13723    }
13724}
13725struct RenameActionPredicate {
13726    glob: GlobMatcher,
13727    kind: Option<FileOperationPatternKind>,
13728}
13729
13730impl RenameActionPredicate {
13731    // Returns true if language server should be notified
13732    fn eval(&self, path: &str, is_dir: bool) -> bool {
13733        self.kind.as_ref().is_none_or(|kind| {
13734            let expected_kind = if is_dir {
13735                FileOperationPatternKind::Folder
13736            } else {
13737                FileOperationPatternKind::File
13738            };
13739            kind == &expected_kind
13740        }) && self.glob.is_match(path)
13741    }
13742}
13743
13744#[derive(Default)]
13745struct LanguageServerWatchedPaths {
13746    worktree_paths: HashMap<WorktreeId, GlobSet>,
13747    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13748}
13749
13750#[derive(Default)]
13751struct LanguageServerWatchedPathsBuilder {
13752    worktree_paths: HashMap<WorktreeId, GlobSet>,
13753    abs_paths: HashMap<Arc<Path>, GlobSet>,
13754}
13755
13756impl LanguageServerWatchedPathsBuilder {
13757    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13758        self.worktree_paths.insert(worktree_id, glob_set);
13759    }
13760    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13761        self.abs_paths.insert(path, glob_set);
13762    }
13763    fn build(
13764        self,
13765        fs: Arc<dyn Fs>,
13766        language_server_id: LanguageServerId,
13767        cx: &mut Context<LspStore>,
13768    ) -> LanguageServerWatchedPaths {
13769        let lsp_store = cx.weak_entity();
13770
13771        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13772        let abs_paths = self
13773            .abs_paths
13774            .into_iter()
13775            .map(|(abs_path, globset)| {
13776                let task = cx.spawn({
13777                    let abs_path = abs_path.clone();
13778                    let fs = fs.clone();
13779
13780                    let lsp_store = lsp_store.clone();
13781                    async move |_, cx| {
13782                        maybe!(async move {
13783                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13784                            while let Some(update) = push_updates.0.next().await {
13785                                let action = lsp_store
13786                                    .update(cx, |this, _| {
13787                                        let Some(local) = this.as_local() else {
13788                                            return ControlFlow::Break(());
13789                                        };
13790                                        let Some(watcher) = local
13791                                            .language_server_watched_paths
13792                                            .get(&language_server_id)
13793                                        else {
13794                                            return ControlFlow::Break(());
13795                                        };
13796                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13797                                            "Watched abs path is not registered with a watcher",
13798                                        );
13799                                        let matching_entries = update
13800                                            .into_iter()
13801                                            .filter(|event| globs.is_match(&event.path))
13802                                            .collect::<Vec<_>>();
13803                                        this.lsp_notify_abs_paths_changed(
13804                                            language_server_id,
13805                                            matching_entries,
13806                                        );
13807                                        ControlFlow::Continue(())
13808                                    })
13809                                    .ok()?;
13810
13811                                if action.is_break() {
13812                                    break;
13813                                }
13814                            }
13815                            Some(())
13816                        })
13817                        .await;
13818                    }
13819                });
13820                (abs_path, (globset, task))
13821            })
13822            .collect();
13823        LanguageServerWatchedPaths {
13824            worktree_paths: self.worktree_paths,
13825            abs_paths,
13826        }
13827    }
13828}
13829
13830struct LspBufferSnapshot {
13831    version: i32,
13832    snapshot: TextBufferSnapshot,
13833}
13834
13835/// A prompt requested by LSP server.
13836#[derive(Clone, Debug)]
13837pub struct LanguageServerPromptRequest {
13838    pub id: usize,
13839    pub level: PromptLevel,
13840    pub message: String,
13841    pub actions: Vec<MessageActionItem>,
13842    pub lsp_name: String,
13843    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13844}
13845
13846impl LanguageServerPromptRequest {
13847    pub fn new(
13848        level: PromptLevel,
13849        message: String,
13850        actions: Vec<MessageActionItem>,
13851        lsp_name: String,
13852        response_channel: smol::channel::Sender<MessageActionItem>,
13853    ) -> Self {
13854        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13855        LanguageServerPromptRequest {
13856            id,
13857            level,
13858            message,
13859            actions,
13860            lsp_name,
13861            response_channel,
13862        }
13863    }
13864    pub async fn respond(self, index: usize) -> Option<()> {
13865        if let Some(response) = self.actions.into_iter().nth(index) {
13866            self.response_channel.send(response).await.ok()
13867        } else {
13868            None
13869        }
13870    }
13871
13872    #[cfg(any(test, feature = "test-support"))]
13873    pub fn test(
13874        level: PromptLevel,
13875        message: String,
13876        actions: Vec<MessageActionItem>,
13877        lsp_name: String,
13878    ) -> Self {
13879        let (tx, _rx) = smol::channel::unbounded();
13880        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13881    }
13882}
13883impl PartialEq for LanguageServerPromptRequest {
13884    fn eq(&self, other: &Self) -> bool {
13885        self.message == other.message && self.actions == other.actions
13886    }
13887}
13888
13889#[derive(Clone, Debug, PartialEq)]
13890pub enum LanguageServerLogType {
13891    Log(MessageType),
13892    Trace { verbose_info: Option<String> },
13893    Rpc { received: bool },
13894}
13895
13896impl LanguageServerLogType {
13897    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13898        match self {
13899            Self::Log(log_type) => {
13900                use proto::log_message::LogLevel;
13901                let level = match *log_type {
13902                    MessageType::ERROR => LogLevel::Error,
13903                    MessageType::WARNING => LogLevel::Warning,
13904                    MessageType::INFO => LogLevel::Info,
13905                    MessageType::LOG => LogLevel::Log,
13906                    other => {
13907                        log::warn!("Unknown lsp log message type: {other:?}");
13908                        LogLevel::Log
13909                    }
13910                };
13911                proto::language_server_log::LogType::Log(proto::LogMessage {
13912                    level: level as i32,
13913                })
13914            }
13915            Self::Trace { verbose_info } => {
13916                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13917                    verbose_info: verbose_info.to_owned(),
13918                })
13919            }
13920            Self::Rpc { received } => {
13921                let kind = if *received {
13922                    proto::rpc_message::Kind::Received
13923                } else {
13924                    proto::rpc_message::Kind::Sent
13925                };
13926                let kind = kind as i32;
13927                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13928            }
13929        }
13930    }
13931
13932    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13933        use proto::log_message::LogLevel;
13934        use proto::rpc_message;
13935        match log_type {
13936            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13937                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13938                    LogLevel::Error => MessageType::ERROR,
13939                    LogLevel::Warning => MessageType::WARNING,
13940                    LogLevel::Info => MessageType::INFO,
13941                    LogLevel::Log => MessageType::LOG,
13942                },
13943            ),
13944            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13945                verbose_info: trace_message.verbose_info,
13946            },
13947            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13948                received: match rpc_message::Kind::from_i32(message.kind)
13949                    .unwrap_or(rpc_message::Kind::Received)
13950                {
13951                    rpc_message::Kind::Received => true,
13952                    rpc_message::Kind::Sent => false,
13953                },
13954            },
13955        }
13956    }
13957}
13958
13959pub struct WorkspaceRefreshTask {
13960    refresh_tx: mpsc::Sender<()>,
13961    progress_tx: mpsc::Sender<()>,
13962    #[allow(dead_code)]
13963    task: Task<()>,
13964}
13965
13966pub enum LanguageServerState {
13967    Starting {
13968        startup: Task<Option<Arc<LanguageServer>>>,
13969        /// List of language servers that will be added to the workspace once it's initialization completes.
13970        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13971    },
13972
13973    Running {
13974        adapter: Arc<CachedLspAdapter>,
13975        server: Arc<LanguageServer>,
13976        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13977        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13978    },
13979}
13980
13981impl LanguageServerState {
13982    fn add_workspace_folder(&self, uri: Uri) {
13983        match self {
13984            LanguageServerState::Starting {
13985                pending_workspace_folders,
13986                ..
13987            } => {
13988                pending_workspace_folders.lock().insert(uri);
13989            }
13990            LanguageServerState::Running { server, .. } => {
13991                server.add_workspace_folder(uri);
13992            }
13993        }
13994    }
13995    fn _remove_workspace_folder(&self, uri: Uri) {
13996        match self {
13997            LanguageServerState::Starting {
13998                pending_workspace_folders,
13999                ..
14000            } => {
14001                pending_workspace_folders.lock().remove(&uri);
14002            }
14003            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
14004        }
14005    }
14006}
14007
14008impl std::fmt::Debug for LanguageServerState {
14009    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14010        match self {
14011            LanguageServerState::Starting { .. } => {
14012                f.debug_struct("LanguageServerState::Starting").finish()
14013            }
14014            LanguageServerState::Running { .. } => {
14015                f.debug_struct("LanguageServerState::Running").finish()
14016            }
14017        }
14018    }
14019}
14020
14021#[derive(Clone, Debug, Serialize)]
14022pub struct LanguageServerProgress {
14023    pub is_disk_based_diagnostics_progress: bool,
14024    pub is_cancellable: bool,
14025    pub title: Option<String>,
14026    pub message: Option<String>,
14027    pub percentage: Option<usize>,
14028    #[serde(skip_serializing)]
14029    pub last_update_at: Instant,
14030}
14031
14032#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
14033pub struct DiagnosticSummary {
14034    pub error_count: usize,
14035    pub warning_count: usize,
14036}
14037
14038impl DiagnosticSummary {
14039    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
14040        let mut this = Self {
14041            error_count: 0,
14042            warning_count: 0,
14043        };
14044
14045        for entry in diagnostics {
14046            if entry.diagnostic.is_primary {
14047                match entry.diagnostic.severity {
14048                    DiagnosticSeverity::ERROR => this.error_count += 1,
14049                    DiagnosticSeverity::WARNING => this.warning_count += 1,
14050                    _ => {}
14051                }
14052            }
14053        }
14054
14055        this
14056    }
14057
14058    pub fn is_empty(&self) -> bool {
14059        self.error_count == 0 && self.warning_count == 0
14060    }
14061
14062    pub fn to_proto(
14063        self,
14064        language_server_id: LanguageServerId,
14065        path: &RelPath,
14066    ) -> proto::DiagnosticSummary {
14067        proto::DiagnosticSummary {
14068            path: path.to_proto(),
14069            language_server_id: language_server_id.0 as u64,
14070            error_count: self.error_count as u32,
14071            warning_count: self.warning_count as u32,
14072        }
14073    }
14074}
14075
14076#[derive(Clone, Debug)]
14077pub enum CompletionDocumentation {
14078    /// There is no documentation for this completion.
14079    Undocumented,
14080    /// A single line of documentation.
14081    SingleLine(SharedString),
14082    /// Multiple lines of plain text documentation.
14083    MultiLinePlainText(SharedString),
14084    /// Markdown documentation.
14085    MultiLineMarkdown(SharedString),
14086    /// Both single line and multiple lines of plain text documentation.
14087    SingleLineAndMultiLinePlainText {
14088        single_line: SharedString,
14089        plain_text: Option<SharedString>,
14090    },
14091}
14092
14093impl CompletionDocumentation {
14094    #[cfg(any(test, feature = "test-support"))]
14095    pub fn text(&self) -> SharedString {
14096        match self {
14097            CompletionDocumentation::Undocumented => "".into(),
14098            CompletionDocumentation::SingleLine(s) => s.clone(),
14099            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
14100            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
14101            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
14102                single_line.clone()
14103            }
14104        }
14105    }
14106}
14107
14108impl From<lsp::Documentation> for CompletionDocumentation {
14109    fn from(docs: lsp::Documentation) -> Self {
14110        match docs {
14111            lsp::Documentation::String(text) => {
14112                if text.lines().count() <= 1 {
14113                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
14114                } else {
14115                    CompletionDocumentation::MultiLinePlainText(text.into())
14116                }
14117            }
14118
14119            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
14120                lsp::MarkupKind::PlainText => {
14121                    if value.lines().count() <= 1 {
14122                        CompletionDocumentation::SingleLine(value.into())
14123                    } else {
14124                        CompletionDocumentation::MultiLinePlainText(value.into())
14125                    }
14126                }
14127
14128                lsp::MarkupKind::Markdown => {
14129                    CompletionDocumentation::MultiLineMarkdown(value.into())
14130                }
14131            },
14132        }
14133    }
14134}
14135
14136pub enum ResolvedHint {
14137    Resolved(InlayHint),
14138    Resolving(Shared<Task<()>>),
14139}
14140
14141pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
14142    glob.components()
14143        .take_while(|component| match component {
14144            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
14145            _ => true,
14146        })
14147        .collect()
14148}
14149
14150pub struct SshLspAdapter {
14151    name: LanguageServerName,
14152    binary: LanguageServerBinary,
14153    initialization_options: Option<String>,
14154    code_action_kinds: Option<Vec<CodeActionKind>>,
14155}
14156
14157impl SshLspAdapter {
14158    pub fn new(
14159        name: LanguageServerName,
14160        binary: LanguageServerBinary,
14161        initialization_options: Option<String>,
14162        code_action_kinds: Option<String>,
14163    ) -> Self {
14164        Self {
14165            name,
14166            binary,
14167            initialization_options,
14168            code_action_kinds: code_action_kinds
14169                .as_ref()
14170                .and_then(|c| serde_json::from_str(c).ok()),
14171        }
14172    }
14173}
14174
14175impl LspInstaller for SshLspAdapter {
14176    type BinaryVersion = ();
14177    async fn check_if_user_installed(
14178        &self,
14179        _: &dyn LspAdapterDelegate,
14180        _: Option<Toolchain>,
14181        _: &AsyncApp,
14182    ) -> Option<LanguageServerBinary> {
14183        Some(self.binary.clone())
14184    }
14185
14186    async fn cached_server_binary(
14187        &self,
14188        _: PathBuf,
14189        _: &dyn LspAdapterDelegate,
14190    ) -> Option<LanguageServerBinary> {
14191        None
14192    }
14193
14194    async fn fetch_latest_server_version(
14195        &self,
14196        _: &dyn LspAdapterDelegate,
14197        _: bool,
14198        _: &mut AsyncApp,
14199    ) -> Result<()> {
14200        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14201    }
14202
14203    async fn fetch_server_binary(
14204        &self,
14205        _: (),
14206        _: PathBuf,
14207        _: &dyn LspAdapterDelegate,
14208    ) -> Result<LanguageServerBinary> {
14209        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14210    }
14211}
14212
14213#[async_trait(?Send)]
14214impl LspAdapter for SshLspAdapter {
14215    fn name(&self) -> LanguageServerName {
14216        self.name.clone()
14217    }
14218
14219    async fn initialization_options(
14220        self: Arc<Self>,
14221        _: &Arc<dyn LspAdapterDelegate>,
14222        _: &mut AsyncApp,
14223    ) -> Result<Option<serde_json::Value>> {
14224        let Some(options) = &self.initialization_options else {
14225            return Ok(None);
14226        };
14227        let result = serde_json::from_str(options)?;
14228        Ok(result)
14229    }
14230
14231    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14232        self.code_action_kinds.clone()
14233    }
14234}
14235
14236pub fn language_server_settings<'a>(
14237    delegate: &'a dyn LspAdapterDelegate,
14238    language: &LanguageServerName,
14239    cx: &'a App,
14240) -> Option<&'a LspSettings> {
14241    language_server_settings_for(
14242        SettingsLocation {
14243            worktree_id: delegate.worktree_id(),
14244            path: RelPath::empty(),
14245        },
14246        language,
14247        cx,
14248    )
14249}
14250
14251pub fn language_server_settings_for<'a>(
14252    location: SettingsLocation<'a>,
14253    language: &LanguageServerName,
14254    cx: &'a App,
14255) -> Option<&'a LspSettings> {
14256    ProjectSettings::get(Some(location), cx).lsp.get(language)
14257}
14258
14259pub struct LocalLspAdapterDelegate {
14260    lsp_store: WeakEntity<LspStore>,
14261    worktree: worktree::Snapshot,
14262    fs: Arc<dyn Fs>,
14263    http_client: Arc<dyn HttpClient>,
14264    language_registry: Arc<LanguageRegistry>,
14265    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14266}
14267
14268impl LocalLspAdapterDelegate {
14269    pub fn new(
14270        language_registry: Arc<LanguageRegistry>,
14271        environment: &Entity<ProjectEnvironment>,
14272        lsp_store: WeakEntity<LspStore>,
14273        worktree: &Entity<Worktree>,
14274        http_client: Arc<dyn HttpClient>,
14275        fs: Arc<dyn Fs>,
14276        cx: &mut App,
14277    ) -> Arc<Self> {
14278        let load_shell_env_task =
14279            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14280
14281        Arc::new(Self {
14282            lsp_store,
14283            worktree: worktree.read(cx).snapshot(),
14284            fs,
14285            http_client,
14286            language_registry,
14287            load_shell_env_task,
14288        })
14289    }
14290
14291    pub fn from_local_lsp(
14292        local: &LocalLspStore,
14293        worktree: &Entity<Worktree>,
14294        cx: &mut App,
14295    ) -> Arc<Self> {
14296        Self::new(
14297            local.languages.clone(),
14298            &local.environment,
14299            local.weak.clone(),
14300            worktree,
14301            local.http_client.clone(),
14302            local.fs.clone(),
14303            cx,
14304        )
14305    }
14306}
14307
14308#[async_trait]
14309impl LspAdapterDelegate for LocalLspAdapterDelegate {
14310    fn show_notification(&self, message: &str, cx: &mut App) {
14311        self.lsp_store
14312            .update(cx, |_, cx| {
14313                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14314            })
14315            .ok();
14316    }
14317
14318    fn http_client(&self) -> Arc<dyn HttpClient> {
14319        self.http_client.clone()
14320    }
14321
14322    fn worktree_id(&self) -> WorktreeId {
14323        self.worktree.id()
14324    }
14325
14326    fn worktree_root_path(&self) -> &Path {
14327        self.worktree.abs_path().as_ref()
14328    }
14329
14330    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14331        self.worktree.resolve_relative_path(path)
14332    }
14333
14334    async fn shell_env(&self) -> HashMap<String, String> {
14335        let task = self.load_shell_env_task.clone();
14336        task.await.unwrap_or_default()
14337    }
14338
14339    async fn npm_package_installed_version(
14340        &self,
14341        package_name: &str,
14342    ) -> Result<Option<(PathBuf, Version)>> {
14343        let local_package_directory = self.worktree_root_path();
14344        let node_modules_directory = local_package_directory.join("node_modules");
14345
14346        if let Some(version) =
14347            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14348        {
14349            return Ok(Some((node_modules_directory, version)));
14350        }
14351        let Some(npm) = self.which("npm".as_ref()).await else {
14352            log::warn!(
14353                "Failed to find npm executable for {:?}",
14354                local_package_directory
14355            );
14356            return Ok(None);
14357        };
14358
14359        let env = self.shell_env().await;
14360        let output = util::command::new_command(&npm)
14361            .args(["root", "-g"])
14362            .envs(env)
14363            .current_dir(local_package_directory)
14364            .output()
14365            .await?;
14366        let global_node_modules =
14367            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14368
14369        if let Some(version) =
14370            read_package_installed_version(global_node_modules.clone(), package_name).await?
14371        {
14372            return Ok(Some((global_node_modules, version)));
14373        }
14374        return Ok(None);
14375    }
14376
14377    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14378        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14379        if self.fs.is_file(&worktree_abs_path).await {
14380            worktree_abs_path.pop();
14381        }
14382
14383        let env = self.shell_env().await;
14384
14385        let shell_path = env.get("PATH").cloned();
14386
14387        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14388    }
14389
14390    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14391        let mut working_dir = self.worktree_root_path().to_path_buf();
14392        if self.fs.is_file(&working_dir).await {
14393            working_dir.pop();
14394        }
14395        let output = util::command::new_command(&command.path)
14396            .args(command.arguments)
14397            .envs(command.env.clone().unwrap_or_default())
14398            .current_dir(working_dir)
14399            .output()
14400            .await?;
14401
14402        anyhow::ensure!(
14403            output.status.success(),
14404            "{}, stdout: {:?}, stderr: {:?}",
14405            output.status,
14406            String::from_utf8_lossy(&output.stdout),
14407            String::from_utf8_lossy(&output.stderr)
14408        );
14409        Ok(())
14410    }
14411
14412    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14413        self.language_registry
14414            .update_lsp_binary_status(server_name, status);
14415    }
14416
14417    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14418        self.language_registry
14419            .all_lsp_adapters()
14420            .into_iter()
14421            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14422            .collect()
14423    }
14424
14425    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14426        let dir = self.language_registry.language_server_download_dir(name)?;
14427
14428        if !dir.exists() {
14429            smol::fs::create_dir_all(&dir)
14430                .await
14431                .context("failed to create container directory")
14432                .log_err()?;
14433        }
14434
14435        Some(dir)
14436    }
14437
14438    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14439        let entry = self
14440            .worktree
14441            .entry_for_path(path)
14442            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14443        let abs_path = self.worktree.absolutize(&entry.path);
14444        self.fs.load(&abs_path).await
14445    }
14446}
14447
14448async fn populate_labels_for_symbols(
14449    symbols: Vec<CoreSymbol>,
14450    language_registry: &Arc<LanguageRegistry>,
14451    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14452    output: &mut Vec<Symbol>,
14453) {
14454    #[allow(clippy::mutable_key_type)]
14455    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14456
14457    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14458    for symbol in symbols {
14459        let Some(file_name) = symbol.path.file_name() else {
14460            continue;
14461        };
14462        let language = language_registry
14463            .load_language_for_file_path(Path::new(file_name))
14464            .await
14465            .ok()
14466            .or_else(|| {
14467                unknown_paths.insert(file_name.into());
14468                None
14469            });
14470        symbols_by_language
14471            .entry(language)
14472            .or_default()
14473            .push(symbol);
14474    }
14475
14476    for unknown_path in unknown_paths {
14477        log::info!("no language found for symbol in file {unknown_path:?}");
14478    }
14479
14480    let mut label_params = Vec::new();
14481    for (language, mut symbols) in symbols_by_language {
14482        label_params.clear();
14483        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14484            name: mem::take(&mut symbol.name),
14485            kind: symbol.kind,
14486            container_name: symbol.container_name.take(),
14487        }));
14488
14489        let mut labels = Vec::new();
14490        if let Some(language) = language {
14491            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14492                language_registry
14493                    .lsp_adapters(&language.name())
14494                    .first()
14495                    .cloned()
14496            });
14497            if let Some(lsp_adapter) = lsp_adapter {
14498                labels = lsp_adapter
14499                    .labels_for_symbols(&label_params, &language)
14500                    .await
14501                    .log_err()
14502                    .unwrap_or_default();
14503            }
14504        }
14505
14506        for (
14507            (
14508                symbol,
14509                language::Symbol {
14510                    name,
14511                    container_name,
14512                    ..
14513                },
14514            ),
14515            label,
14516        ) in symbols
14517            .into_iter()
14518            .zip(label_params.drain(..))
14519            .zip(labels.into_iter().chain(iter::repeat(None)))
14520        {
14521            output.push(Symbol {
14522                language_server_name: symbol.language_server_name,
14523                source_worktree_id: symbol.source_worktree_id,
14524                source_language_server_id: symbol.source_language_server_id,
14525                path: symbol.path,
14526                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14527                name,
14528                kind: symbol.kind,
14529                range: symbol.range,
14530                container_name,
14531            });
14532        }
14533    }
14534}
14535
14536pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String {
14537    text.lines()
14538        .map(|line| line.trim())
14539        .filter(|line| !line.is_empty())
14540        .join(separator)
14541}
14542
14543fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14544    match server.capabilities().text_document_sync.as_ref()? {
14545        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14546            // Server wants didSave but didn't specify includeText.
14547            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14548            // Server doesn't want didSave at all.
14549            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14550            // Server provided SaveOptions.
14551            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14552                Some(save_options.include_text.unwrap_or(false))
14553            }
14554        },
14555        // We do not have any save info. Kind affects didChange only.
14556        lsp::TextDocumentSyncCapability::Kind(_) => None,
14557    }
14558}
14559
14560/// Completion items are displayed in a `UniformList`.
14561/// Usually, those items are single-line strings, but in LSP responses,
14562/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14563/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14564/// 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,
14565/// breaking the completions menu presentation.
14566///
14567/// 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.
14568pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14569    let mut new_text = String::with_capacity(label.text.len());
14570    let mut offset_map = vec![0; label.text.len() + 1];
14571    let mut last_char_was_space = false;
14572    let mut new_idx = 0;
14573    let chars = label.text.char_indices().fuse();
14574    let mut newlines_removed = false;
14575
14576    for (idx, c) in chars {
14577        offset_map[idx] = new_idx;
14578
14579        match c {
14580            '\n' if last_char_was_space => {
14581                newlines_removed = true;
14582            }
14583            '\t' | ' ' if last_char_was_space => {}
14584            '\n' if !last_char_was_space => {
14585                new_text.push(' ');
14586                new_idx += 1;
14587                last_char_was_space = true;
14588                newlines_removed = true;
14589            }
14590            ' ' | '\t' => {
14591                new_text.push(' ');
14592                new_idx += 1;
14593                last_char_was_space = true;
14594            }
14595            _ => {
14596                new_text.push(c);
14597                new_idx += c.len_utf8();
14598                last_char_was_space = false;
14599            }
14600        }
14601    }
14602    offset_map[label.text.len()] = new_idx;
14603
14604    // Only modify the label if newlines were removed.
14605    if !newlines_removed {
14606        return;
14607    }
14608
14609    let last_index = new_idx;
14610    let mut run_ranges_errors = Vec::new();
14611    label.runs.retain_mut(|(range, _)| {
14612        match offset_map.get(range.start) {
14613            Some(&start) => range.start = start,
14614            None => {
14615                run_ranges_errors.push(range.clone());
14616                return false;
14617            }
14618        }
14619
14620        match offset_map.get(range.end) {
14621            Some(&end) => range.end = end,
14622            None => {
14623                run_ranges_errors.push(range.clone());
14624                range.end = last_index;
14625            }
14626        }
14627        true
14628    });
14629    if !run_ranges_errors.is_empty() {
14630        log::error!(
14631            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14632            label.text
14633        );
14634    }
14635
14636    let mut wrong_filter_range = None;
14637    if label.filter_range == (0..label.text.len()) {
14638        label.filter_range = 0..new_text.len();
14639    } else {
14640        let mut original_filter_range = Some(label.filter_range.clone());
14641        match offset_map.get(label.filter_range.start) {
14642            Some(&start) => label.filter_range.start = start,
14643            None => {
14644                wrong_filter_range = original_filter_range.take();
14645                label.filter_range.start = last_index;
14646            }
14647        }
14648
14649        match offset_map.get(label.filter_range.end) {
14650            Some(&end) => label.filter_range.end = end,
14651            None => {
14652                wrong_filter_range = original_filter_range.take();
14653                label.filter_range.end = last_index;
14654            }
14655        }
14656    }
14657    if let Some(wrong_filter_range) = wrong_filter_range {
14658        log::error!(
14659            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14660            label.text
14661        );
14662    }
14663
14664    label.text = new_text;
14665}
14666
14667/// Apply edits to the buffer that will become part of the formatting transaction.
14668/// Fails if the buffer has been edited since the start of that transaction.
14669fn extend_formatting_transaction(
14670    buffer: &FormattableBuffer,
14671    formatting_transaction_id: text::TransactionId,
14672    cx: &mut AsyncApp,
14673    operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
14674) -> anyhow::Result<()> {
14675    buffer.handle.update(cx, |buffer, cx| {
14676        let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
14677        if last_transaction_id != Some(formatting_transaction_id) {
14678            anyhow::bail!("Buffer edited while formatting. Aborting")
14679        }
14680        buffer.start_transaction();
14681        operation(buffer, cx);
14682        if let Some(transaction_id) = buffer.end_transaction(cx) {
14683            buffer.merge_transactions(transaction_id, formatting_transaction_id);
14684        }
14685        Ok(())
14686    })
14687}