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    Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language,
   75    LanguageName, LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller,
   76    ManifestDelegate, ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16,
   77    Toolchain, Transaction, Unclipped,
   78    language_settings::{
   79        AllLanguageSettings, FormatOnSave, Formatter, LanguageSettings, all_language_settings,
   80        language_settings,
   81    },
   82    point_to_lsp,
   83    proto::{
   84        deserialize_anchor, deserialize_anchor_range, deserialize_version, serialize_anchor,
   85        serialize_anchor_range, serialize_version,
   86    },
   87    range_from_lsp, range_to_lsp,
   88    row_chunk::RowChunk,
   89};
   90use lsp::{
   91    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   92    DEFAULT_LSP_REQUEST_TIMEOUT, DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   93    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   94    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LanguageServer,
   95    LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId, LanguageServerName,
   96    LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType, OneOf,
   97    RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles,
   98    WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   99};
  100use node_runtime::read_package_installed_version;
  101use parking_lot::Mutex;
  102use postage::{mpsc, sink::Sink, stream::Stream, watch};
  103use rand::prelude::*;
  104use rpc::{
  105    AnyProtoClient, ErrorCode, ErrorExt as _,
  106    proto::{LspRequestId, LspRequestMessage as _},
  107};
  108use semver::Version;
  109use serde::Serialize;
  110use serde_json::Value;
  111use settings::{Settings, SettingsLocation, SettingsStore};
  112use sha2::{Digest, Sha256};
  113use snippet::Snippet;
  114use std::{
  115    any::TypeId,
  116    borrow::Cow,
  117    cell::RefCell,
  118    cmp::{Ordering, Reverse},
  119    collections::{VecDeque, hash_map},
  120    convert::TryInto,
  121    ffi::OsStr,
  122    future::ready,
  123    iter, mem,
  124    ops::{ControlFlow, Range},
  125    path::{self, Path, PathBuf},
  126    pin::pin,
  127    rc::Rc,
  128    sync::{
  129        Arc,
  130        atomic::{self, AtomicUsize},
  131    },
  132    time::{Duration, Instant},
  133    vec,
  134};
  135use sum_tree::Dimensions;
  136use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  137
  138use util::{
  139    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  140    paths::{PathStyle, SanitizedPath, UrlExt},
  141    post_inc,
  142    redact::redact_command,
  143    rel_path::RelPath,
  144};
  145
  146pub use document_colors::DocumentColors;
  147pub use folding_ranges::LspFoldingRange;
  148pub use fs::*;
  149pub use language::Location;
  150pub use lsp_store::inlay_hints::{CacheInlayHints, InvalidationStrategy};
  151#[cfg(any(test, feature = "test-support"))]
  152pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  153pub use semantic_tokens::{
  154    BufferSemanticToken, BufferSemanticTokens, RefreshForServer, SemanticTokenStylizer, TokenType,
  155};
  156
  157pub use worktree::{
  158    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  159    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  160};
  161
  162const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  163pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  164const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  165const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  166static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  167
  168#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  169pub enum ProgressToken {
  170    Number(i32),
  171    String(SharedString),
  172}
  173
  174impl std::fmt::Display for ProgressToken {
  175    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  176        match self {
  177            Self::Number(number) => write!(f, "{number}"),
  178            Self::String(string) => write!(f, "{string}"),
  179        }
  180    }
  181}
  182
  183impl ProgressToken {
  184    fn from_lsp(value: lsp::NumberOrString) -> Self {
  185        match value {
  186            lsp::NumberOrString::Number(number) => Self::Number(number),
  187            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  188        }
  189    }
  190
  191    fn to_lsp(&self) -> lsp::NumberOrString {
  192        match self {
  193            Self::Number(number) => lsp::NumberOrString::Number(*number),
  194            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  195        }
  196    }
  197
  198    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  199        Some(match value.value? {
  200            proto::progress_token::Value::Number(number) => Self::Number(number),
  201            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  202        })
  203    }
  204
  205    fn to_proto(&self) -> proto::ProgressToken {
  206        proto::ProgressToken {
  207            value: Some(match self {
  208                Self::Number(number) => proto::progress_token::Value::Number(*number),
  209                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  210            }),
  211        }
  212    }
  213}
  214
  215#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  216pub enum FormatTrigger {
  217    Save,
  218    Manual,
  219}
  220
  221pub enum LspFormatTarget {
  222    Buffers,
  223    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  224}
  225
  226#[derive(Debug, Clone, PartialEq, Eq, Hash)]
  227pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  228
  229struct OpenLspBuffer(Entity<Buffer>);
  230
  231impl FormatTrigger {
  232    fn from_proto(value: i32) -> FormatTrigger {
  233        match value {
  234            0 => FormatTrigger::Save,
  235            1 => FormatTrigger::Manual,
  236            _ => FormatTrigger::Save,
  237        }
  238    }
  239}
  240
  241#[derive(Clone)]
  242struct UnifiedLanguageServer {
  243    id: LanguageServerId,
  244    project_roots: HashSet<Arc<RelPath>>,
  245}
  246
  247/// Settings that affect language server identity.
  248///
  249/// Dynamic settings (`LspSettings::settings`) are excluded because they can be
  250/// updated via `workspace/didChangeConfiguration` without restarting the server.
  251#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  252struct LanguageServerSeedSettings {
  253    binary: Option<BinarySettings>,
  254    initialization_options: Option<serde_json::Value>,
  255}
  256
  257#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  258struct LanguageServerSeed {
  259    worktree_id: WorktreeId,
  260    name: LanguageServerName,
  261    toolchain: Option<Toolchain>,
  262    settings: LanguageServerSeedSettings,
  263}
  264
  265#[derive(Debug)]
  266pub struct DocumentDiagnosticsUpdate<'a, D> {
  267    pub diagnostics: D,
  268    pub result_id: Option<SharedString>,
  269    pub registration_id: Option<SharedString>,
  270    pub server_id: LanguageServerId,
  271    pub disk_based_sources: Cow<'a, [String]>,
  272}
  273
  274pub struct DocumentDiagnostics {
  275    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  276    document_abs_path: PathBuf,
  277    version: Option<i32>,
  278}
  279
  280#[derive(Default, Debug)]
  281struct DynamicRegistrations {
  282    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  283    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  284}
  285
  286pub struct LocalLspStore {
  287    weak: WeakEntity<LspStore>,
  288    pub worktree_store: Entity<WorktreeStore>,
  289    toolchain_store: Entity<LocalToolchainStore>,
  290    http_client: Arc<dyn HttpClient>,
  291    environment: Entity<ProjectEnvironment>,
  292    fs: Arc<dyn Fs>,
  293    languages: Arc<LanguageRegistry>,
  294    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  295    yarn: Entity<YarnPathStore>,
  296    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  297    buffers_being_formatted: HashSet<BufferId>,
  298    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  299    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  300    watched_manifest_filenames: HashSet<ManifestName>,
  301    language_server_paths_watched_for_rename:
  302        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  303    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  304    supplementary_language_servers:
  305        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  306    prettier_store: Entity<PrettierStore>,
  307    next_diagnostic_group_id: usize,
  308    diagnostics: HashMap<
  309        WorktreeId,
  310        HashMap<
  311            Arc<RelPath>,
  312            Vec<(
  313                LanguageServerId,
  314                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  315            )>,
  316        >,
  317    >,
  318    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  319    _subscription: gpui::Subscription,
  320    lsp_tree: LanguageServerTree,
  321    registered_buffers: HashMap<BufferId, usize>,
  322    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  323    buffer_pull_diagnostics_result_ids: HashMap<
  324        LanguageServerId,
  325        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  326    >,
  327    workspace_pull_diagnostics_result_ids: HashMap<
  328        LanguageServerId,
  329        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  330    >,
  331    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  332
  333    buffers_to_refresh_hash_set: HashSet<BufferId>,
  334    buffers_to_refresh_queue: VecDeque<BufferId>,
  335    _background_diagnostics_worker: Shared<Task<()>>,
  336}
  337
  338impl LocalLspStore {
  339    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  340    pub fn running_language_server_for_id(
  341        &self,
  342        id: LanguageServerId,
  343    ) -> Option<&Arc<LanguageServer>> {
  344        let language_server_state = self.language_servers.get(&id)?;
  345
  346        match language_server_state {
  347            LanguageServerState::Running { server, .. } => Some(server),
  348            LanguageServerState::Starting { .. } => None,
  349        }
  350    }
  351
  352    fn get_or_insert_language_server(
  353        &mut self,
  354        worktree_handle: &Entity<Worktree>,
  355        delegate: Arc<LocalLspAdapterDelegate>,
  356        disposition: &Arc<LaunchDisposition>,
  357        language_name: &LanguageName,
  358        cx: &mut App,
  359    ) -> LanguageServerId {
  360        let key = LanguageServerSeed {
  361            worktree_id: worktree_handle.read(cx).id(),
  362            name: disposition.server_name.clone(),
  363            settings: LanguageServerSeedSettings {
  364                binary: disposition.settings.binary.clone(),
  365                initialization_options: disposition.settings.initialization_options.clone(),
  366            },
  367            toolchain: disposition.toolchain.clone(),
  368        };
  369        if let Some(state) = self.language_server_ids.get_mut(&key) {
  370            state.project_roots.insert(disposition.path.path.clone());
  371            state.id
  372        } else {
  373            let adapter = self
  374                .languages
  375                .lsp_adapters(language_name)
  376                .into_iter()
  377                .find(|adapter| adapter.name() == disposition.server_name)
  378                .expect("To find LSP adapter");
  379            let new_language_server_id = self.start_language_server(
  380                worktree_handle,
  381                delegate,
  382                adapter,
  383                disposition.settings.clone(),
  384                key.clone(),
  385                language_name.clone(),
  386                cx,
  387            );
  388            if let Some(state) = self.language_server_ids.get_mut(&key) {
  389                state.project_roots.insert(disposition.path.path.clone());
  390            } else {
  391                debug_assert!(
  392                    false,
  393                    "Expected `start_language_server` to ensure that `key` exists in a map"
  394                );
  395            }
  396            new_language_server_id
  397        }
  398    }
  399
  400    fn start_language_server(
  401        &mut self,
  402        worktree_handle: &Entity<Worktree>,
  403        delegate: Arc<LocalLspAdapterDelegate>,
  404        adapter: Arc<CachedLspAdapter>,
  405        settings: Arc<LspSettings>,
  406        key: LanguageServerSeed,
  407        language_name: LanguageName,
  408        cx: &mut App,
  409    ) -> LanguageServerId {
  410        let worktree = worktree_handle.read(cx);
  411
  412        let worktree_id = worktree.id();
  413        let worktree_abs_path = worktree.abs_path();
  414        let toolchain = key.toolchain.clone();
  415        let override_options = settings.initialization_options.clone();
  416
  417        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  418
  419        let server_id = self.languages.next_language_server_id();
  420        log::trace!(
  421            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  422            adapter.name.0
  423        );
  424
  425        let wait_until_worktree_trust =
  426            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  427                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  428                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  429                });
  430                if can_trust {
  431                    self.restricted_worktrees_tasks.remove(&worktree_id);
  432                    None
  433                } else {
  434                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  435                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  436                        hash_map::Entry::Vacant(v) => {
  437                            let (mut tx, rx) = watch::channel::<bool>();
  438                            let lsp_store = self.weak.clone();
  439                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  440                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  441                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  442                                        tx.blocking_send(true).ok();
  443                                        lsp_store
  444                                            .update(cx, |lsp_store, _| {
  445                                                if let Some(local_lsp_store) =
  446                                                    lsp_store.as_local_mut()
  447                                                {
  448                                                    local_lsp_store
  449                                                        .restricted_worktrees_tasks
  450                                                        .remove(&worktree_id);
  451                                                }
  452                                            })
  453                                            .ok();
  454                                    }
  455                                }
  456                            });
  457                            v.insert((subscription, rx.clone()));
  458                            Some(rx)
  459                        }
  460                    }
  461                }
  462            });
  463        let update_binary_status = wait_until_worktree_trust.is_none();
  464
  465        let binary = self.get_language_server_binary(
  466            worktree_abs_path.clone(),
  467            adapter.clone(),
  468            settings,
  469            toolchain.clone(),
  470            delegate.clone(),
  471            true,
  472            wait_until_worktree_trust,
  473            cx,
  474        );
  475        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  476
  477        let pending_server = cx.spawn({
  478            let adapter = adapter.clone();
  479            let server_name = adapter.name.clone();
  480            let stderr_capture = stderr_capture.clone();
  481            #[cfg(any(test, feature = "test-support"))]
  482            let lsp_store = self.weak.clone();
  483            let pending_workspace_folders = pending_workspace_folders.clone();
  484            async move |cx| {
  485                let binary = binary.await?;
  486                #[cfg(any(test, feature = "test-support"))]
  487                if let Some(server) = lsp_store
  488                    .update(&mut cx.clone(), |this, cx| {
  489                        this.languages.create_fake_language_server(
  490                            server_id,
  491                            &server_name,
  492                            binary.clone(),
  493                            &mut cx.to_async(),
  494                        )
  495                    })
  496                    .ok()
  497                    .flatten()
  498                {
  499                    return Ok(server);
  500                }
  501
  502                let code_action_kinds = adapter.code_action_kinds();
  503                lsp::LanguageServer::new(
  504                    stderr_capture,
  505                    server_id,
  506                    server_name,
  507                    binary,
  508                    &worktree_abs_path,
  509                    code_action_kinds,
  510                    Some(pending_workspace_folders),
  511                    cx,
  512                )
  513            }
  514        });
  515
  516        let startup = {
  517            let server_name = adapter.name.0.clone();
  518            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  519            let key = key.clone();
  520            let adapter = adapter.clone();
  521            let lsp_store = self.weak.clone();
  522            let pending_workspace_folders = pending_workspace_folders.clone();
  523            let pull_diagnostics = ProjectSettings::get_global(cx)
  524                .diagnostics
  525                .lsp_pull_diagnostics
  526                .enabled;
  527            let settings_location = SettingsLocation {
  528                worktree_id,
  529                path: RelPath::empty(),
  530            };
  531            let augments_syntax_tokens = AllLanguageSettings::get(Some(settings_location), cx)
  532                .language(Some(settings_location), Some(&language_name), cx)
  533                .semantic_tokens
  534                .use_tree_sitter();
  535            cx.spawn(async move |cx| {
  536                let result = async {
  537                    let language_server = pending_server.await?;
  538
  539                    let workspace_config = Self::workspace_configuration_for_adapter(
  540                        adapter.adapter.clone(),
  541                        &delegate,
  542                        toolchain,
  543                        None,
  544                        cx,
  545                    )
  546                    .await?;
  547
  548                    let mut initialization_options = Self::initialization_options_for_adapter(
  549                        adapter.adapter.clone(),
  550                        &delegate,
  551                        cx,
  552                    )
  553                    .await?;
  554
  555                    match (&mut initialization_options, override_options) {
  556                        (Some(initialization_options), Some(override_options)) => {
  557                            merge_json_value_into(override_options, initialization_options);
  558                        }
  559                        (None, override_options) => initialization_options = override_options,
  560                        _ => {}
  561                    }
  562
  563                    let initialization_params = cx.update(|cx| {
  564                        let mut params = language_server.default_initialize_params(
  565                            pull_diagnostics,
  566                            augments_syntax_tokens,
  567                            cx,
  568                        );
  569                        params.initialization_options = initialization_options;
  570                        adapter.adapter.prepare_initialize_params(params, cx)
  571                    })?;
  572
  573                    Self::setup_lsp_messages(
  574                        lsp_store.clone(),
  575                        &language_server,
  576                        delegate.clone(),
  577                        adapter.clone(),
  578                    );
  579
  580                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  581                        settings: workspace_config,
  582                    };
  583                    let language_server = cx
  584                        .update(|cx| {
  585                            let request_timeout = ProjectSettings::get_global(cx)
  586                                .global_lsp_settings
  587                                .get_request_timeout();
  588
  589                            language_server.initialize(
  590                                initialization_params,
  591                                Arc::new(did_change_configuration_params.clone()),
  592                                request_timeout,
  593                                cx,
  594                            )
  595                        })
  596                        .await
  597                        .inspect_err(|_| {
  598                            if let Some(lsp_store) = lsp_store.upgrade() {
  599                                lsp_store.update(cx, |lsp_store, cx| {
  600                                    lsp_store.cleanup_lsp_data(server_id);
  601                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  602                                });
  603                            }
  604                        })?;
  605
  606                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  607                        did_change_configuration_params,
  608                    )?;
  609
  610                    anyhow::Ok(language_server)
  611                }
  612                .await;
  613
  614                match result {
  615                    Ok(server) => {
  616                        lsp_store
  617                            .update(cx, |lsp_store, cx| {
  618                                lsp_store.insert_newly_running_language_server(
  619                                    adapter,
  620                                    server.clone(),
  621                                    server_id,
  622                                    key,
  623                                    pending_workspace_folders,
  624                                    cx,
  625                                );
  626                            })
  627                            .ok();
  628                        stderr_capture.lock().take();
  629                        Some(server)
  630                    }
  631
  632                    Err(err) => {
  633                        let log = stderr_capture.lock().take().unwrap_or_default();
  634                        delegate.update_status(
  635                            adapter.name(),
  636                            BinaryStatus::Failed {
  637                                error: if log.is_empty() {
  638                                    format!("{err:#}")
  639                                } else {
  640                                    format!("{err:#}\n-- stderr --\n{log}")
  641                                },
  642                            },
  643                        );
  644                        log::error!(
  645                            "Failed to start language server {server_name:?}: {}",
  646                            redact_command(&format!("{err:?}"))
  647                        );
  648                        if !log.is_empty() {
  649                            log::error!("server stderr: {}", redact_command(&log));
  650                        }
  651                        None
  652                    }
  653                }
  654            })
  655        };
  656        let state = LanguageServerState::Starting {
  657            startup,
  658            pending_workspace_folders,
  659        };
  660
  661        if update_binary_status {
  662            self.languages
  663                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  664        }
  665
  666        self.language_servers.insert(server_id, state);
  667        self.language_server_ids
  668            .entry(key)
  669            .or_insert(UnifiedLanguageServer {
  670                id: server_id,
  671                project_roots: Default::default(),
  672            });
  673        server_id
  674    }
  675
  676    fn get_language_server_binary(
  677        &self,
  678        worktree_abs_path: Arc<Path>,
  679        adapter: Arc<CachedLspAdapter>,
  680        settings: Arc<LspSettings>,
  681        toolchain: Option<Toolchain>,
  682        delegate: Arc<dyn LspAdapterDelegate>,
  683        allow_binary_download: bool,
  684        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  685        cx: &mut App,
  686    ) -> Task<Result<LanguageServerBinary>> {
  687        if let Some(settings) = &settings.binary
  688            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  689        {
  690            let settings = settings.clone();
  691            let languages = self.languages.clone();
  692            return cx.background_spawn(async move {
  693                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  694                    let already_trusted =  *wait_until_worktree_trust.borrow();
  695                    if !already_trusted {
  696                        log::info!(
  697                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  698                            adapter.name(),
  699                        );
  700                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  701                            if worktree_trusted {
  702                                break;
  703                            }
  704                        }
  705                        log::info!(
  706                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  707                            adapter.name(),
  708                        );
  709                    }
  710                    languages
  711                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  712                }
  713                let mut env = delegate.shell_env().await;
  714                env.extend(settings.env.unwrap_or_default());
  715
  716                Ok(LanguageServerBinary {
  717                    path: delegate.resolve_relative_path(path),
  718                    env: Some(env),
  719                    arguments: settings
  720                        .arguments
  721                        .unwrap_or_default()
  722                        .iter()
  723                        .map(Into::into)
  724                        .collect(),
  725                })
  726            });
  727        }
  728        let lsp_binary_options = LanguageServerBinaryOptions {
  729            allow_path_lookup: !settings
  730                .binary
  731                .as_ref()
  732                .and_then(|b| b.ignore_system_version)
  733                .unwrap_or_default(),
  734            allow_binary_download,
  735            pre_release: settings
  736                .fetch
  737                .as_ref()
  738                .and_then(|f| f.pre_release)
  739                .unwrap_or(false),
  740        };
  741
  742        cx.spawn(async move |cx| {
  743            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  744                let already_trusted =  *wait_until_worktree_trust.borrow();
  745                if !already_trusted {
  746                    log::info!(
  747                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  748                        adapter.name(),
  749                    );
  750                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  751                        if worktree_trusted {
  752                            break;
  753                        }
  754                    }
  755                    log::info!(
  756                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  757                            adapter.name(),
  758                    );
  759                }
  760            }
  761
  762            let (existing_binary, maybe_download_binary) = adapter
  763                .clone()
  764                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  765                .await
  766                .await;
  767
  768            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  769
  770            let mut binary = match (existing_binary, maybe_download_binary) {
  771                (binary, None) => binary?,
  772                (Err(_), Some(downloader)) => downloader.await?,
  773                (Ok(existing_binary), Some(downloader)) => {
  774                    let mut download_timeout = cx
  775                        .background_executor()
  776                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  777                        .fuse();
  778                    let mut downloader = downloader.fuse();
  779                    futures::select! {
  780                        _ = download_timeout => {
  781                            // Return existing binary and kick the existing work to the background.
  782                            cx.spawn(async move |_| downloader.await).detach();
  783                            Ok(existing_binary)
  784                        },
  785                        downloaded_or_existing_binary = downloader => {
  786                            // If download fails, this results in the existing binary.
  787                            downloaded_or_existing_binary
  788                        }
  789                    }?
  790                }
  791            };
  792            let mut shell_env = delegate.shell_env().await;
  793
  794            shell_env.extend(binary.env.unwrap_or_default());
  795
  796            if let Some(settings) = settings.binary.as_ref() {
  797                if let Some(arguments) = &settings.arguments {
  798                    binary.arguments = arguments.iter().map(Into::into).collect();
  799                }
  800                if let Some(env) = &settings.env {
  801                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  802                }
  803            }
  804
  805            binary.env = Some(shell_env);
  806            Ok(binary)
  807        })
  808    }
  809
  810    fn setup_lsp_messages(
  811        lsp_store: WeakEntity<LspStore>,
  812        language_server: &LanguageServer,
  813        delegate: Arc<dyn LspAdapterDelegate>,
  814        adapter: Arc<CachedLspAdapter>,
  815    ) {
  816        let name = language_server.name();
  817        let server_id = language_server.server_id();
  818        language_server
  819            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  820                let adapter = adapter.clone();
  821                let this = lsp_store.clone();
  822                move |mut params, cx| {
  823                    let adapter = adapter.clone();
  824                    if let Some(this) = this.upgrade() {
  825                        this.update(cx, |this, cx| {
  826                            {
  827                                let buffer = params
  828                                    .uri
  829                                    .to_file_path()
  830                                    .map(|file_path| this.get_buffer(&file_path, cx))
  831                                    .ok()
  832                                    .flatten();
  833                                adapter.process_diagnostics(&mut params, server_id, buffer);
  834                            }
  835
  836                            this.merge_lsp_diagnostics(
  837                                DiagnosticSourceKind::Pushed,
  838                                vec![DocumentDiagnosticsUpdate {
  839                                    server_id,
  840                                    diagnostics: params,
  841                                    result_id: None,
  842                                    disk_based_sources: Cow::Borrowed(
  843                                        &adapter.disk_based_diagnostic_sources,
  844                                    ),
  845                                    registration_id: None,
  846                                }],
  847                                |_, diagnostic, cx| match diagnostic.source_kind {
  848                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  849                                        adapter.retain_old_diagnostic(diagnostic, cx)
  850                                    }
  851                                    DiagnosticSourceKind::Pulled => true,
  852                                },
  853                                cx,
  854                            )
  855                            .log_err();
  856                        });
  857                    }
  858                }
  859            })
  860            .detach();
  861        language_server
  862            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  863                let adapter = adapter.adapter.clone();
  864                let delegate = delegate.clone();
  865                let this = lsp_store.clone();
  866                move |params, cx| {
  867                    let adapter = adapter.clone();
  868                    let delegate = delegate.clone();
  869                    let this = this.clone();
  870                    let mut cx = cx.clone();
  871                    async move {
  872                        let toolchain_for_id = this
  873                            .update(&mut cx, |this, _| {
  874                                this.as_local()?.language_server_ids.iter().find_map(
  875                                    |(seed, value)| {
  876                                        (value.id == server_id).then(|| seed.toolchain.clone())
  877                                    },
  878                                )
  879                            })?
  880                            .context("Expected the LSP store to be in a local mode")?;
  881
  882                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  883                        for item in &params.items {
  884                            let scope_uri = item.scope_uri.clone();
  885                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  886                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  887                            else {
  888                                // We've already queried workspace configuration of this URI.
  889                                continue;
  890                            };
  891                            let workspace_config = Self::workspace_configuration_for_adapter(
  892                                adapter.clone(),
  893                                &delegate,
  894                                toolchain_for_id.clone(),
  895                                scope_uri,
  896                                &mut cx,
  897                            )
  898                            .await?;
  899                            new_scope_uri.insert(workspace_config);
  900                        }
  901
  902                        Ok(params
  903                            .items
  904                            .into_iter()
  905                            .filter_map(|item| {
  906                                let workspace_config =
  907                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  908                                if let Some(section) = &item.section {
  909                                    Some(
  910                                        workspace_config
  911                                            .get(section)
  912                                            .cloned()
  913                                            .unwrap_or(serde_json::Value::Null),
  914                                    )
  915                                } else {
  916                                    Some(workspace_config.clone())
  917                                }
  918                            })
  919                            .collect())
  920                    }
  921                }
  922            })
  923            .detach();
  924
  925        language_server
  926            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  927                let this = lsp_store.clone();
  928                move |_, cx| {
  929                    let this = this.clone();
  930                    let cx = cx.clone();
  931                    async move {
  932                        let Some(server) =
  933                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  934                        else {
  935                            return Ok(None);
  936                        };
  937                        let root = server.workspace_folders();
  938                        Ok(Some(
  939                            root.into_iter()
  940                                .map(|uri| WorkspaceFolder {
  941                                    uri,
  942                                    name: Default::default(),
  943                                })
  944                                .collect(),
  945                        ))
  946                    }
  947                }
  948            })
  949            .detach();
  950        // Even though we don't have handling for these requests, respond to them to
  951        // avoid stalling any language server like `gopls` which waits for a response
  952        // to these requests when initializing.
  953        language_server
  954            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  955                let this = lsp_store.clone();
  956                move |params, cx| {
  957                    let this = this.clone();
  958                    let mut cx = cx.clone();
  959                    async move {
  960                        this.update(&mut cx, |this, _| {
  961                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  962                            {
  963                                status
  964                                    .progress_tokens
  965                                    .insert(ProgressToken::from_lsp(params.token));
  966                            }
  967                        })?;
  968
  969                        Ok(())
  970                    }
  971                }
  972            })
  973            .detach();
  974
  975        language_server
  976            .on_request::<lsp::request::RegisterCapability, _, _>({
  977                let lsp_store = lsp_store.clone();
  978                move |params, cx| {
  979                    let lsp_store = lsp_store.clone();
  980                    let mut cx = cx.clone();
  981                    async move {
  982                        lsp_store
  983                            .update(&mut cx, |lsp_store, cx| {
  984                                if lsp_store.as_local().is_some() {
  985                                    match lsp_store
  986                                        .register_server_capabilities(server_id, params, cx)
  987                                    {
  988                                        Ok(()) => {}
  989                                        Err(e) => {
  990                                            log::error!(
  991                                                "Failed to register server capabilities: {e:#}"
  992                                            );
  993                                        }
  994                                    };
  995                                }
  996                            })
  997                            .ok();
  998                        Ok(())
  999                    }
 1000                }
 1001            })
 1002            .detach();
 1003
 1004        language_server
 1005            .on_request::<lsp::request::UnregisterCapability, _, _>({
 1006                let lsp_store = lsp_store.clone();
 1007                move |params, cx| {
 1008                    let lsp_store = lsp_store.clone();
 1009                    let mut cx = cx.clone();
 1010                    async move {
 1011                        lsp_store
 1012                            .update(&mut cx, |lsp_store, cx| {
 1013                                if lsp_store.as_local().is_some() {
 1014                                    match lsp_store
 1015                                        .unregister_server_capabilities(server_id, params, cx)
 1016                                    {
 1017                                        Ok(()) => {}
 1018                                        Err(e) => {
 1019                                            log::error!(
 1020                                                "Failed to unregister server capabilities: {e:#}"
 1021                                            );
 1022                                        }
 1023                                    }
 1024                                }
 1025                            })
 1026                            .ok();
 1027                        Ok(())
 1028                    }
 1029                }
 1030            })
 1031            .detach();
 1032
 1033        language_server
 1034            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
 1035                let this = lsp_store.clone();
 1036                move |params, cx| {
 1037                    let mut cx = cx.clone();
 1038                    let this = this.clone();
 1039                    async move {
 1040                        LocalLspStore::on_lsp_workspace_edit(
 1041                            this.clone(),
 1042                            params,
 1043                            server_id,
 1044                            &mut cx,
 1045                        )
 1046                        .await
 1047                    }
 1048                }
 1049            })
 1050            .detach();
 1051
 1052        language_server
 1053            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1054                let lsp_store = lsp_store.clone();
 1055                let request_id = Arc::new(AtomicUsize::new(0));
 1056                move |(), cx| {
 1057                    let lsp_store = lsp_store.clone();
 1058                    let request_id = request_id.clone();
 1059                    let mut cx = cx.clone();
 1060                    async move {
 1061                        lsp_store
 1062                            .update(&mut cx, |lsp_store, cx| {
 1063                                let request_id =
 1064                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1065                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1066                                    server_id,
 1067                                    request_id,
 1068                                });
 1069                                lsp_store
 1070                                    .downstream_client
 1071                                    .as_ref()
 1072                                    .map(|(client, project_id)| {
 1073                                        client.send(proto::RefreshInlayHints {
 1074                                            project_id: *project_id,
 1075                                            server_id: server_id.to_proto(),
 1076                                            request_id: request_id.map(|id| id as u64),
 1077                                        })
 1078                                    })
 1079                            })?
 1080                            .transpose()?;
 1081                        Ok(())
 1082                    }
 1083                }
 1084            })
 1085            .detach();
 1086
 1087        language_server
 1088            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1089                let this = lsp_store.clone();
 1090                move |(), cx| {
 1091                    let this = this.clone();
 1092                    let mut cx = cx.clone();
 1093                    async move {
 1094                        this.update(&mut cx, |this, cx| {
 1095                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1096                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1097                                client.send(proto::RefreshCodeLens {
 1098                                    project_id: *project_id,
 1099                                })
 1100                            })
 1101                        })?
 1102                        .transpose()?;
 1103                        Ok(())
 1104                    }
 1105                }
 1106            })
 1107            .detach();
 1108
 1109        language_server
 1110            .on_request::<lsp::request::SemanticTokensRefresh, _, _>({
 1111                let lsp_store = lsp_store.clone();
 1112                let request_id = Arc::new(AtomicUsize::new(0));
 1113                move |(), cx| {
 1114                    let lsp_store = lsp_store.clone();
 1115                    let request_id = request_id.clone();
 1116                    let mut cx = cx.clone();
 1117                    async move {
 1118                        lsp_store
 1119                            .update(&mut cx, |lsp_store, cx| {
 1120                                let request_id =
 1121                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1122                                cx.emit(LspStoreEvent::RefreshSemanticTokens {
 1123                                    server_id,
 1124                                    request_id,
 1125                                });
 1126                                lsp_store
 1127                                    .downstream_client
 1128                                    .as_ref()
 1129                                    .map(|(client, project_id)| {
 1130                                        client.send(proto::RefreshSemanticTokens {
 1131                                            project_id: *project_id,
 1132                                            server_id: server_id.to_proto(),
 1133                                            request_id: request_id.map(|id| id as u64),
 1134                                        })
 1135                                    })
 1136                            })?
 1137                            .transpose()?;
 1138                        Ok(())
 1139                    }
 1140                }
 1141            })
 1142            .detach();
 1143
 1144        language_server
 1145            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1146                let this = lsp_store.clone();
 1147                move |(), cx| {
 1148                    let this = this.clone();
 1149                    let mut cx = cx.clone();
 1150                    async move {
 1151                        this.update(&mut cx, |lsp_store, cx| {
 1152                            lsp_store.pull_workspace_diagnostics(server_id);
 1153                            lsp_store
 1154                                .downstream_client
 1155                                .as_ref()
 1156                                .map(|(client, project_id)| {
 1157                                    client.send(proto::PullWorkspaceDiagnostics {
 1158                                        project_id: *project_id,
 1159                                        server_id: server_id.to_proto(),
 1160                                    })
 1161                                })
 1162                                .transpose()?;
 1163                            anyhow::Ok(
 1164                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1165                            )
 1166                        })??
 1167                        .await;
 1168                        Ok(())
 1169                    }
 1170                }
 1171            })
 1172            .detach();
 1173
 1174        language_server
 1175            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1176                let this = lsp_store.clone();
 1177                let name = name.to_string();
 1178                let adapter = adapter.clone();
 1179                move |params, cx| {
 1180                    let this = this.clone();
 1181                    let name = name.to_string();
 1182                    let adapter = adapter.clone();
 1183                    let mut cx = cx.clone();
 1184                    async move {
 1185                        let actions = params.actions.unwrap_or_default();
 1186                        let message = params.message.clone();
 1187                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1188                        let level = match params.typ {
 1189                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1190                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1191                            _ => PromptLevel::Info,
 1192                        };
 1193                        let request = LanguageServerPromptRequest::new(
 1194                            level,
 1195                            params.message,
 1196                            actions,
 1197                            name.clone(),
 1198                            tx,
 1199                        );
 1200
 1201                        let did_update = this
 1202                            .update(&mut cx, |_, cx| {
 1203                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1204                            })
 1205                            .is_ok();
 1206                        if did_update {
 1207                            let response = rx.recv().await.ok();
 1208                            if let Some(ref selected_action) = response {
 1209                                let context = language::PromptResponseContext {
 1210                                    message,
 1211                                    selected_action: selected_action.clone(),
 1212                                };
 1213                                adapter.process_prompt_response(&context, &mut cx)
 1214                            }
 1215
 1216                            Ok(response)
 1217                        } else {
 1218                            Ok(None)
 1219                        }
 1220                    }
 1221                }
 1222            })
 1223            .detach();
 1224        language_server
 1225            .on_notification::<lsp::notification::ShowMessage, _>({
 1226                let this = lsp_store.clone();
 1227                let name = name.to_string();
 1228                move |params, cx| {
 1229                    let this = this.clone();
 1230                    let name = name.to_string();
 1231                    let mut cx = cx.clone();
 1232
 1233                    let (tx, _) = smol::channel::bounded(1);
 1234                    let level = match params.typ {
 1235                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1236                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1237                        _ => PromptLevel::Info,
 1238                    };
 1239                    let request =
 1240                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1241
 1242                    let _ = this.update(&mut cx, |_, cx| {
 1243                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1244                    });
 1245                }
 1246            })
 1247            .detach();
 1248
 1249        let disk_based_diagnostics_progress_token =
 1250            adapter.disk_based_diagnostics_progress_token.clone();
 1251
 1252        language_server
 1253            .on_notification::<lsp::notification::Progress, _>({
 1254                let this = lsp_store.clone();
 1255                move |params, cx| {
 1256                    if let Some(this) = this.upgrade() {
 1257                        this.update(cx, |this, cx| {
 1258                            this.on_lsp_progress(
 1259                                params,
 1260                                server_id,
 1261                                disk_based_diagnostics_progress_token.clone(),
 1262                                cx,
 1263                            );
 1264                        });
 1265                    }
 1266                }
 1267            })
 1268            .detach();
 1269
 1270        language_server
 1271            .on_notification::<lsp::notification::LogMessage, _>({
 1272                let this = lsp_store.clone();
 1273                move |params, cx| {
 1274                    if let Some(this) = this.upgrade() {
 1275                        this.update(cx, |_, cx| {
 1276                            cx.emit(LspStoreEvent::LanguageServerLog(
 1277                                server_id,
 1278                                LanguageServerLogType::Log(params.typ),
 1279                                params.message,
 1280                            ));
 1281                        });
 1282                    }
 1283                }
 1284            })
 1285            .detach();
 1286
 1287        language_server
 1288            .on_notification::<lsp::notification::LogTrace, _>({
 1289                let this = lsp_store.clone();
 1290                move |params, cx| {
 1291                    let mut cx = cx.clone();
 1292                    if let Some(this) = this.upgrade() {
 1293                        this.update(&mut cx, |_, cx| {
 1294                            cx.emit(LspStoreEvent::LanguageServerLog(
 1295                                server_id,
 1296                                LanguageServerLogType::Trace {
 1297                                    verbose_info: params.verbose,
 1298                                },
 1299                                params.message,
 1300                            ));
 1301                        });
 1302                    }
 1303                }
 1304            })
 1305            .detach();
 1306
 1307        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1308        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1309        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1310        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1311    }
 1312
 1313    fn shutdown_language_servers_on_quit(&mut self) -> impl Future<Output = ()> + use<> {
 1314        let shutdown_futures = self
 1315            .language_servers
 1316            .drain()
 1317            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1318            .collect::<Vec<_>>();
 1319
 1320        async move {
 1321            join_all(shutdown_futures).await;
 1322        }
 1323    }
 1324
 1325    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1326        match server_state {
 1327            LanguageServerState::Running { server, .. } => {
 1328                if let Some(shutdown) = server.shutdown() {
 1329                    shutdown.await;
 1330                }
 1331            }
 1332            LanguageServerState::Starting { startup, .. } => {
 1333                if let Some(server) = startup.await
 1334                    && let Some(shutdown) = server.shutdown()
 1335                {
 1336                    shutdown.await;
 1337                }
 1338            }
 1339        }
 1340        Ok(())
 1341    }
 1342
 1343    fn language_servers_for_worktree(
 1344        &self,
 1345        worktree_id: WorktreeId,
 1346    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1347        self.language_server_ids
 1348            .iter()
 1349            .filter_map(move |(seed, state)| {
 1350                if seed.worktree_id != worktree_id {
 1351                    return None;
 1352                }
 1353
 1354                if let Some(LanguageServerState::Running { server, .. }) =
 1355                    self.language_servers.get(&state.id)
 1356                {
 1357                    Some(server)
 1358                } else {
 1359                    None
 1360                }
 1361            })
 1362    }
 1363
 1364    fn language_server_ids_for_project_path(
 1365        &self,
 1366        project_path: ProjectPath,
 1367        language: &Language,
 1368        cx: &mut App,
 1369    ) -> Vec<LanguageServerId> {
 1370        let Some(worktree) = self
 1371            .worktree_store
 1372            .read(cx)
 1373            .worktree_for_id(project_path.worktree_id, cx)
 1374        else {
 1375            return Vec::new();
 1376        };
 1377        let delegate: Arc<dyn ManifestDelegate> =
 1378            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1379
 1380        self.lsp_tree
 1381            .get(
 1382                project_path,
 1383                language.name(),
 1384                language.manifest(),
 1385                &delegate,
 1386                cx,
 1387            )
 1388            .collect::<Vec<_>>()
 1389    }
 1390
 1391    fn language_server_ids_for_buffer(
 1392        &self,
 1393        buffer: &Buffer,
 1394        cx: &mut App,
 1395    ) -> Vec<LanguageServerId> {
 1396        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1397            let worktree_id = file.worktree_id(cx);
 1398
 1399            let path: Arc<RelPath> = file
 1400                .path()
 1401                .parent()
 1402                .map(Arc::from)
 1403                .unwrap_or_else(|| file.path().clone());
 1404            let worktree_path = ProjectPath { worktree_id, path };
 1405            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1406        } else {
 1407            Vec::new()
 1408        }
 1409    }
 1410
 1411    fn language_servers_for_buffer<'a>(
 1412        &'a self,
 1413        buffer: &'a Buffer,
 1414        cx: &'a mut App,
 1415    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1416        self.language_server_ids_for_buffer(buffer, cx)
 1417            .into_iter()
 1418            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1419                LanguageServerState::Running {
 1420                    adapter, server, ..
 1421                } => Some((adapter, server)),
 1422                _ => None,
 1423            })
 1424    }
 1425
 1426    async fn execute_code_action_kind_locally(
 1427        lsp_store: WeakEntity<LspStore>,
 1428        mut buffers: Vec<Entity<Buffer>>,
 1429        kind: CodeActionKind,
 1430        push_to_history: bool,
 1431        cx: &mut AsyncApp,
 1432    ) -> anyhow::Result<ProjectTransaction> {
 1433        // Do not allow multiple concurrent code actions requests for the
 1434        // same buffer.
 1435        lsp_store.update(cx, |this, cx| {
 1436            let this = this.as_local_mut().unwrap();
 1437            buffers.retain(|buffer| {
 1438                this.buffers_being_formatted
 1439                    .insert(buffer.read(cx).remote_id())
 1440            });
 1441        })?;
 1442        let _cleanup = defer({
 1443            let this = lsp_store.clone();
 1444            let mut cx = cx.clone();
 1445            let buffers = &buffers;
 1446            move || {
 1447                this.update(&mut cx, |this, cx| {
 1448                    let this = this.as_local_mut().unwrap();
 1449                    for buffer in buffers {
 1450                        this.buffers_being_formatted
 1451                            .remove(&buffer.read(cx).remote_id());
 1452                    }
 1453                })
 1454                .ok();
 1455            }
 1456        });
 1457        let mut project_transaction = ProjectTransaction::default();
 1458
 1459        for buffer in &buffers {
 1460            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1461                buffer.update(cx, |buffer, cx| {
 1462                    lsp_store
 1463                        .as_local()
 1464                        .unwrap()
 1465                        .language_servers_for_buffer(buffer, cx)
 1466                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1467                        .collect::<Vec<_>>()
 1468                })
 1469            })?;
 1470            for (_, language_server) in adapters_and_servers.iter() {
 1471                let actions = Self::get_server_code_actions_from_action_kinds(
 1472                    &lsp_store,
 1473                    language_server.server_id(),
 1474                    vec![kind.clone()],
 1475                    buffer,
 1476                    cx,
 1477                )
 1478                .await?;
 1479                Self::execute_code_actions_on_server(
 1480                    &lsp_store,
 1481                    language_server,
 1482                    actions,
 1483                    push_to_history,
 1484                    &mut project_transaction,
 1485                    cx,
 1486                )
 1487                .await?;
 1488            }
 1489        }
 1490        Ok(project_transaction)
 1491    }
 1492
 1493    async fn format_locally(
 1494        lsp_store: WeakEntity<LspStore>,
 1495        mut buffers: Vec<FormattableBuffer>,
 1496        push_to_history: bool,
 1497        trigger: FormatTrigger,
 1498        logger: zlog::Logger,
 1499        cx: &mut AsyncApp,
 1500    ) -> anyhow::Result<ProjectTransaction> {
 1501        // Do not allow multiple concurrent formatting requests for the
 1502        // same buffer.
 1503        lsp_store.update(cx, |this, cx| {
 1504            let this = this.as_local_mut().unwrap();
 1505            buffers.retain(|buffer| {
 1506                this.buffers_being_formatted
 1507                    .insert(buffer.handle.read(cx).remote_id())
 1508            });
 1509        })?;
 1510
 1511        let _cleanup = defer({
 1512            let this = lsp_store.clone();
 1513            let mut cx = cx.clone();
 1514            let buffers = &buffers;
 1515            move || {
 1516                this.update(&mut cx, |this, cx| {
 1517                    let this = this.as_local_mut().unwrap();
 1518                    for buffer in buffers {
 1519                        this.buffers_being_formatted
 1520                            .remove(&buffer.handle.read(cx).remote_id());
 1521                    }
 1522                })
 1523                .ok();
 1524            }
 1525        });
 1526
 1527        let mut project_transaction = ProjectTransaction::default();
 1528
 1529        for buffer in &buffers {
 1530            zlog::debug!(
 1531                logger =>
 1532                "formatting buffer '{:?}'",
 1533                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1534            );
 1535            // Create an empty transaction to hold all of the formatting edits.
 1536            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1537                // ensure no transactions created while formatting are
 1538                // grouped with the previous transaction in the history
 1539                // based on the transaction group interval
 1540                buffer.finalize_last_transaction();
 1541                buffer
 1542                    .start_transaction()
 1543                    .context("transaction already open")?;
 1544                buffer.end_transaction(cx);
 1545                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1546                buffer.finalize_last_transaction();
 1547                anyhow::Ok(transaction_id)
 1548            })?;
 1549
 1550            let result = Self::format_buffer_locally(
 1551                lsp_store.clone(),
 1552                buffer,
 1553                formatting_transaction_id,
 1554                trigger,
 1555                logger,
 1556                cx,
 1557            )
 1558            .await;
 1559
 1560            buffer.handle.update(cx, |buffer, cx| {
 1561                let Some(formatting_transaction) =
 1562                    buffer.get_transaction(formatting_transaction_id).cloned()
 1563                else {
 1564                    zlog::warn!(logger => "no formatting transaction");
 1565                    return;
 1566                };
 1567                if formatting_transaction.edit_ids.is_empty() {
 1568                    zlog::debug!(logger => "no changes made while formatting");
 1569                    buffer.forget_transaction(formatting_transaction_id);
 1570                    return;
 1571                }
 1572                if !push_to_history {
 1573                    zlog::trace!(logger => "forgetting format transaction");
 1574                    buffer.forget_transaction(formatting_transaction.id);
 1575                }
 1576                project_transaction
 1577                    .0
 1578                    .insert(cx.entity(), formatting_transaction);
 1579            });
 1580
 1581            result?;
 1582        }
 1583
 1584        Ok(project_transaction)
 1585    }
 1586
 1587    async fn format_buffer_locally(
 1588        lsp_store: WeakEntity<LspStore>,
 1589        buffer: &FormattableBuffer,
 1590        formatting_transaction_id: clock::Lamport,
 1591        trigger: FormatTrigger,
 1592        logger: zlog::Logger,
 1593        cx: &mut AsyncApp,
 1594    ) -> Result<()> {
 1595        let (adapters_and_servers, settings, request_timeout) =
 1596            lsp_store.update(cx, |lsp_store, cx| {
 1597                buffer.handle.update(cx, |buffer, cx| {
 1598                    let adapters_and_servers = lsp_store
 1599                        .as_local()
 1600                        .unwrap()
 1601                        .language_servers_for_buffer(buffer, cx)
 1602                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1603                        .collect::<Vec<_>>();
 1604                    let settings =
 1605                        language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1606                            .into_owned();
 1607                    let request_timeout = ProjectSettings::get_global(cx)
 1608                        .global_lsp_settings
 1609                        .get_request_timeout();
 1610                    (adapters_and_servers, settings, request_timeout)
 1611                })
 1612            })?;
 1613
 1614        /// Apply edits to the buffer that will become part of the formatting transaction.
 1615        /// Fails if the buffer has been edited since the start of that transaction.
 1616        fn extend_formatting_transaction(
 1617            buffer: &FormattableBuffer,
 1618            formatting_transaction_id: text::TransactionId,
 1619            cx: &mut AsyncApp,
 1620            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1621        ) -> anyhow::Result<()> {
 1622            buffer.handle.update(cx, |buffer, cx| {
 1623                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1624                if last_transaction_id != Some(formatting_transaction_id) {
 1625                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1626                }
 1627                buffer.start_transaction();
 1628                operation(buffer, cx);
 1629                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1630                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1631                }
 1632                Ok(())
 1633            })
 1634        }
 1635
 1636        // handle whitespace formatting
 1637        if settings.remove_trailing_whitespace_on_save {
 1638            zlog::trace!(logger => "removing trailing whitespace");
 1639            let diff = buffer
 1640                .handle
 1641                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1642                .await;
 1643            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1644                buffer.apply_diff(diff, cx);
 1645            })?;
 1646        }
 1647
 1648        if settings.ensure_final_newline_on_save {
 1649            zlog::trace!(logger => "ensuring final newline");
 1650            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1651                buffer.ensure_final_newline(cx);
 1652            })?;
 1653        }
 1654
 1655        // Formatter for `code_actions_on_format` that runs before
 1656        // the rest of the formatters
 1657        let mut code_actions_on_format_formatters = None;
 1658        let should_run_code_actions_on_format = !matches!(
 1659            (trigger, &settings.format_on_save),
 1660            (FormatTrigger::Save, &FormatOnSave::Off)
 1661        );
 1662        if should_run_code_actions_on_format {
 1663            let have_code_actions_to_run_on_format = settings
 1664                .code_actions_on_format
 1665                .values()
 1666                .any(|enabled| *enabled);
 1667            if have_code_actions_to_run_on_format {
 1668                zlog::trace!(logger => "going to run code actions on format");
 1669                code_actions_on_format_formatters = Some(
 1670                    settings
 1671                        .code_actions_on_format
 1672                        .iter()
 1673                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1674                        .cloned()
 1675                        .map(Formatter::CodeAction)
 1676                        .collect::<Vec<_>>(),
 1677                );
 1678            }
 1679        }
 1680
 1681        let formatters = match (trigger, &settings.format_on_save) {
 1682            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1683            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1684                settings.formatter.as_ref()
 1685            }
 1686        };
 1687
 1688        let formatters = code_actions_on_format_formatters
 1689            .iter()
 1690            .flatten()
 1691            .chain(formatters);
 1692
 1693        for formatter in formatters {
 1694            let formatter = if formatter == &Formatter::Auto {
 1695                if settings.prettier.allowed {
 1696                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1697                    &Formatter::Prettier
 1698                } else {
 1699                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1700                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1701                }
 1702            } else {
 1703                formatter
 1704            };
 1705            match formatter {
 1706                Formatter::None => {
 1707                    zlog::trace!(logger => "skipping formatter 'none'");
 1708                    continue;
 1709                }
 1710                Formatter::Auto => unreachable!("Auto resolved above"),
 1711                Formatter::Prettier => {
 1712                    let logger = zlog::scoped!(logger => "prettier");
 1713                    zlog::trace!(logger => "formatting");
 1714                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1715
 1716                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1717                        lsp_store.prettier_store().unwrap().downgrade()
 1718                    })?;
 1719                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1720                        .await
 1721                        .transpose()?;
 1722                    let Some(diff) = diff else {
 1723                        zlog::trace!(logger => "No changes");
 1724                        continue;
 1725                    };
 1726
 1727                    extend_formatting_transaction(
 1728                        buffer,
 1729                        formatting_transaction_id,
 1730                        cx,
 1731                        |buffer, cx| {
 1732                            buffer.apply_diff(diff, cx);
 1733                        },
 1734                    )?;
 1735                }
 1736                Formatter::External { command, arguments } => {
 1737                    let logger = zlog::scoped!(logger => "command");
 1738                    zlog::trace!(logger => "formatting");
 1739                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1740
 1741                    let diff = Self::format_via_external_command(
 1742                        buffer,
 1743                        &command,
 1744                        arguments.as_deref(),
 1745                        cx,
 1746                    )
 1747                    .await
 1748                    .with_context(|| {
 1749                        format!("Failed to format buffer via external command: {}", command)
 1750                    })?;
 1751                    let Some(diff) = diff else {
 1752                        zlog::trace!(logger => "No changes");
 1753                        continue;
 1754                    };
 1755
 1756                    extend_formatting_transaction(
 1757                        buffer,
 1758                        formatting_transaction_id,
 1759                        cx,
 1760                        |buffer, cx| {
 1761                            buffer.apply_diff(diff, cx);
 1762                        },
 1763                    )?;
 1764                }
 1765                Formatter::LanguageServer(specifier) => {
 1766                    let logger = zlog::scoped!(logger => "language-server");
 1767                    zlog::trace!(logger => "formatting");
 1768                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1769
 1770                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1771                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1772                        continue;
 1773                    };
 1774
 1775                    let language_server = match specifier {
 1776                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1777                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1778                                if adapter.name.0.as_ref() == name {
 1779                                    Some(server.clone())
 1780                                } else {
 1781                                    None
 1782                                }
 1783                            })
 1784                        }
 1785                        settings::LanguageServerFormatterSpecifier::Current => adapters_and_servers
 1786                            .iter()
 1787                            .find(|(_, server)| Self::server_supports_formatting(server))
 1788                            .map(|(_, server)| server.clone()),
 1789                    };
 1790
 1791                    let Some(language_server) = language_server else {
 1792                        log::debug!(
 1793                            "No language server found to format buffer '{:?}'. Skipping",
 1794                            buffer_path_abs.as_path().to_string_lossy()
 1795                        );
 1796                        continue;
 1797                    };
 1798
 1799                    zlog::trace!(
 1800                        logger =>
 1801                        "Formatting buffer '{:?}' using language server '{:?}'",
 1802                        buffer_path_abs.as_path().to_string_lossy(),
 1803                        language_server.name()
 1804                    );
 1805
 1806                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1807                        zlog::trace!(logger => "formatting ranges");
 1808                        Self::format_ranges_via_lsp(
 1809                            &lsp_store,
 1810                            &buffer.handle,
 1811                            ranges,
 1812                            buffer_path_abs,
 1813                            &language_server,
 1814                            &settings,
 1815                            cx,
 1816                        )
 1817                        .await
 1818                        .context("Failed to format ranges via language server")?
 1819                    } else {
 1820                        zlog::trace!(logger => "formatting full");
 1821                        Self::format_via_lsp(
 1822                            &lsp_store,
 1823                            &buffer.handle,
 1824                            buffer_path_abs,
 1825                            &language_server,
 1826                            &settings,
 1827                            cx,
 1828                        )
 1829                        .await
 1830                        .context("failed to format via language server")?
 1831                    };
 1832
 1833                    if edits.is_empty() {
 1834                        zlog::trace!(logger => "No changes");
 1835                        continue;
 1836                    }
 1837                    extend_formatting_transaction(
 1838                        buffer,
 1839                        formatting_transaction_id,
 1840                        cx,
 1841                        |buffer, cx| {
 1842                            buffer.edit(edits, None, cx);
 1843                        },
 1844                    )?;
 1845                }
 1846                Formatter::CodeAction(code_action_name) => {
 1847                    let logger = zlog::scoped!(logger => "code-actions");
 1848                    zlog::trace!(logger => "formatting");
 1849                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1850
 1851                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1852                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1853                        continue;
 1854                    };
 1855
 1856                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1857                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1858
 1859                    let mut actions_and_servers = Vec::new();
 1860
 1861                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1862                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1863                            &lsp_store,
 1864                            language_server.server_id(),
 1865                            vec![code_action_kind.clone()],
 1866                            &buffer.handle,
 1867                            cx,
 1868                        )
 1869                        .await
 1870                        .with_context(|| {
 1871                            format!(
 1872                                "Failed to resolve code action {:?} with language server {}",
 1873                                code_action_kind,
 1874                                language_server.name()
 1875                            )
 1876                        });
 1877                        let Ok(actions) = actions_result else {
 1878                            // note: it may be better to set result to the error and break formatters here
 1879                            // but for now we try to execute the actions that we can resolve and skip the rest
 1880                            zlog::error!(
 1881                                logger =>
 1882                                "Failed to resolve code action {:?} with language server {}",
 1883                                code_action_kind,
 1884                                language_server.name()
 1885                            );
 1886                            continue;
 1887                        };
 1888                        for action in actions {
 1889                            actions_and_servers.push((action, index));
 1890                        }
 1891                    }
 1892
 1893                    if actions_and_servers.is_empty() {
 1894                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1895                        continue;
 1896                    }
 1897
 1898                    'actions: for (mut action, server_index) in actions_and_servers {
 1899                        let server = &adapters_and_servers[server_index].1;
 1900
 1901                        let describe_code_action = |action: &CodeAction| {
 1902                            format!(
 1903                                "code action '{}' with title \"{}\" on server {}",
 1904                                action
 1905                                    .lsp_action
 1906                                    .action_kind()
 1907                                    .unwrap_or("unknown".into())
 1908                                    .as_str(),
 1909                                action.lsp_action.title(),
 1910                                server.name(),
 1911                            )
 1912                        };
 1913
 1914                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1915
 1916                        if let Err(err) =
 1917                            Self::try_resolve_code_action(server, &mut action, request_timeout)
 1918                                .await
 1919                        {
 1920                            zlog::error!(
 1921                                logger =>
 1922                                "Failed to resolve {}. Error: {}",
 1923                                describe_code_action(&action),
 1924                                err
 1925                            );
 1926                            continue;
 1927                        }
 1928
 1929                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1930                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1931                            // but filters out and logs warnings for code actions that require unreasonably
 1932                            // difficult handling on our part, such as:
 1933                            // - applying edits that call commands
 1934                            //   which can result in arbitrary workspace edits being sent from the server that
 1935                            //   have no way of being tied back to the command that initiated them (i.e. we
 1936                            //   can't know which edits are part of the format request, or if the server is done sending
 1937                            //   actions in response to the command)
 1938                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1939                            //   as we then would need to handle such changes correctly in the local history as well
 1940                            //   as the remote history through the ProjectTransaction
 1941                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1942                            // Supporting these actions is not impossible, but not supported as of yet.
 1943                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1944                                zlog::trace!(
 1945                                    logger =>
 1946                                    "No changes for code action. Skipping {}",
 1947                                    describe_code_action(&action),
 1948                                );
 1949                                continue;
 1950                            }
 1951
 1952                            let mut operations = Vec::new();
 1953                            if let Some(document_changes) = edit.document_changes {
 1954                                match document_changes {
 1955                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1956                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1957                                    ),
 1958                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1959                                }
 1960                            } else if let Some(changes) = edit.changes {
 1961                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1962                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1963                                        text_document:
 1964                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1965                                                uri,
 1966                                                version: None,
 1967                                            },
 1968                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1969                                    })
 1970                                }));
 1971                            }
 1972
 1973                            let mut edits = Vec::with_capacity(operations.len());
 1974
 1975                            if operations.is_empty() {
 1976                                zlog::trace!(
 1977                                    logger =>
 1978                                    "No changes for code action. Skipping {}",
 1979                                    describe_code_action(&action),
 1980                                );
 1981                                continue;
 1982                            }
 1983                            for operation in operations {
 1984                                let op = match operation {
 1985                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1986                                    lsp::DocumentChangeOperation::Op(_) => {
 1987                                        zlog::warn!(
 1988                                            logger =>
 1989                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1990                                            describe_code_action(&action),
 1991                                        );
 1992                                        continue 'actions;
 1993                                    }
 1994                                };
 1995                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1996                                    zlog::warn!(
 1997                                        logger =>
 1998                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1999                                        &op.text_document.uri,
 2000                                        describe_code_action(&action),
 2001                                    );
 2002                                    continue 'actions;
 2003                                };
 2004                                if &file_path != buffer_path_abs {
 2005                                    zlog::warn!(
 2006                                        logger =>
 2007                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 2008                                        file_path,
 2009                                        buffer_path_abs,
 2010                                        describe_code_action(&action),
 2011                                    );
 2012                                    continue 'actions;
 2013                                }
 2014
 2015                                let mut lsp_edits = Vec::new();
 2016                                for edit in op.edits {
 2017                                    match edit {
 2018                                        Edit::Plain(edit) => {
 2019                                            if !lsp_edits.contains(&edit) {
 2020                                                lsp_edits.push(edit);
 2021                                            }
 2022                                        }
 2023                                        Edit::Annotated(edit) => {
 2024                                            if !lsp_edits.contains(&edit.text_edit) {
 2025                                                lsp_edits.push(edit.text_edit);
 2026                                            }
 2027                                        }
 2028                                        Edit::Snippet(_) => {
 2029                                            zlog::warn!(
 2030                                                logger =>
 2031                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 2032                                                describe_code_action(&action),
 2033                                            );
 2034                                            continue 'actions;
 2035                                        }
 2036                                    }
 2037                                }
 2038                                let edits_result = lsp_store
 2039                                    .update(cx, |lsp_store, cx| {
 2040                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 2041                                            &buffer.handle,
 2042                                            lsp_edits,
 2043                                            server.server_id(),
 2044                                            op.text_document.version,
 2045                                            cx,
 2046                                        )
 2047                                    })?
 2048                                    .await;
 2049                                let Ok(resolved_edits) = edits_result else {
 2050                                    zlog::warn!(
 2051                                        logger =>
 2052                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 2053                                        buffer_path_abs.as_path(),
 2054                                        describe_code_action(&action),
 2055                                    );
 2056                                    continue 'actions;
 2057                                };
 2058                                edits.extend(resolved_edits);
 2059                            }
 2060
 2061                            if edits.is_empty() {
 2062                                zlog::warn!(logger => "No edits resolved from LSP");
 2063                                continue;
 2064                            }
 2065
 2066                            extend_formatting_transaction(
 2067                                buffer,
 2068                                formatting_transaction_id,
 2069                                cx,
 2070                                |buffer, cx| {
 2071                                    zlog::info!(
 2072                                        "Applying edits {edits:?}. Content: {:?}",
 2073                                        buffer.text()
 2074                                    );
 2075                                    buffer.edit(edits, None, cx);
 2076                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 2077                                },
 2078                            )?;
 2079                        }
 2080
 2081                        // bail early if command is invalid
 2082                        let Some(command) = action.lsp_action.command() else {
 2083                            continue;
 2084                        };
 2085
 2086                        zlog::warn!(
 2087                            logger =>
 2088                            "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2089                            &command.command,
 2090                        );
 2091
 2092                        let server_capabilities = server.capabilities();
 2093                        let available_commands = server_capabilities
 2094                            .execute_command_provider
 2095                            .as_ref()
 2096                            .map(|options| options.commands.as_slice())
 2097                            .unwrap_or_default();
 2098                        if !available_commands.contains(&command.command) {
 2099                            zlog::warn!(
 2100                                logger =>
 2101                                "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2102                                command.command,
 2103                                server.name(),
 2104                            );
 2105                            continue;
 2106                        }
 2107
 2108                        // noop so we just ensure buffer hasn't been edited since resolving code actions
 2109                        extend_formatting_transaction(
 2110                            buffer,
 2111                            formatting_transaction_id,
 2112                            cx,
 2113                            |_, _| {},
 2114                        )?;
 2115                        zlog::info!(logger => "Executing command {}", &command.command);
 2116
 2117                        lsp_store.update(cx, |this, _| {
 2118                            this.as_local_mut()
 2119                                .unwrap()
 2120                                .last_workspace_edits_by_language_server
 2121                                .remove(&server.server_id());
 2122                        })?;
 2123
 2124                        let execute_command_result = server
 2125                            .request::<lsp::request::ExecuteCommand>(
 2126                                lsp::ExecuteCommandParams {
 2127                                    command: command.command.clone(),
 2128                                    arguments: command.arguments.clone().unwrap_or_default(),
 2129                                    ..Default::default()
 2130                                },
 2131                                request_timeout,
 2132                            )
 2133                            .await
 2134                            .into_response();
 2135
 2136                        if execute_command_result.is_err() {
 2137                            zlog::error!(
 2138                                logger =>
 2139                                "Failed to execute command '{}' as part of {}",
 2140                                &command.command,
 2141                                describe_code_action(&action),
 2142                            );
 2143                            continue 'actions;
 2144                        }
 2145
 2146                        let mut project_transaction_command = lsp_store.update(cx, |this, _| {
 2147                            this.as_local_mut()
 2148                                .unwrap()
 2149                                .last_workspace_edits_by_language_server
 2150                                .remove(&server.server_id())
 2151                                .unwrap_or_default()
 2152                        })?;
 2153
 2154                        if let Some(transaction) =
 2155                            project_transaction_command.0.remove(&buffer.handle)
 2156                        {
 2157                            zlog::trace!(
 2158                                logger =>
 2159                                "Successfully captured {} edits that resulted from command {}",
 2160                                transaction.edit_ids.len(),
 2161                                &command.command,
 2162                            );
 2163                            let transaction_id_project_transaction = transaction.id;
 2164                            buffer.handle.update(cx, |buffer, _| {
 2165                                // it may have been removed from history if push_to_history was
 2166                                // false in deserialize_workspace_edit. If so push it so we
 2167                                // can merge it with the format transaction
 2168                                // and pop the combined transaction off the history stack
 2169                                // later if push_to_history is false
 2170                                if buffer.get_transaction(transaction.id).is_none() {
 2171                                    buffer.push_transaction(transaction, Instant::now());
 2172                                }
 2173                                buffer.merge_transactions(
 2174                                    transaction_id_project_transaction,
 2175                                    formatting_transaction_id,
 2176                                );
 2177                            });
 2178                        }
 2179
 2180                        if project_transaction_command.0.is_empty() {
 2181                            continue;
 2182                        }
 2183
 2184                        let mut extra_buffers = String::new();
 2185                        for buffer in project_transaction_command.0.keys() {
 2186                            buffer.read_with(cx, |b, cx| {
 2187                                let Some(path) = b.project_path(cx) else {
 2188                                    return;
 2189                                };
 2190
 2191                                if !extra_buffers.is_empty() {
 2192                                    extra_buffers.push_str(", ");
 2193                                }
 2194                                extra_buffers.push_str(path.path.as_unix_str());
 2195                            });
 2196                        }
 2197                        zlog::warn!(
 2198                            logger =>
 2199                            "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2200                            &command.command,
 2201                            extra_buffers,
 2202                        );
 2203                        // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2204                        // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2205                        // add it so it's included, and merge it into the format transaction when its created later
 2206                    }
 2207                }
 2208            }
 2209        }
 2210
 2211        Ok(())
 2212    }
 2213
 2214    pub async fn format_ranges_via_lsp(
 2215        this: &WeakEntity<LspStore>,
 2216        buffer_handle: &Entity<Buffer>,
 2217        ranges: &[Range<Anchor>],
 2218        abs_path: &Path,
 2219        language_server: &Arc<LanguageServer>,
 2220        settings: &LanguageSettings,
 2221        cx: &mut AsyncApp,
 2222    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2223        let capabilities = &language_server.capabilities();
 2224        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2225        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2226            anyhow::bail!(
 2227                "{} language server does not support range formatting",
 2228                language_server.name()
 2229            );
 2230        }
 2231
 2232        let uri = file_path_to_lsp_url(abs_path)?;
 2233        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2234
 2235        let request_timeout = cx.update(|app| {
 2236            ProjectSettings::get_global(app)
 2237                .global_lsp_settings
 2238                .get_request_timeout()
 2239        });
 2240        let lsp_edits = {
 2241            let mut lsp_ranges = Vec::new();
 2242            this.update(cx, |_this, cx| {
 2243                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2244                // not have been sent to the language server. This seems like a fairly systemic
 2245                // issue, though, the resolution probably is not specific to formatting.
 2246                //
 2247                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2248                // LSP.
 2249                let snapshot = buffer_handle.read(cx).snapshot();
 2250                for range in ranges {
 2251                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2252                }
 2253                anyhow::Ok(())
 2254            })??;
 2255
 2256            let mut edits = None;
 2257            for range in lsp_ranges {
 2258                if let Some(mut edit) = language_server
 2259                    .request::<lsp::request::RangeFormatting>(
 2260                        lsp::DocumentRangeFormattingParams {
 2261                            text_document: text_document.clone(),
 2262                            range,
 2263                            options: lsp_command::lsp_formatting_options(settings),
 2264                            work_done_progress_params: Default::default(),
 2265                        },
 2266                        request_timeout,
 2267                    )
 2268                    .await
 2269                    .into_response()?
 2270                {
 2271                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2272                }
 2273            }
 2274            edits
 2275        };
 2276
 2277        if let Some(lsp_edits) = lsp_edits {
 2278            this.update(cx, |this, cx| {
 2279                this.as_local_mut().unwrap().edits_from_lsp(
 2280                    buffer_handle,
 2281                    lsp_edits,
 2282                    language_server.server_id(),
 2283                    None,
 2284                    cx,
 2285                )
 2286            })?
 2287            .await
 2288        } else {
 2289            Ok(Vec::with_capacity(0))
 2290        }
 2291    }
 2292
 2293    fn server_supports_formatting(server: &Arc<LanguageServer>) -> bool {
 2294        let capabilities = server.capabilities();
 2295        let formatting = capabilities.document_formatting_provider.as_ref();
 2296        let range_formatting = capabilities.document_range_formatting_provider.as_ref();
 2297        matches!(formatting, Some(p) if *p != OneOf::Left(false))
 2298            || matches!(range_formatting, Some(p) if *p != OneOf::Left(false))
 2299    }
 2300
 2301    async fn format_via_lsp(
 2302        this: &WeakEntity<LspStore>,
 2303        buffer: &Entity<Buffer>,
 2304        abs_path: &Path,
 2305        language_server: &Arc<LanguageServer>,
 2306        settings: &LanguageSettings,
 2307        cx: &mut AsyncApp,
 2308    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2309        let logger = zlog::scoped!("lsp_format");
 2310        zlog::debug!(logger => "Formatting via LSP");
 2311
 2312        let uri = file_path_to_lsp_url(abs_path)?;
 2313        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2314        let capabilities = &language_server.capabilities();
 2315
 2316        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2317        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2318
 2319        let request_timeout = cx.update(|app| {
 2320            ProjectSettings::get_global(app)
 2321                .global_lsp_settings
 2322                .get_request_timeout()
 2323        });
 2324
 2325        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2326            let _timer = zlog::time!(logger => "format-full");
 2327            language_server
 2328                .request::<lsp::request::Formatting>(
 2329                    lsp::DocumentFormattingParams {
 2330                        text_document,
 2331                        options: lsp_command::lsp_formatting_options(settings),
 2332                        work_done_progress_params: Default::default(),
 2333                    },
 2334                    request_timeout,
 2335                )
 2336                .await
 2337                .into_response()?
 2338        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2339            let _timer = zlog::time!(logger => "format-range");
 2340            let buffer_start = lsp::Position::new(0, 0);
 2341            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2342            language_server
 2343                .request::<lsp::request::RangeFormatting>(
 2344                    lsp::DocumentRangeFormattingParams {
 2345                        text_document: text_document.clone(),
 2346                        range: lsp::Range::new(buffer_start, buffer_end),
 2347                        options: lsp_command::lsp_formatting_options(settings),
 2348                        work_done_progress_params: Default::default(),
 2349                    },
 2350                    request_timeout,
 2351                )
 2352                .await
 2353                .into_response()?
 2354        } else {
 2355            None
 2356        };
 2357
 2358        if let Some(lsp_edits) = lsp_edits {
 2359            this.update(cx, |this, cx| {
 2360                this.as_local_mut().unwrap().edits_from_lsp(
 2361                    buffer,
 2362                    lsp_edits,
 2363                    language_server.server_id(),
 2364                    None,
 2365                    cx,
 2366                )
 2367            })?
 2368            .await
 2369        } else {
 2370            Ok(Vec::with_capacity(0))
 2371        }
 2372    }
 2373
 2374    async fn format_via_external_command(
 2375        buffer: &FormattableBuffer,
 2376        command: &str,
 2377        arguments: Option<&[String]>,
 2378        cx: &mut AsyncApp,
 2379    ) -> Result<Option<Diff>> {
 2380        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2381            let file = File::from_dyn(buffer.file())?;
 2382            let worktree = file.worktree.read(cx);
 2383            let mut worktree_path = worktree.abs_path().to_path_buf();
 2384            if worktree.root_entry()?.is_file() {
 2385                worktree_path.pop();
 2386            }
 2387            Some(worktree_path)
 2388        });
 2389
 2390        use util::command::Stdio;
 2391        let mut child = util::command::new_command(command);
 2392
 2393        if let Some(buffer_env) = buffer.env.as_ref() {
 2394            child.envs(buffer_env);
 2395        }
 2396
 2397        if let Some(working_dir_path) = working_dir_path {
 2398            child.current_dir(working_dir_path);
 2399        }
 2400
 2401        if let Some(arguments) = arguments {
 2402            child.args(arguments.iter().map(|arg| {
 2403                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2404                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2405                } else {
 2406                    arg.replace("{buffer_path}", "Untitled")
 2407                }
 2408            }));
 2409        }
 2410
 2411        let mut child = child
 2412            .stdin(Stdio::piped())
 2413            .stdout(Stdio::piped())
 2414            .stderr(Stdio::piped())
 2415            .spawn()?;
 2416
 2417        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2418        let text = buffer
 2419            .handle
 2420            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2421        for chunk in text.chunks() {
 2422            stdin.write_all(chunk.as_bytes()).await?;
 2423        }
 2424        stdin.flush().await?;
 2425
 2426        let output = child.output().await?;
 2427        anyhow::ensure!(
 2428            output.status.success(),
 2429            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2430            output.status.code(),
 2431            String::from_utf8_lossy(&output.stdout),
 2432            String::from_utf8_lossy(&output.stderr),
 2433        );
 2434
 2435        let stdout = String::from_utf8(output.stdout)?;
 2436        Ok(Some(
 2437            buffer
 2438                .handle
 2439                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2440                .await,
 2441        ))
 2442    }
 2443
 2444    async fn try_resolve_code_action(
 2445        lang_server: &LanguageServer,
 2446        action: &mut CodeAction,
 2447        request_timeout: Duration,
 2448    ) -> anyhow::Result<()> {
 2449        match &mut action.lsp_action {
 2450            LspAction::Action(lsp_action) => {
 2451                if !action.resolved
 2452                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2453                    && lsp_action.data.is_some()
 2454                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2455                {
 2456                    **lsp_action = lang_server
 2457                        .request::<lsp::request::CodeActionResolveRequest>(
 2458                            *lsp_action.clone(),
 2459                            request_timeout,
 2460                        )
 2461                        .await
 2462                        .into_response()?;
 2463                }
 2464            }
 2465            LspAction::CodeLens(lens) => {
 2466                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2467                    *lens = lang_server
 2468                        .request::<lsp::request::CodeLensResolve>(lens.clone(), request_timeout)
 2469                        .await
 2470                        .into_response()?;
 2471                }
 2472            }
 2473            LspAction::Command(_) => {}
 2474        }
 2475
 2476        action.resolved = true;
 2477        anyhow::Ok(())
 2478    }
 2479
 2480    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2481        let buffer = buffer_handle.read(cx);
 2482
 2483        let file = buffer.file().cloned();
 2484
 2485        let Some(file) = File::from_dyn(file.as_ref()) else {
 2486            return;
 2487        };
 2488        if !file.is_local() {
 2489            return;
 2490        }
 2491        let path = ProjectPath::from_file(file, cx);
 2492        let worktree_id = file.worktree_id(cx);
 2493        let language = buffer.language().cloned();
 2494
 2495        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2496            for (server_id, diagnostics) in
 2497                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2498            {
 2499                self.update_buffer_diagnostics(
 2500                    buffer_handle,
 2501                    server_id,
 2502                    None,
 2503                    None,
 2504                    None,
 2505                    Vec::new(),
 2506                    diagnostics,
 2507                    cx,
 2508                )
 2509                .log_err();
 2510            }
 2511        }
 2512        let Some(language) = language else {
 2513            return;
 2514        };
 2515        let Some(snapshot) = self
 2516            .worktree_store
 2517            .read(cx)
 2518            .worktree_for_id(worktree_id, cx)
 2519            .map(|worktree| worktree.read(cx).snapshot())
 2520        else {
 2521            return;
 2522        };
 2523        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2524
 2525        for server_id in
 2526            self.lsp_tree
 2527                .get(path, language.name(), language.manifest(), &delegate, cx)
 2528        {
 2529            let server = self
 2530                .language_servers
 2531                .get(&server_id)
 2532                .and_then(|server_state| {
 2533                    if let LanguageServerState::Running { server, .. } = server_state {
 2534                        Some(server.clone())
 2535                    } else {
 2536                        None
 2537                    }
 2538                });
 2539            let server = match server {
 2540                Some(server) => server,
 2541                None => continue,
 2542            };
 2543
 2544            buffer_handle.update(cx, |buffer, cx| {
 2545                buffer.set_completion_triggers(
 2546                    server.server_id(),
 2547                    server
 2548                        .capabilities()
 2549                        .completion_provider
 2550                        .as_ref()
 2551                        .and_then(|provider| {
 2552                            provider
 2553                                .trigger_characters
 2554                                .as_ref()
 2555                                .map(|characters| characters.iter().cloned().collect())
 2556                        })
 2557                        .unwrap_or_default(),
 2558                    cx,
 2559                );
 2560            });
 2561        }
 2562    }
 2563
 2564    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2565        buffer.update(cx, |buffer, cx| {
 2566            let Some(language) = buffer.language() else {
 2567                return;
 2568            };
 2569            let path = ProjectPath {
 2570                worktree_id: old_file.worktree_id(cx),
 2571                path: old_file.path.clone(),
 2572            };
 2573            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2574                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2575                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2576            }
 2577        });
 2578    }
 2579
 2580    fn update_buffer_diagnostics(
 2581        &mut self,
 2582        buffer: &Entity<Buffer>,
 2583        server_id: LanguageServerId,
 2584        registration_id: Option<Option<SharedString>>,
 2585        result_id: Option<SharedString>,
 2586        version: Option<i32>,
 2587        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2588        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2589        cx: &mut Context<LspStore>,
 2590    ) -> Result<()> {
 2591        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2592            Ordering::Equal
 2593                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2594                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2595                .then_with(|| a.severity.cmp(&b.severity))
 2596                .then_with(|| a.message.cmp(&b.message))
 2597        }
 2598
 2599        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2600        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2601        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2602
 2603        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2604            Ordering::Equal
 2605                .then_with(|| a.range.start.cmp(&b.range.start))
 2606                .then_with(|| b.range.end.cmp(&a.range.end))
 2607                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2608        });
 2609
 2610        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2611
 2612        let edits_since_save = std::cell::LazyCell::new(|| {
 2613            let saved_version = buffer.read(cx).saved_version();
 2614            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2615        });
 2616
 2617        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2618
 2619        for (new_diagnostic, entry) in diagnostics {
 2620            let start;
 2621            let end;
 2622            if new_diagnostic && entry.diagnostic.is_disk_based {
 2623                // Some diagnostics are based on files on disk instead of buffers'
 2624                // current contents. Adjust these diagnostics' ranges to reflect
 2625                // any unsaved edits.
 2626                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2627                // and were properly adjusted on reuse.
 2628                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2629                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2630            } else {
 2631                start = entry.range.start;
 2632                end = entry.range.end;
 2633            }
 2634
 2635            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2636                ..snapshot.clip_point_utf16(end, Bias::Right);
 2637
 2638            // Expand empty ranges by one codepoint
 2639            if range.start == range.end {
 2640                // This will be go to the next boundary when being clipped
 2641                range.end.column += 1;
 2642                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2643                if range.start == range.end && range.end.column > 0 {
 2644                    range.start.column -= 1;
 2645                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2646                }
 2647            }
 2648
 2649            sanitized_diagnostics.push(DiagnosticEntry {
 2650                range,
 2651                diagnostic: entry.diagnostic,
 2652            });
 2653        }
 2654        drop(edits_since_save);
 2655
 2656        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2657        buffer.update(cx, |buffer, cx| {
 2658            if let Some(registration_id) = registration_id {
 2659                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2660                    self.buffer_pull_diagnostics_result_ids
 2661                        .entry(server_id)
 2662                        .or_default()
 2663                        .entry(registration_id)
 2664                        .or_default()
 2665                        .insert(abs_path, result_id);
 2666                }
 2667            }
 2668
 2669            buffer.update_diagnostics(server_id, set, cx)
 2670        });
 2671
 2672        Ok(())
 2673    }
 2674
 2675    fn register_language_server_for_invisible_worktree(
 2676        &mut self,
 2677        worktree: &Entity<Worktree>,
 2678        language_server_id: LanguageServerId,
 2679        cx: &mut App,
 2680    ) {
 2681        let worktree = worktree.read(cx);
 2682        let worktree_id = worktree.id();
 2683        debug_assert!(!worktree.is_visible());
 2684        let Some(mut origin_seed) = self
 2685            .language_server_ids
 2686            .iter()
 2687            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2688        else {
 2689            return;
 2690        };
 2691        origin_seed.worktree_id = worktree_id;
 2692        self.language_server_ids
 2693            .entry(origin_seed)
 2694            .or_insert_with(|| UnifiedLanguageServer {
 2695                id: language_server_id,
 2696                project_roots: Default::default(),
 2697            });
 2698    }
 2699
 2700    fn register_buffer_with_language_servers(
 2701        &mut self,
 2702        buffer_handle: &Entity<Buffer>,
 2703        only_register_servers: HashSet<LanguageServerSelector>,
 2704        cx: &mut Context<LspStore>,
 2705    ) {
 2706        let buffer = buffer_handle.read(cx);
 2707        let buffer_id = buffer.remote_id();
 2708
 2709        let Some(file) = File::from_dyn(buffer.file()) else {
 2710            return;
 2711        };
 2712        if !file.is_local() {
 2713            return;
 2714        }
 2715
 2716        let abs_path = file.abs_path(cx);
 2717        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2718            return;
 2719        };
 2720        let initial_snapshot = buffer.text_snapshot();
 2721        let worktree_id = file.worktree_id(cx);
 2722
 2723        let Some(language) = buffer.language().cloned() else {
 2724            return;
 2725        };
 2726        let path: Arc<RelPath> = file
 2727            .path()
 2728            .parent()
 2729            .map(Arc::from)
 2730            .unwrap_or_else(|| file.path().clone());
 2731        let Some(worktree) = self
 2732            .worktree_store
 2733            .read(cx)
 2734            .worktree_for_id(worktree_id, cx)
 2735        else {
 2736            return;
 2737        };
 2738        let language_name = language.name();
 2739        let (reused, delegate, servers) = self
 2740            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2741            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2742            .unwrap_or_else(|| {
 2743                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2744                let delegate: Arc<dyn ManifestDelegate> =
 2745                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2746
 2747                let servers = self
 2748                    .lsp_tree
 2749                    .walk(
 2750                        ProjectPath { worktree_id, path },
 2751                        language.name(),
 2752                        language.manifest(),
 2753                        &delegate,
 2754                        cx,
 2755                    )
 2756                    .collect::<Vec<_>>();
 2757                (false, lsp_delegate, servers)
 2758            });
 2759        let servers_and_adapters = servers
 2760            .into_iter()
 2761            .filter_map(|server_node| {
 2762                if reused && server_node.server_id().is_none() {
 2763                    return None;
 2764                }
 2765                if !only_register_servers.is_empty() {
 2766                    if let Some(server_id) = server_node.server_id()
 2767                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2768                    {
 2769                        return None;
 2770                    }
 2771                    if let Some(name) = server_node.name()
 2772                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2773                    {
 2774                        return None;
 2775                    }
 2776                }
 2777
 2778                let server_id = server_node.server_id_or_init(|disposition| {
 2779                    let path = &disposition.path;
 2780
 2781                    {
 2782                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2783
 2784                        let server_id = self.get_or_insert_language_server(
 2785                            &worktree,
 2786                            delegate.clone(),
 2787                            disposition,
 2788                            &language_name,
 2789                            cx,
 2790                        );
 2791
 2792                        if let Some(state) = self.language_servers.get(&server_id)
 2793                            && let Ok(uri) = uri
 2794                        {
 2795                            state.add_workspace_folder(uri);
 2796                        };
 2797                        server_id
 2798                    }
 2799                })?;
 2800                let server_state = self.language_servers.get(&server_id)?;
 2801                if let LanguageServerState::Running {
 2802                    server, adapter, ..
 2803                } = server_state
 2804                {
 2805                    Some((server.clone(), adapter.clone()))
 2806                } else {
 2807                    None
 2808                }
 2809            })
 2810            .collect::<Vec<_>>();
 2811        for (server, adapter) in servers_and_adapters {
 2812            buffer_handle.update(cx, |buffer, cx| {
 2813                buffer.set_completion_triggers(
 2814                    server.server_id(),
 2815                    server
 2816                        .capabilities()
 2817                        .completion_provider
 2818                        .as_ref()
 2819                        .and_then(|provider| {
 2820                            provider
 2821                                .trigger_characters
 2822                                .as_ref()
 2823                                .map(|characters| characters.iter().cloned().collect())
 2824                        })
 2825                        .unwrap_or_default(),
 2826                    cx,
 2827                );
 2828            });
 2829
 2830            let snapshot = LspBufferSnapshot {
 2831                version: 0,
 2832                snapshot: initial_snapshot.clone(),
 2833            };
 2834
 2835            let mut registered = false;
 2836            self.buffer_snapshots
 2837                .entry(buffer_id)
 2838                .or_default()
 2839                .entry(server.server_id())
 2840                .or_insert_with(|| {
 2841                    registered = true;
 2842                    server.register_buffer(
 2843                        uri.clone(),
 2844                        adapter.language_id(&language.name()),
 2845                        0,
 2846                        initial_snapshot.text(),
 2847                    );
 2848
 2849                    vec![snapshot]
 2850                });
 2851
 2852            self.buffers_opened_in_servers
 2853                .entry(buffer_id)
 2854                .or_default()
 2855                .insert(server.server_id());
 2856            if registered {
 2857                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2858                    language_server_id: server.server_id(),
 2859                    name: None,
 2860                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2861                        proto::RegisteredForBuffer {
 2862                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2863                            buffer_id: buffer_id.to_proto(),
 2864                        },
 2865                    ),
 2866                });
 2867            }
 2868        }
 2869    }
 2870
 2871    fn reuse_existing_language_server<'lang_name>(
 2872        &self,
 2873        server_tree: &LanguageServerTree,
 2874        worktree: &Entity<Worktree>,
 2875        language_name: &'lang_name LanguageName,
 2876        cx: &mut App,
 2877    ) -> Option<(
 2878        Arc<LocalLspAdapterDelegate>,
 2879        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2880    )> {
 2881        if worktree.read(cx).is_visible() {
 2882            return None;
 2883        }
 2884
 2885        let worktree_store = self.worktree_store.read(cx);
 2886        let servers = server_tree
 2887            .instances
 2888            .iter()
 2889            .filter(|(worktree_id, _)| {
 2890                worktree_store
 2891                    .worktree_for_id(**worktree_id, cx)
 2892                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2893            })
 2894            .flat_map(|(worktree_id, servers)| {
 2895                servers
 2896                    .roots
 2897                    .iter()
 2898                    .flat_map(|(_, language_servers)| language_servers)
 2899                    .map(move |(_, (server_node, server_languages))| {
 2900                        (worktree_id, server_node, server_languages)
 2901                    })
 2902                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2903                    .map(|(worktree_id, server_node, _)| {
 2904                        (
 2905                            *worktree_id,
 2906                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2907                        )
 2908                    })
 2909            })
 2910            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2911                acc.entry(worktree_id)
 2912                    .or_insert_with(Vec::new)
 2913                    .push(server_node);
 2914                acc
 2915            })
 2916            .into_values()
 2917            .max_by_key(|servers| servers.len())?;
 2918
 2919        let worktree_id = worktree.read(cx).id();
 2920        let apply = move |tree: &mut LanguageServerTree| {
 2921            for server_node in &servers {
 2922                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2923            }
 2924            servers
 2925        };
 2926
 2927        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2928        Some((delegate, apply))
 2929    }
 2930
 2931    pub(crate) fn unregister_old_buffer_from_language_servers(
 2932        &mut self,
 2933        buffer: &Entity<Buffer>,
 2934        old_file: &File,
 2935        cx: &mut App,
 2936    ) {
 2937        let old_path = match old_file.as_local() {
 2938            Some(local) => local.abs_path(cx),
 2939            None => return,
 2940        };
 2941
 2942        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2943            debug_panic!("{old_path:?} is not parseable as an URI");
 2944            return;
 2945        };
 2946        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2947    }
 2948
 2949    pub(crate) fn unregister_buffer_from_language_servers(
 2950        &mut self,
 2951        buffer: &Entity<Buffer>,
 2952        file_url: &lsp::Uri,
 2953        cx: &mut App,
 2954    ) {
 2955        buffer.update(cx, |buffer, cx| {
 2956            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2957
 2958            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2959                if snapshots
 2960                    .as_mut()
 2961                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2962                {
 2963                    language_server.unregister_buffer(file_url.clone());
 2964                }
 2965            }
 2966        });
 2967    }
 2968
 2969    fn buffer_snapshot_for_lsp_version(
 2970        &mut self,
 2971        buffer: &Entity<Buffer>,
 2972        server_id: LanguageServerId,
 2973        version: Option<i32>,
 2974        cx: &App,
 2975    ) -> Result<TextBufferSnapshot> {
 2976        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2977
 2978        if let Some(version) = version {
 2979            let buffer_id = buffer.read(cx).remote_id();
 2980            let snapshots = if let Some(snapshots) = self
 2981                .buffer_snapshots
 2982                .get_mut(&buffer_id)
 2983                .and_then(|m| m.get_mut(&server_id))
 2984            {
 2985                snapshots
 2986            } else if version == 0 {
 2987                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2988                // We detect this case and treat it as if the version was `None`.
 2989                return Ok(buffer.read(cx).text_snapshot());
 2990            } else {
 2991                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2992            };
 2993
 2994            let found_snapshot = snapshots
 2995                    .binary_search_by_key(&version, |e| e.version)
 2996                    .map(|ix| snapshots[ix].snapshot.clone())
 2997                    .map_err(|_| {
 2998                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2999                    })?;
 3000
 3001            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 3002            Ok(found_snapshot)
 3003        } else {
 3004            Ok((buffer.read(cx)).text_snapshot())
 3005        }
 3006    }
 3007
 3008    async fn get_server_code_actions_from_action_kinds(
 3009        lsp_store: &WeakEntity<LspStore>,
 3010        language_server_id: LanguageServerId,
 3011        code_action_kinds: Vec<lsp::CodeActionKind>,
 3012        buffer: &Entity<Buffer>,
 3013        cx: &mut AsyncApp,
 3014    ) -> Result<Vec<CodeAction>> {
 3015        let actions = lsp_store
 3016            .update(cx, move |this, cx| {
 3017                let request = GetCodeActions {
 3018                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 3019                    kinds: Some(code_action_kinds),
 3020                };
 3021                let server = LanguageServerToQuery::Other(language_server_id);
 3022                this.request_lsp(buffer.clone(), server, request, cx)
 3023            })?
 3024            .await?;
 3025        Ok(actions)
 3026    }
 3027
 3028    pub async fn execute_code_actions_on_server(
 3029        lsp_store: &WeakEntity<LspStore>,
 3030        language_server: &Arc<LanguageServer>,
 3031        actions: Vec<CodeAction>,
 3032        push_to_history: bool,
 3033        project_transaction: &mut ProjectTransaction,
 3034        cx: &mut AsyncApp,
 3035    ) -> anyhow::Result<()> {
 3036        let request_timeout = cx.update(|app| {
 3037            ProjectSettings::get_global(app)
 3038                .global_lsp_settings
 3039                .get_request_timeout()
 3040        });
 3041
 3042        for mut action in actions {
 3043            Self::try_resolve_code_action(language_server, &mut action, request_timeout)
 3044                .await
 3045                .context("resolving a formatting code action")?;
 3046
 3047            if let Some(edit) = action.lsp_action.edit() {
 3048                if edit.changes.is_none() && edit.document_changes.is_none() {
 3049                    continue;
 3050                }
 3051
 3052                let new = Self::deserialize_workspace_edit(
 3053                    lsp_store.upgrade().context("project dropped")?,
 3054                    edit.clone(),
 3055                    push_to_history,
 3056                    language_server.clone(),
 3057                    cx,
 3058                )
 3059                .await?;
 3060                project_transaction.0.extend(new.0);
 3061            }
 3062
 3063            let Some(command) = action.lsp_action.command() else {
 3064                continue;
 3065            };
 3066
 3067            let server_capabilities = language_server.capabilities();
 3068            let available_commands = server_capabilities
 3069                .execute_command_provider
 3070                .as_ref()
 3071                .map(|options| options.commands.as_slice())
 3072                .unwrap_or_default();
 3073            if !available_commands.contains(&command.command) {
 3074                log::warn!(
 3075                    "Cannot execute a command {} not listed in the language server capabilities",
 3076                    command.command
 3077                );
 3078                continue;
 3079            }
 3080
 3081            lsp_store.update(cx, |lsp_store, _| {
 3082                if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 3083                    mode.last_workspace_edits_by_language_server
 3084                        .remove(&language_server.server_id());
 3085                }
 3086            })?;
 3087
 3088            language_server
 3089                .request::<lsp::request::ExecuteCommand>(
 3090                    lsp::ExecuteCommandParams {
 3091                        command: command.command.clone(),
 3092                        arguments: command.arguments.clone().unwrap_or_default(),
 3093                        ..Default::default()
 3094                    },
 3095                    request_timeout,
 3096                )
 3097                .await
 3098                .into_response()
 3099                .context("execute command")?;
 3100
 3101            lsp_store.update(cx, |this, _| {
 3102                if let LspStoreMode::Local(mode) = &mut this.mode {
 3103                    project_transaction.0.extend(
 3104                        mode.last_workspace_edits_by_language_server
 3105                            .remove(&language_server.server_id())
 3106                            .unwrap_or_default()
 3107                            .0,
 3108                    )
 3109                }
 3110            })?;
 3111        }
 3112        Ok(())
 3113    }
 3114
 3115    pub async fn deserialize_text_edits(
 3116        this: Entity<LspStore>,
 3117        buffer_to_edit: Entity<Buffer>,
 3118        edits: Vec<lsp::TextEdit>,
 3119        push_to_history: bool,
 3120        _: Arc<CachedLspAdapter>,
 3121        language_server: Arc<LanguageServer>,
 3122        cx: &mut AsyncApp,
 3123    ) -> Result<Option<Transaction>> {
 3124        let edits = this
 3125            .update(cx, |this, cx| {
 3126                this.as_local_mut().unwrap().edits_from_lsp(
 3127                    &buffer_to_edit,
 3128                    edits,
 3129                    language_server.server_id(),
 3130                    None,
 3131                    cx,
 3132                )
 3133            })
 3134            .await?;
 3135
 3136        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3137            buffer.finalize_last_transaction();
 3138            buffer.start_transaction();
 3139            for (range, text) in edits {
 3140                buffer.edit([(range, text)], None, cx);
 3141            }
 3142
 3143            if buffer.end_transaction(cx).is_some() {
 3144                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3145                if !push_to_history {
 3146                    buffer.forget_transaction(transaction.id);
 3147                }
 3148                Some(transaction)
 3149            } else {
 3150                None
 3151            }
 3152        });
 3153
 3154        Ok(transaction)
 3155    }
 3156
 3157    #[allow(clippy::type_complexity)]
 3158    pub fn edits_from_lsp(
 3159        &mut self,
 3160        buffer: &Entity<Buffer>,
 3161        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3162        server_id: LanguageServerId,
 3163        version: Option<i32>,
 3164        cx: &mut Context<LspStore>,
 3165    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3166        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3167        cx.background_spawn(async move {
 3168            let snapshot = snapshot?;
 3169            let mut lsp_edits = lsp_edits
 3170                .into_iter()
 3171                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3172                .collect::<Vec<_>>();
 3173
 3174            lsp_edits.sort_unstable_by_key(|(range, _)| (range.start, range.end));
 3175
 3176            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3177            let mut edits = Vec::new();
 3178            while let Some((range, mut new_text)) = lsp_edits.next() {
 3179                // Clip invalid ranges provided by the language server.
 3180                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3181                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3182
 3183                // Combine any LSP edits that are adjacent.
 3184                //
 3185                // Also, combine LSP edits that are separated from each other by only
 3186                // a newline. This is important because for some code actions,
 3187                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3188                // are separated by unchanged newline characters.
 3189                //
 3190                // In order for the diffing logic below to work properly, any edits that
 3191                // cancel each other out must be combined into one.
 3192                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3193                    if next_range.start.0 > range.end {
 3194                        if next_range.start.0.row > range.end.row + 1
 3195                            || next_range.start.0.column > 0
 3196                            || snapshot.clip_point_utf16(
 3197                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3198                                Bias::Left,
 3199                            ) > range.end
 3200                        {
 3201                            break;
 3202                        }
 3203                        new_text.push('\n');
 3204                    }
 3205                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3206                    new_text.push_str(next_text);
 3207                    lsp_edits.next();
 3208                }
 3209
 3210                // For multiline edits, perform a diff of the old and new text so that
 3211                // we can identify the changes more precisely, preserving the locations
 3212                // of any anchors positioned in the unchanged regions.
 3213                if range.end.row > range.start.row {
 3214                    let offset = range.start.to_offset(&snapshot);
 3215                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3216                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3217                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3218                        (
 3219                            snapshot.anchor_after(offset + range.start)
 3220                                ..snapshot.anchor_before(offset + range.end),
 3221                            replacement,
 3222                        )
 3223                    }));
 3224                } else if range.end == range.start {
 3225                    let anchor = snapshot.anchor_after(range.start);
 3226                    edits.push((anchor..anchor, new_text.into()));
 3227                } else {
 3228                    let edit_start = snapshot.anchor_after(range.start);
 3229                    let edit_end = snapshot.anchor_before(range.end);
 3230                    edits.push((edit_start..edit_end, new_text.into()));
 3231                }
 3232            }
 3233
 3234            Ok(edits)
 3235        })
 3236    }
 3237
 3238    pub(crate) async fn deserialize_workspace_edit(
 3239        this: Entity<LspStore>,
 3240        edit: lsp::WorkspaceEdit,
 3241        push_to_history: bool,
 3242        language_server: Arc<LanguageServer>,
 3243        cx: &mut AsyncApp,
 3244    ) -> Result<ProjectTransaction> {
 3245        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3246
 3247        let mut operations = Vec::new();
 3248        if let Some(document_changes) = edit.document_changes {
 3249            match document_changes {
 3250                lsp::DocumentChanges::Edits(edits) => {
 3251                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3252                }
 3253                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3254            }
 3255        } else if let Some(changes) = edit.changes {
 3256            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3257                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3258                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3259                        uri,
 3260                        version: None,
 3261                    },
 3262                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3263                })
 3264            }));
 3265        }
 3266
 3267        let mut project_transaction = ProjectTransaction::default();
 3268        for operation in operations {
 3269            match operation {
 3270                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3271                    let abs_path = op
 3272                        .uri
 3273                        .to_file_path()
 3274                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3275
 3276                    if let Some(parent_path) = abs_path.parent() {
 3277                        fs.create_dir(parent_path).await?;
 3278                    }
 3279                    if abs_path.ends_with("/") {
 3280                        fs.create_dir(&abs_path).await?;
 3281                    } else {
 3282                        fs.create_file(
 3283                            &abs_path,
 3284                            op.options
 3285                                .map(|options| fs::CreateOptions {
 3286                                    overwrite: options.overwrite.unwrap_or(false),
 3287                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3288                                })
 3289                                .unwrap_or_default(),
 3290                        )
 3291                        .await?;
 3292                    }
 3293                }
 3294
 3295                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3296                    let source_abs_path = op
 3297                        .old_uri
 3298                        .to_file_path()
 3299                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3300                    let target_abs_path = op
 3301                        .new_uri
 3302                        .to_file_path()
 3303                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3304
 3305                    let options = fs::RenameOptions {
 3306                        overwrite: op
 3307                            .options
 3308                            .as_ref()
 3309                            .and_then(|options| options.overwrite)
 3310                            .unwrap_or(false),
 3311                        ignore_if_exists: op
 3312                            .options
 3313                            .as_ref()
 3314                            .and_then(|options| options.ignore_if_exists)
 3315                            .unwrap_or(false),
 3316                        create_parents: true,
 3317                    };
 3318
 3319                    fs.rename(&source_abs_path, &target_abs_path, options)
 3320                        .await?;
 3321                }
 3322
 3323                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3324                    let abs_path = op
 3325                        .uri
 3326                        .to_file_path()
 3327                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3328                    let options = op
 3329                        .options
 3330                        .map(|options| fs::RemoveOptions {
 3331                            recursive: options.recursive.unwrap_or(false),
 3332                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3333                        })
 3334                        .unwrap_or_default();
 3335                    if abs_path.ends_with("/") {
 3336                        fs.remove_dir(&abs_path, options).await?;
 3337                    } else {
 3338                        fs.remove_file(&abs_path, options).await?;
 3339                    }
 3340                }
 3341
 3342                lsp::DocumentChangeOperation::Edit(op) => {
 3343                    let buffer_to_edit = this
 3344                        .update(cx, |this, cx| {
 3345                            this.open_local_buffer_via_lsp(
 3346                                op.text_document.uri.clone(),
 3347                                language_server.server_id(),
 3348                                cx,
 3349                            )
 3350                        })
 3351                        .await?;
 3352
 3353                    let edits = this
 3354                        .update(cx, |this, cx| {
 3355                            let path = buffer_to_edit.read(cx).project_path(cx);
 3356                            let active_entry = this.active_entry;
 3357                            let is_active_entry = path.is_some_and(|project_path| {
 3358                                this.worktree_store
 3359                                    .read(cx)
 3360                                    .entry_for_path(&project_path, cx)
 3361                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3362                            });
 3363                            let local = this.as_local_mut().unwrap();
 3364
 3365                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3366                            for edit in op.edits {
 3367                                match edit {
 3368                                    Edit::Plain(edit) => {
 3369                                        if !edits.contains(&edit) {
 3370                                            edits.push(edit)
 3371                                        }
 3372                                    }
 3373                                    Edit::Annotated(edit) => {
 3374                                        if !edits.contains(&edit.text_edit) {
 3375                                            edits.push(edit.text_edit)
 3376                                        }
 3377                                    }
 3378                                    Edit::Snippet(edit) => {
 3379                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3380                                        else {
 3381                                            continue;
 3382                                        };
 3383
 3384                                        if is_active_entry {
 3385                                            snippet_edits.push((edit.range, snippet));
 3386                                        } else {
 3387                                            // Since this buffer is not focused, apply a normal edit.
 3388                                            let new_edit = TextEdit {
 3389                                                range: edit.range,
 3390                                                new_text: snippet.text,
 3391                                            };
 3392                                            if !edits.contains(&new_edit) {
 3393                                                edits.push(new_edit);
 3394                                            }
 3395                                        }
 3396                                    }
 3397                                }
 3398                            }
 3399                            if !snippet_edits.is_empty() {
 3400                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3401                                let version = if let Some(buffer_version) = op.text_document.version
 3402                                {
 3403                                    local
 3404                                        .buffer_snapshot_for_lsp_version(
 3405                                            &buffer_to_edit,
 3406                                            language_server.server_id(),
 3407                                            Some(buffer_version),
 3408                                            cx,
 3409                                        )
 3410                                        .ok()
 3411                                        .map(|snapshot| snapshot.version)
 3412                                } else {
 3413                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3414                                };
 3415
 3416                                let most_recent_edit =
 3417                                    version.and_then(|version| version.most_recent());
 3418                                // Check if the edit that triggered that edit has been made by this participant.
 3419
 3420                                if let Some(most_recent_edit) = most_recent_edit {
 3421                                    cx.emit(LspStoreEvent::SnippetEdit {
 3422                                        buffer_id,
 3423                                        edits: snippet_edits,
 3424                                        most_recent_edit,
 3425                                    });
 3426                                }
 3427                            }
 3428
 3429                            local.edits_from_lsp(
 3430                                &buffer_to_edit,
 3431                                edits,
 3432                                language_server.server_id(),
 3433                                op.text_document.version,
 3434                                cx,
 3435                            )
 3436                        })
 3437                        .await?;
 3438
 3439                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3440                        buffer.finalize_last_transaction();
 3441                        buffer.start_transaction();
 3442                        for (range, text) in edits {
 3443                            buffer.edit([(range, text)], None, cx);
 3444                        }
 3445
 3446                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3447                            if push_to_history {
 3448                                buffer.finalize_last_transaction();
 3449                                buffer.get_transaction(transaction_id).cloned()
 3450                            } else {
 3451                                buffer.forget_transaction(transaction_id)
 3452                            }
 3453                        })
 3454                    });
 3455                    if let Some(transaction) = transaction {
 3456                        project_transaction.0.insert(buffer_to_edit, transaction);
 3457                    }
 3458                }
 3459            }
 3460        }
 3461
 3462        Ok(project_transaction)
 3463    }
 3464
 3465    async fn on_lsp_workspace_edit(
 3466        this: WeakEntity<LspStore>,
 3467        params: lsp::ApplyWorkspaceEditParams,
 3468        server_id: LanguageServerId,
 3469        cx: &mut AsyncApp,
 3470    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3471        let this = this.upgrade().context("project project closed")?;
 3472        let language_server = this
 3473            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3474            .context("language server not found")?;
 3475        let transaction = Self::deserialize_workspace_edit(
 3476            this.clone(),
 3477            params.edit,
 3478            true,
 3479            language_server.clone(),
 3480            cx,
 3481        )
 3482        .await
 3483        .log_err();
 3484        this.update(cx, |this, cx| {
 3485            if let Some(transaction) = transaction {
 3486                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3487
 3488                this.as_local_mut()
 3489                    .unwrap()
 3490                    .last_workspace_edits_by_language_server
 3491                    .insert(server_id, transaction);
 3492            }
 3493        });
 3494        Ok(lsp::ApplyWorkspaceEditResponse {
 3495            applied: true,
 3496            failed_change: None,
 3497            failure_reason: None,
 3498        })
 3499    }
 3500
 3501    fn remove_worktree(
 3502        &mut self,
 3503        id_to_remove: WorktreeId,
 3504        cx: &mut Context<LspStore>,
 3505    ) -> Vec<LanguageServerId> {
 3506        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3507        self.diagnostics.remove(&id_to_remove);
 3508        self.prettier_store.update(cx, |prettier_store, cx| {
 3509            prettier_store.remove_worktree(id_to_remove, cx);
 3510        });
 3511
 3512        let mut servers_to_remove = BTreeSet::default();
 3513        let mut servers_to_preserve = HashSet::default();
 3514        for (seed, state) in &self.language_server_ids {
 3515            if seed.worktree_id == id_to_remove {
 3516                servers_to_remove.insert(state.id);
 3517            } else {
 3518                servers_to_preserve.insert(state.id);
 3519            }
 3520        }
 3521        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3522        self.language_server_ids
 3523            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3524        for server_id_to_remove in &servers_to_remove {
 3525            self.language_server_watched_paths
 3526                .remove(server_id_to_remove);
 3527            self.language_server_paths_watched_for_rename
 3528                .remove(server_id_to_remove);
 3529            self.last_workspace_edits_by_language_server
 3530                .remove(server_id_to_remove);
 3531            self.language_servers.remove(server_id_to_remove);
 3532            self.buffer_pull_diagnostics_result_ids
 3533                .remove(server_id_to_remove);
 3534            self.workspace_pull_diagnostics_result_ids
 3535                .remove(server_id_to_remove);
 3536            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3537                buffer_servers.remove(server_id_to_remove);
 3538            }
 3539            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3540        }
 3541        servers_to_remove.into_iter().collect()
 3542    }
 3543
 3544    fn rebuild_watched_paths_inner<'a>(
 3545        &'a self,
 3546        language_server_id: LanguageServerId,
 3547        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3548        cx: &mut Context<LspStore>,
 3549    ) -> LanguageServerWatchedPathsBuilder {
 3550        let worktrees = self
 3551            .worktree_store
 3552            .read(cx)
 3553            .worktrees()
 3554            .filter_map(|worktree| {
 3555                self.language_servers_for_worktree(worktree.read(cx).id())
 3556                    .find(|server| server.server_id() == language_server_id)
 3557                    .map(|_| worktree)
 3558            })
 3559            .collect::<Vec<_>>();
 3560
 3561        let mut worktree_globs = HashMap::default();
 3562        let mut abs_globs = HashMap::default();
 3563        log::trace!(
 3564            "Processing new watcher paths for language server with id {}",
 3565            language_server_id
 3566        );
 3567
 3568        for watcher in watchers {
 3569            if let Some((worktree, literal_prefix, pattern)) =
 3570                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3571            {
 3572                worktree.update(cx, |worktree, _| {
 3573                    if let Some((tree, glob)) =
 3574                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3575                    {
 3576                        tree.add_path_prefix_to_scan(literal_prefix);
 3577                        worktree_globs
 3578                            .entry(tree.id())
 3579                            .or_insert_with(GlobSetBuilder::new)
 3580                            .add(glob);
 3581                    }
 3582                });
 3583            } else {
 3584                let (path, pattern) = match &watcher.glob_pattern {
 3585                    lsp::GlobPattern::String(s) => {
 3586                        let watcher_path = SanitizedPath::new(s);
 3587                        let path = glob_literal_prefix(watcher_path.as_path());
 3588                        let pattern = watcher_path
 3589                            .as_path()
 3590                            .strip_prefix(&path)
 3591                            .map(|p| p.to_string_lossy().into_owned())
 3592                            .unwrap_or_else(|e| {
 3593                                debug_panic!(
 3594                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3595                                    s,
 3596                                    path.display(),
 3597                                    e
 3598                                );
 3599                                watcher_path.as_path().to_string_lossy().into_owned()
 3600                            });
 3601                        (path, pattern)
 3602                    }
 3603                    lsp::GlobPattern::Relative(rp) => {
 3604                        let Ok(mut base_uri) = match &rp.base_uri {
 3605                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3606                            lsp::OneOf::Right(base_uri) => base_uri,
 3607                        }
 3608                        .to_file_path() else {
 3609                            continue;
 3610                        };
 3611
 3612                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3613                        let pattern = Path::new(&rp.pattern)
 3614                            .strip_prefix(&path)
 3615                            .map(|p| p.to_string_lossy().into_owned())
 3616                            .unwrap_or_else(|e| {
 3617                                debug_panic!(
 3618                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3619                                    rp.pattern,
 3620                                    path.display(),
 3621                                    e
 3622                                );
 3623                                rp.pattern.clone()
 3624                            });
 3625                        base_uri.push(path);
 3626                        (base_uri, pattern)
 3627                    }
 3628                };
 3629
 3630                if let Some(glob) = Glob::new(&pattern).log_err() {
 3631                    if !path
 3632                        .components()
 3633                        .any(|c| matches!(c, path::Component::Normal(_)))
 3634                    {
 3635                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3636                        // rather than adding a new watcher for `/`.
 3637                        for worktree in &worktrees {
 3638                            worktree_globs
 3639                                .entry(worktree.read(cx).id())
 3640                                .or_insert_with(GlobSetBuilder::new)
 3641                                .add(glob.clone());
 3642                        }
 3643                    } else {
 3644                        abs_globs
 3645                            .entry(path.into())
 3646                            .or_insert_with(GlobSetBuilder::new)
 3647                            .add(glob);
 3648                    }
 3649                }
 3650            }
 3651        }
 3652
 3653        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3654        for (worktree_id, builder) in worktree_globs {
 3655            if let Ok(globset) = builder.build() {
 3656                watch_builder.watch_worktree(worktree_id, globset);
 3657            }
 3658        }
 3659        for (abs_path, builder) in abs_globs {
 3660            if let Ok(globset) = builder.build() {
 3661                watch_builder.watch_abs_path(abs_path, globset);
 3662            }
 3663        }
 3664        watch_builder
 3665    }
 3666
 3667    fn worktree_and_path_for_file_watcher(
 3668        worktrees: &[Entity<Worktree>],
 3669        watcher: &FileSystemWatcher,
 3670        cx: &App,
 3671    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3672        worktrees.iter().find_map(|worktree| {
 3673            let tree = worktree.read(cx);
 3674            let worktree_root_path = tree.abs_path();
 3675            let path_style = tree.path_style();
 3676            match &watcher.glob_pattern {
 3677                lsp::GlobPattern::String(s) => {
 3678                    let watcher_path = SanitizedPath::new(s);
 3679                    let relative = watcher_path
 3680                        .as_path()
 3681                        .strip_prefix(&worktree_root_path)
 3682                        .ok()?;
 3683                    let literal_prefix = glob_literal_prefix(relative);
 3684                    Some((
 3685                        worktree.clone(),
 3686                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3687                        relative.to_string_lossy().into_owned(),
 3688                    ))
 3689                }
 3690                lsp::GlobPattern::Relative(rp) => {
 3691                    let base_uri = match &rp.base_uri {
 3692                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3693                        lsp::OneOf::Right(base_uri) => base_uri,
 3694                    }
 3695                    .to_file_path()
 3696                    .ok()?;
 3697                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3698                    let mut literal_prefix = relative.to_owned();
 3699                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3700                    Some((
 3701                        worktree.clone(),
 3702                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3703                        rp.pattern.clone(),
 3704                    ))
 3705                }
 3706            }
 3707        })
 3708    }
 3709
 3710    fn rebuild_watched_paths(
 3711        &mut self,
 3712        language_server_id: LanguageServerId,
 3713        cx: &mut Context<LspStore>,
 3714    ) {
 3715        let Some(registrations) = self
 3716            .language_server_dynamic_registrations
 3717            .get(&language_server_id)
 3718        else {
 3719            return;
 3720        };
 3721
 3722        let watch_builder = self.rebuild_watched_paths_inner(
 3723            language_server_id,
 3724            registrations.did_change_watched_files.values().flatten(),
 3725            cx,
 3726        );
 3727        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3728        self.language_server_watched_paths
 3729            .insert(language_server_id, watcher);
 3730
 3731        cx.notify();
 3732    }
 3733
 3734    fn on_lsp_did_change_watched_files(
 3735        &mut self,
 3736        language_server_id: LanguageServerId,
 3737        registration_id: &str,
 3738        params: DidChangeWatchedFilesRegistrationOptions,
 3739        cx: &mut Context<LspStore>,
 3740    ) {
 3741        let registrations = self
 3742            .language_server_dynamic_registrations
 3743            .entry(language_server_id)
 3744            .or_default();
 3745
 3746        registrations
 3747            .did_change_watched_files
 3748            .insert(registration_id.to_string(), params.watchers);
 3749
 3750        self.rebuild_watched_paths(language_server_id, cx);
 3751    }
 3752
 3753    fn on_lsp_unregister_did_change_watched_files(
 3754        &mut self,
 3755        language_server_id: LanguageServerId,
 3756        registration_id: &str,
 3757        cx: &mut Context<LspStore>,
 3758    ) {
 3759        let registrations = self
 3760            .language_server_dynamic_registrations
 3761            .entry(language_server_id)
 3762            .or_default();
 3763
 3764        if registrations
 3765            .did_change_watched_files
 3766            .remove(registration_id)
 3767            .is_some()
 3768        {
 3769            log::info!(
 3770                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3771                language_server_id,
 3772                registration_id
 3773            );
 3774        } else {
 3775            log::warn!(
 3776                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3777                language_server_id,
 3778                registration_id
 3779            );
 3780        }
 3781
 3782        self.rebuild_watched_paths(language_server_id, cx);
 3783    }
 3784
 3785    async fn initialization_options_for_adapter(
 3786        adapter: Arc<dyn LspAdapter>,
 3787        delegate: &Arc<dyn LspAdapterDelegate>,
 3788        cx: &mut AsyncApp,
 3789    ) -> Result<Option<serde_json::Value>> {
 3790        let Some(mut initialization_config) =
 3791            adapter.clone().initialization_options(delegate, cx).await?
 3792        else {
 3793            return Ok(None);
 3794        };
 3795
 3796        for other_adapter in delegate.registered_lsp_adapters() {
 3797            if other_adapter.name() == adapter.name() {
 3798                continue;
 3799            }
 3800            if let Ok(Some(target_config)) = other_adapter
 3801                .clone()
 3802                .additional_initialization_options(adapter.name(), delegate)
 3803                .await
 3804            {
 3805                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3806            }
 3807        }
 3808
 3809        Ok(Some(initialization_config))
 3810    }
 3811
 3812    async fn workspace_configuration_for_adapter(
 3813        adapter: Arc<dyn LspAdapter>,
 3814        delegate: &Arc<dyn LspAdapterDelegate>,
 3815        toolchain: Option<Toolchain>,
 3816        requested_uri: Option<Uri>,
 3817        cx: &mut AsyncApp,
 3818    ) -> Result<serde_json::Value> {
 3819        let mut workspace_config = adapter
 3820            .clone()
 3821            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3822            .await?;
 3823
 3824        for other_adapter in delegate.registered_lsp_adapters() {
 3825            if other_adapter.name() == adapter.name() {
 3826                continue;
 3827            }
 3828            if let Ok(Some(target_config)) = other_adapter
 3829                .clone()
 3830                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3831                .await
 3832            {
 3833                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3834            }
 3835        }
 3836
 3837        Ok(workspace_config)
 3838    }
 3839
 3840    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3841        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3842            Some(server.clone())
 3843        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3844            Some(Arc::clone(server))
 3845        } else {
 3846            None
 3847        }
 3848    }
 3849}
 3850
 3851fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3852    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3853        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3854            language_server_id: server.server_id(),
 3855            name: Some(server.name()),
 3856            message: proto::update_language_server::Variant::MetadataUpdated(
 3857                proto::ServerMetadataUpdated {
 3858                    capabilities: Some(capabilities),
 3859                    binary: Some(proto::LanguageServerBinaryInfo {
 3860                        path: server.binary().path.to_string_lossy().into_owned(),
 3861                        arguments: server
 3862                            .binary()
 3863                            .arguments
 3864                            .iter()
 3865                            .map(|arg| arg.to_string_lossy().into_owned())
 3866                            .collect(),
 3867                    }),
 3868                    configuration: serde_json::to_string(server.configuration()).ok(),
 3869                    workspace_folders: server
 3870                        .workspace_folders()
 3871                        .iter()
 3872                        .map(|uri| uri.to_string())
 3873                        .collect(),
 3874                },
 3875            ),
 3876        });
 3877    }
 3878}
 3879
 3880#[derive(Debug)]
 3881pub struct FormattableBuffer {
 3882    handle: Entity<Buffer>,
 3883    abs_path: Option<PathBuf>,
 3884    env: Option<HashMap<String, String>>,
 3885    ranges: Option<Vec<Range<Anchor>>>,
 3886}
 3887
 3888pub struct RemoteLspStore {
 3889    upstream_client: Option<AnyProtoClient>,
 3890    upstream_project_id: u64,
 3891}
 3892
 3893pub(crate) enum LspStoreMode {
 3894    Local(LocalLspStore),   // ssh host and collab host
 3895    Remote(RemoteLspStore), // collab guest
 3896}
 3897
 3898impl LspStoreMode {
 3899    fn is_local(&self) -> bool {
 3900        matches!(self, LspStoreMode::Local(_))
 3901    }
 3902}
 3903
 3904pub struct LspStore {
 3905    mode: LspStoreMode,
 3906    last_formatting_failure: Option<String>,
 3907    downstream_client: Option<(AnyProtoClient, u64)>,
 3908    nonce: u128,
 3909    buffer_store: Entity<BufferStore>,
 3910    worktree_store: Entity<WorktreeStore>,
 3911    pub languages: Arc<LanguageRegistry>,
 3912    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3913    active_entry: Option<ProjectEntryId>,
 3914    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3915    _maintain_buffer_languages: Task<()>,
 3916    diagnostic_summaries:
 3917        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3918    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3919    semantic_token_config: SemanticTokenConfig,
 3920    lsp_data: HashMap<BufferId, BufferLspData>,
 3921    buffer_reload_tasks: HashMap<BufferId, Task<anyhow::Result<()>>>,
 3922    next_hint_id: Arc<AtomicUsize>,
 3923}
 3924
 3925#[derive(Debug)]
 3926pub struct BufferLspData {
 3927    buffer_version: Global,
 3928    document_colors: Option<DocumentColorData>,
 3929    code_lens: Option<CodeLensData>,
 3930    semantic_tokens: Option<SemanticTokensData>,
 3931    folding_ranges: Option<FoldingRangeData>,
 3932    document_symbols: Option<DocumentSymbolsData>,
 3933    inlay_hints: BufferInlayHints,
 3934    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3935    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3936}
 3937
 3938#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3939struct LspKey {
 3940    request_type: TypeId,
 3941    server_queried: Option<LanguageServerId>,
 3942}
 3943
 3944impl BufferLspData {
 3945    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3946        Self {
 3947            buffer_version: buffer.read(cx).version(),
 3948            document_colors: None,
 3949            code_lens: None,
 3950            semantic_tokens: None,
 3951            folding_ranges: None,
 3952            document_symbols: None,
 3953            inlay_hints: BufferInlayHints::new(buffer, cx),
 3954            lsp_requests: HashMap::default(),
 3955            chunk_lsp_requests: HashMap::default(),
 3956        }
 3957    }
 3958
 3959    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3960        if let Some(document_colors) = &mut self.document_colors {
 3961            document_colors.remove_server_data(for_server);
 3962        }
 3963
 3964        if let Some(code_lens) = &mut self.code_lens {
 3965            code_lens.remove_server_data(for_server);
 3966        }
 3967
 3968        self.inlay_hints.remove_server_data(for_server);
 3969
 3970        if let Some(semantic_tokens) = &mut self.semantic_tokens {
 3971            semantic_tokens.remove_server_data(for_server);
 3972        }
 3973
 3974        if let Some(folding_ranges) = &mut self.folding_ranges {
 3975            folding_ranges.ranges.remove(&for_server);
 3976        }
 3977
 3978        if let Some(document_symbols) = &mut self.document_symbols {
 3979            document_symbols.remove_server_data(for_server);
 3980        }
 3981    }
 3982
 3983    #[cfg(any(test, feature = "test-support"))]
 3984    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3985        &self.inlay_hints
 3986    }
 3987}
 3988
 3989#[derive(Debug)]
 3990pub enum LspStoreEvent {
 3991    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3992    LanguageServerRemoved(LanguageServerId),
 3993    LanguageServerUpdate {
 3994        language_server_id: LanguageServerId,
 3995        name: Option<LanguageServerName>,
 3996        message: proto::update_language_server::Variant,
 3997    },
 3998    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3999    LanguageServerPrompt(LanguageServerPromptRequest),
 4000    LanguageDetected {
 4001        buffer: Entity<Buffer>,
 4002        new_language: Option<Arc<Language>>,
 4003    },
 4004    Notification(String),
 4005    RefreshInlayHints {
 4006        server_id: LanguageServerId,
 4007        request_id: Option<usize>,
 4008    },
 4009    RefreshSemanticTokens {
 4010        server_id: LanguageServerId,
 4011        request_id: Option<usize>,
 4012    },
 4013    RefreshCodeLens,
 4014    DiagnosticsUpdated {
 4015        server_id: LanguageServerId,
 4016        paths: Vec<ProjectPath>,
 4017    },
 4018    DiskBasedDiagnosticsStarted {
 4019        language_server_id: LanguageServerId,
 4020    },
 4021    DiskBasedDiagnosticsFinished {
 4022        language_server_id: LanguageServerId,
 4023    },
 4024    SnippetEdit {
 4025        buffer_id: BufferId,
 4026        edits: Vec<(lsp::Range, Snippet)>,
 4027        most_recent_edit: clock::Lamport,
 4028    },
 4029    WorkspaceEditApplied(ProjectTransaction),
 4030}
 4031
 4032#[derive(Clone, Debug, Serialize)]
 4033pub struct LanguageServerStatus {
 4034    pub name: LanguageServerName,
 4035    pub server_version: Option<SharedString>,
 4036    pub server_readable_version: Option<SharedString>,
 4037    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 4038    pub has_pending_diagnostic_updates: bool,
 4039    pub progress_tokens: HashSet<ProgressToken>,
 4040    pub worktree: Option<WorktreeId>,
 4041    pub binary: Option<LanguageServerBinary>,
 4042    pub configuration: Option<Value>,
 4043    pub workspace_folders: BTreeSet<Uri>,
 4044    pub process_id: Option<u32>,
 4045}
 4046
 4047#[derive(Clone, Debug)]
 4048struct CoreSymbol {
 4049    pub language_server_name: LanguageServerName,
 4050    pub source_worktree_id: WorktreeId,
 4051    pub source_language_server_id: LanguageServerId,
 4052    pub path: SymbolLocation,
 4053    pub name: String,
 4054    pub kind: lsp::SymbolKind,
 4055    pub range: Range<Unclipped<PointUtf16>>,
 4056    pub container_name: Option<String>,
 4057}
 4058
 4059#[derive(Clone, Debug, PartialEq, Eq)]
 4060pub enum SymbolLocation {
 4061    InProject(ProjectPath),
 4062    OutsideProject {
 4063        abs_path: Arc<Path>,
 4064        signature: [u8; 32],
 4065    },
 4066}
 4067
 4068impl SymbolLocation {
 4069    fn file_name(&self) -> Option<&str> {
 4070        match self {
 4071            Self::InProject(path) => path.path.file_name(),
 4072            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 4073        }
 4074    }
 4075}
 4076
 4077impl LspStore {
 4078    pub fn init(client: &AnyProtoClient) {
 4079        client.add_entity_request_handler(Self::handle_lsp_query);
 4080        client.add_entity_message_handler(Self::handle_lsp_query_response);
 4081        client.add_entity_request_handler(Self::handle_restart_language_servers);
 4082        client.add_entity_request_handler(Self::handle_stop_language_servers);
 4083        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 4084        client.add_entity_message_handler(Self::handle_start_language_server);
 4085        client.add_entity_message_handler(Self::handle_update_language_server);
 4086        client.add_entity_message_handler(Self::handle_language_server_log);
 4087        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 4088        client.add_entity_request_handler(Self::handle_format_buffers);
 4089        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 4090        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 4091        client.add_entity_request_handler(Self::handle_apply_code_action);
 4092        client.add_entity_request_handler(Self::handle_get_project_symbols);
 4093        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 4094        client.add_entity_request_handler(Self::handle_get_color_presentation);
 4095        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 4096        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 4097        client.add_entity_request_handler(Self::handle_refresh_semantic_tokens);
 4098        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 4099        client.add_entity_request_handler(Self::handle_on_type_formatting);
 4100        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 4101        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 4102        client.add_entity_request_handler(Self::handle_rename_project_entry);
 4103        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 4104        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 4105        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 4106        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 4107        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 4108        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 4109        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 4110
 4111        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 4112        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 4113        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 4114        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 4115        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 4116        client.add_entity_request_handler(
 4117            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 4118        );
 4119        client.add_entity_request_handler(
 4120            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 4121        );
 4122        client.add_entity_request_handler(
 4123            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 4124        );
 4125    }
 4126
 4127    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 4128        match &self.mode {
 4129            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 4130            _ => None,
 4131        }
 4132    }
 4133
 4134    pub fn as_local(&self) -> Option<&LocalLspStore> {
 4135        match &self.mode {
 4136            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4137            _ => None,
 4138        }
 4139    }
 4140
 4141    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4142        match &mut self.mode {
 4143            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4144            _ => None,
 4145        }
 4146    }
 4147
 4148    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4149        match &self.mode {
 4150            LspStoreMode::Remote(RemoteLspStore {
 4151                upstream_client: Some(upstream_client),
 4152                upstream_project_id,
 4153                ..
 4154            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4155
 4156            LspStoreMode::Remote(RemoteLspStore {
 4157                upstream_client: None,
 4158                ..
 4159            }) => None,
 4160            LspStoreMode::Local(_) => None,
 4161        }
 4162    }
 4163
 4164    pub fn new_local(
 4165        buffer_store: Entity<BufferStore>,
 4166        worktree_store: Entity<WorktreeStore>,
 4167        prettier_store: Entity<PrettierStore>,
 4168        toolchain_store: Entity<LocalToolchainStore>,
 4169        environment: Entity<ProjectEnvironment>,
 4170        manifest_tree: Entity<ManifestTree>,
 4171        languages: Arc<LanguageRegistry>,
 4172        http_client: Arc<dyn HttpClient>,
 4173        fs: Arc<dyn Fs>,
 4174        cx: &mut Context<Self>,
 4175    ) -> Self {
 4176        let yarn = YarnPathStore::new(fs.clone(), cx);
 4177        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4178            .detach();
 4179        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4180            .detach();
 4181        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4182            .detach();
 4183        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4184            .detach();
 4185        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4186            .detach();
 4187        subscribe_to_binary_statuses(&languages, cx).detach();
 4188
 4189        let _maintain_workspace_config = {
 4190            let (sender, receiver) = watch::channel();
 4191            (Self::maintain_workspace_config(receiver, cx), sender)
 4192        };
 4193
 4194        Self {
 4195            mode: LspStoreMode::Local(LocalLspStore {
 4196                weak: cx.weak_entity(),
 4197                worktree_store: worktree_store.clone(),
 4198
 4199                supplementary_language_servers: Default::default(),
 4200                languages: languages.clone(),
 4201                language_server_ids: Default::default(),
 4202                language_servers: Default::default(),
 4203                last_workspace_edits_by_language_server: Default::default(),
 4204                language_server_watched_paths: Default::default(),
 4205                language_server_paths_watched_for_rename: Default::default(),
 4206                language_server_dynamic_registrations: Default::default(),
 4207                buffers_being_formatted: Default::default(),
 4208                buffers_to_refresh_hash_set: HashSet::default(),
 4209                buffers_to_refresh_queue: VecDeque::new(),
 4210                _background_diagnostics_worker: Task::ready(()).shared(),
 4211                buffer_snapshots: Default::default(),
 4212                prettier_store,
 4213                environment,
 4214                http_client,
 4215                fs,
 4216                yarn,
 4217                next_diagnostic_group_id: Default::default(),
 4218                diagnostics: Default::default(),
 4219                _subscription: cx.on_app_quit(|this, _| {
 4220                    this.as_local_mut()
 4221                        .unwrap()
 4222                        .shutdown_language_servers_on_quit()
 4223                }),
 4224                lsp_tree: LanguageServerTree::new(
 4225                    manifest_tree,
 4226                    languages.clone(),
 4227                    toolchain_store.clone(),
 4228                ),
 4229                toolchain_store,
 4230                registered_buffers: HashMap::default(),
 4231                buffers_opened_in_servers: HashMap::default(),
 4232                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4233                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4234                restricted_worktrees_tasks: HashMap::default(),
 4235                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4236                    .manifest_file_names(),
 4237            }),
 4238            last_formatting_failure: None,
 4239            downstream_client: None,
 4240            buffer_store,
 4241            worktree_store,
 4242            languages: languages.clone(),
 4243            language_server_statuses: Default::default(),
 4244            nonce: StdRng::from_os_rng().random(),
 4245            diagnostic_summaries: HashMap::default(),
 4246            lsp_server_capabilities: HashMap::default(),
 4247            semantic_token_config: SemanticTokenConfig::new(cx),
 4248            lsp_data: HashMap::default(),
 4249            buffer_reload_tasks: HashMap::default(),
 4250            next_hint_id: Arc::default(),
 4251            active_entry: None,
 4252            _maintain_workspace_config,
 4253            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4254        }
 4255    }
 4256
 4257    fn send_lsp_proto_request<R: LspCommand>(
 4258        &self,
 4259        buffer: Entity<Buffer>,
 4260        client: AnyProtoClient,
 4261        upstream_project_id: u64,
 4262        request: R,
 4263        cx: &mut Context<LspStore>,
 4264    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4265        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4266            return Task::ready(Ok(R::Response::default()));
 4267        }
 4268        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4269        cx.spawn(async move |this, cx| {
 4270            let response = client.request(message).await?;
 4271            let this = this.upgrade().context("project dropped")?;
 4272            request
 4273                .response_from_proto(response, this, buffer, cx.clone())
 4274                .await
 4275        })
 4276    }
 4277
 4278    pub(super) fn new_remote(
 4279        buffer_store: Entity<BufferStore>,
 4280        worktree_store: Entity<WorktreeStore>,
 4281        languages: Arc<LanguageRegistry>,
 4282        upstream_client: AnyProtoClient,
 4283        project_id: u64,
 4284        cx: &mut Context<Self>,
 4285    ) -> Self {
 4286        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4287            .detach();
 4288        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4289            .detach();
 4290        subscribe_to_binary_statuses(&languages, cx).detach();
 4291        let _maintain_workspace_config = {
 4292            let (sender, receiver) = watch::channel();
 4293            (Self::maintain_workspace_config(receiver, cx), sender)
 4294        };
 4295        Self {
 4296            mode: LspStoreMode::Remote(RemoteLspStore {
 4297                upstream_client: Some(upstream_client),
 4298                upstream_project_id: project_id,
 4299            }),
 4300            downstream_client: None,
 4301            last_formatting_failure: None,
 4302            buffer_store,
 4303            worktree_store,
 4304            languages: languages.clone(),
 4305            language_server_statuses: Default::default(),
 4306            nonce: StdRng::from_os_rng().random(),
 4307            diagnostic_summaries: HashMap::default(),
 4308            lsp_server_capabilities: HashMap::default(),
 4309            semantic_token_config: SemanticTokenConfig::new(cx),
 4310            next_hint_id: Arc::default(),
 4311            lsp_data: HashMap::default(),
 4312            buffer_reload_tasks: HashMap::default(),
 4313            active_entry: None,
 4314
 4315            _maintain_workspace_config,
 4316            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4317        }
 4318    }
 4319
 4320    fn on_buffer_store_event(
 4321        &mut self,
 4322        _: Entity<BufferStore>,
 4323        event: &BufferStoreEvent,
 4324        cx: &mut Context<Self>,
 4325    ) {
 4326        match event {
 4327            BufferStoreEvent::BufferAdded(buffer) => {
 4328                self.on_buffer_added(buffer, cx).log_err();
 4329            }
 4330            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4331                let buffer_id = buffer.read(cx).remote_id();
 4332                if let Some(local) = self.as_local_mut()
 4333                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4334                {
 4335                    local.reset_buffer(buffer, old_file, cx);
 4336
 4337                    if local.registered_buffers.contains_key(&buffer_id) {
 4338                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4339                    }
 4340                }
 4341
 4342                self.detect_language_for_buffer(buffer, cx);
 4343                if let Some(local) = self.as_local_mut() {
 4344                    local.initialize_buffer(buffer, cx);
 4345                    if local.registered_buffers.contains_key(&buffer_id) {
 4346                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4347                    }
 4348                }
 4349            }
 4350            _ => {}
 4351        }
 4352    }
 4353
 4354    fn on_worktree_store_event(
 4355        &mut self,
 4356        _: Entity<WorktreeStore>,
 4357        event: &WorktreeStoreEvent,
 4358        cx: &mut Context<Self>,
 4359    ) {
 4360        match event {
 4361            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4362                if !worktree.read(cx).is_local() {
 4363                    return;
 4364                }
 4365                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4366                    worktree::Event::UpdatedEntries(changes) => {
 4367                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4368                    }
 4369                    worktree::Event::UpdatedGitRepositories(_)
 4370                    | worktree::Event::DeletedEntry(_) => {}
 4371                })
 4372                .detach()
 4373            }
 4374            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4375            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4376                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4377            }
 4378            WorktreeStoreEvent::WorktreeUpdatedEntries(worktree_id, changes) => {
 4379                self.invalidate_diagnostic_summaries_for_removed_entries(*worktree_id, changes, cx);
 4380            }
 4381            WorktreeStoreEvent::WorktreeReleased(..)
 4382            | WorktreeStoreEvent::WorktreeOrderChanged
 4383            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4384            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4385        }
 4386    }
 4387
 4388    fn on_prettier_store_event(
 4389        &mut self,
 4390        _: Entity<PrettierStore>,
 4391        event: &PrettierStoreEvent,
 4392        cx: &mut Context<Self>,
 4393    ) {
 4394        match event {
 4395            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4396                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4397            }
 4398            PrettierStoreEvent::LanguageServerAdded {
 4399                new_server_id,
 4400                name,
 4401                prettier_server,
 4402            } => {
 4403                self.register_supplementary_language_server(
 4404                    *new_server_id,
 4405                    name.clone(),
 4406                    prettier_server.clone(),
 4407                    cx,
 4408                );
 4409            }
 4410        }
 4411    }
 4412
 4413    fn on_toolchain_store_event(
 4414        &mut self,
 4415        _: Entity<LocalToolchainStore>,
 4416        event: &ToolchainStoreEvent,
 4417        _: &mut Context<Self>,
 4418    ) {
 4419        if let ToolchainStoreEvent::ToolchainActivated = event {
 4420            self.request_workspace_config_refresh()
 4421        }
 4422    }
 4423
 4424    fn request_workspace_config_refresh(&mut self) {
 4425        *self._maintain_workspace_config.1.borrow_mut() = ();
 4426    }
 4427
 4428    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4429        self.as_local().map(|local| local.prettier_store.clone())
 4430    }
 4431
 4432    fn on_buffer_event(
 4433        &mut self,
 4434        buffer: Entity<Buffer>,
 4435        event: &language::BufferEvent,
 4436        cx: &mut Context<Self>,
 4437    ) {
 4438        match event {
 4439            language::BufferEvent::Edited { .. } => {
 4440                self.on_buffer_edited(buffer, cx);
 4441            }
 4442
 4443            language::BufferEvent::Saved => {
 4444                self.on_buffer_saved(buffer, cx);
 4445            }
 4446
 4447            language::BufferEvent::Reloaded => {
 4448                self.on_buffer_reloaded(buffer, cx);
 4449            }
 4450
 4451            _ => {}
 4452        }
 4453    }
 4454
 4455    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4456        buffer
 4457            .read(cx)
 4458            .set_language_registry(self.languages.clone());
 4459
 4460        cx.subscribe(buffer, |this, buffer, event, cx| {
 4461            this.on_buffer_event(buffer, event, cx);
 4462        })
 4463        .detach();
 4464
 4465        self.detect_language_for_buffer(buffer, cx);
 4466        if let Some(local) = self.as_local_mut() {
 4467            local.initialize_buffer(buffer, cx);
 4468        }
 4469
 4470        Ok(())
 4471    }
 4472
 4473    pub fn refresh_background_diagnostics_for_buffers(
 4474        &mut self,
 4475        buffers: HashSet<BufferId>,
 4476        cx: &mut Context<Self>,
 4477    ) -> Shared<Task<()>> {
 4478        let Some(local) = self.as_local_mut() else {
 4479            return Task::ready(()).shared();
 4480        };
 4481        for buffer in buffers {
 4482            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4483                local.buffers_to_refresh_queue.push_back(buffer);
 4484                if local.buffers_to_refresh_queue.len() == 1 {
 4485                    local._background_diagnostics_worker =
 4486                        Self::background_diagnostics_worker(cx).shared();
 4487                }
 4488            }
 4489        }
 4490
 4491        local._background_diagnostics_worker.clone()
 4492    }
 4493
 4494    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4495        let buffer_store = self.buffer_store.clone();
 4496        let local = self.as_local_mut()?;
 4497        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4498            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4499            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4500                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4501            }
 4502        }
 4503        None
 4504    }
 4505
 4506    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4507        cx.spawn(async move |this, cx| {
 4508            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4509                task.await.log_err();
 4510            }
 4511        })
 4512    }
 4513
 4514    pub(crate) fn register_buffer_with_language_servers(
 4515        &mut self,
 4516        buffer: &Entity<Buffer>,
 4517        only_register_servers: HashSet<LanguageServerSelector>,
 4518        ignore_refcounts: bool,
 4519        cx: &mut Context<Self>,
 4520    ) -> OpenLspBufferHandle {
 4521        let buffer_id = buffer.read(cx).remote_id();
 4522        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4523        if let Some(local) = self.as_local_mut() {
 4524            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4525            if !ignore_refcounts {
 4526                *refcount += 1;
 4527            }
 4528
 4529            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4530            // 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
 4531            // 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
 4532            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4533            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4534                return handle;
 4535            };
 4536            if !file.is_local() {
 4537                return handle;
 4538            }
 4539
 4540            if ignore_refcounts || *refcount == 1 {
 4541                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4542            }
 4543            if !ignore_refcounts {
 4544                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4545                    let refcount = {
 4546                        let local = lsp_store.as_local_mut().unwrap();
 4547                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4548                            debug_panic!("bad refcounting");
 4549                            return;
 4550                        };
 4551
 4552                        *refcount -= 1;
 4553                        *refcount
 4554                    };
 4555                    if refcount == 0 {
 4556                        lsp_store.lsp_data.remove(&buffer_id);
 4557                        lsp_store.buffer_reload_tasks.remove(&buffer_id);
 4558                        let local = lsp_store.as_local_mut().unwrap();
 4559                        local.registered_buffers.remove(&buffer_id);
 4560
 4561                        local.buffers_opened_in_servers.remove(&buffer_id);
 4562                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4563                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4564
 4565                            let buffer_abs_path = file.abs_path(cx);
 4566                            for (_, buffer_pull_diagnostics_result_ids) in
 4567                                &mut local.buffer_pull_diagnostics_result_ids
 4568                            {
 4569                                buffer_pull_diagnostics_result_ids.retain(
 4570                                    |_, buffer_result_ids| {
 4571                                        buffer_result_ids.remove(&buffer_abs_path);
 4572                                        !buffer_result_ids.is_empty()
 4573                                    },
 4574                                );
 4575                            }
 4576
 4577                            let diagnostic_updates = local
 4578                                .language_servers
 4579                                .keys()
 4580                                .cloned()
 4581                                .map(|server_id| DocumentDiagnosticsUpdate {
 4582                                    diagnostics: DocumentDiagnostics {
 4583                                        document_abs_path: buffer_abs_path.clone(),
 4584                                        version: None,
 4585                                        diagnostics: Vec::new(),
 4586                                    },
 4587                                    result_id: None,
 4588                                    registration_id: None,
 4589                                    server_id,
 4590                                    disk_based_sources: Cow::Borrowed(&[]),
 4591                                })
 4592                                .collect::<Vec<_>>();
 4593
 4594                            lsp_store
 4595                                .merge_diagnostic_entries(
 4596                                    diagnostic_updates,
 4597                                    |_, diagnostic, _| {
 4598                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4599                                    },
 4600                                    cx,
 4601                                )
 4602                                .context("Clearing diagnostics for the closed buffer")
 4603                                .log_err();
 4604                        }
 4605                    }
 4606                })
 4607                .detach();
 4608            }
 4609        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4610            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4611            cx.background_spawn(async move {
 4612                upstream_client
 4613                    .request(proto::RegisterBufferWithLanguageServers {
 4614                        project_id: upstream_project_id,
 4615                        buffer_id,
 4616                        only_servers: only_register_servers
 4617                            .into_iter()
 4618                            .map(|selector| {
 4619                                let selector = match selector {
 4620                                    LanguageServerSelector::Id(language_server_id) => {
 4621                                        proto::language_server_selector::Selector::ServerId(
 4622                                            language_server_id.to_proto(),
 4623                                        )
 4624                                    }
 4625                                    LanguageServerSelector::Name(language_server_name) => {
 4626                                        proto::language_server_selector::Selector::Name(
 4627                                            language_server_name.to_string(),
 4628                                        )
 4629                                    }
 4630                                };
 4631                                proto::LanguageServerSelector {
 4632                                    selector: Some(selector),
 4633                                }
 4634                            })
 4635                            .collect(),
 4636                    })
 4637                    .await
 4638            })
 4639            .detach();
 4640        } else {
 4641            // Our remote connection got closed
 4642        }
 4643        handle
 4644    }
 4645
 4646    fn maintain_buffer_languages(
 4647        languages: Arc<LanguageRegistry>,
 4648        cx: &mut Context<Self>,
 4649    ) -> Task<()> {
 4650        let mut subscription = languages.subscribe();
 4651        let mut prev_reload_count = languages.reload_count();
 4652        cx.spawn(async move |this, cx| {
 4653            while let Some(()) = subscription.next().await {
 4654                if let Some(this) = this.upgrade() {
 4655                    // If the language registry has been reloaded, then remove and
 4656                    // re-assign the languages on all open buffers.
 4657                    let reload_count = languages.reload_count();
 4658                    if reload_count > prev_reload_count {
 4659                        prev_reload_count = reload_count;
 4660                        this.update(cx, |this, cx| {
 4661                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4662                                for buffer in buffer_store.buffers() {
 4663                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4664                                    {
 4665                                        buffer.update(cx, |buffer, cx| {
 4666                                            buffer.set_language_async(None, cx)
 4667                                        });
 4668                                        if let Some(local) = this.as_local_mut() {
 4669                                            local.reset_buffer(&buffer, &f, cx);
 4670
 4671                                            if local
 4672                                                .registered_buffers
 4673                                                .contains_key(&buffer.read(cx).remote_id())
 4674                                                && let Some(file_url) =
 4675                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4676                                            {
 4677                                                local.unregister_buffer_from_language_servers(
 4678                                                    &buffer, &file_url, cx,
 4679                                                );
 4680                                            }
 4681                                        }
 4682                                    }
 4683                                }
 4684                            });
 4685                        });
 4686                    }
 4687
 4688                    this.update(cx, |this, cx| {
 4689                        let mut plain_text_buffers = Vec::new();
 4690                        let mut buffers_with_unknown_injections = Vec::new();
 4691                        for handle in this.buffer_store.read(cx).buffers() {
 4692                            let buffer = handle.read(cx);
 4693                            if buffer.language().is_none()
 4694                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4695                            {
 4696                                plain_text_buffers.push(handle);
 4697                            } else if buffer.contains_unknown_injections() {
 4698                                buffers_with_unknown_injections.push(handle);
 4699                            }
 4700                        }
 4701
 4702                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4703                        // and reused later in the invisible worktrees.
 4704                        plain_text_buffers.sort_by_key(|buffer| {
 4705                            Reverse(
 4706                                File::from_dyn(buffer.read(cx).file())
 4707                                    .map(|file| file.worktree.read(cx).is_visible()),
 4708                            )
 4709                        });
 4710
 4711                        for buffer in plain_text_buffers {
 4712                            this.detect_language_for_buffer(&buffer, cx);
 4713                            if let Some(local) = this.as_local_mut() {
 4714                                local.initialize_buffer(&buffer, cx);
 4715                                if local
 4716                                    .registered_buffers
 4717                                    .contains_key(&buffer.read(cx).remote_id())
 4718                                {
 4719                                    local.register_buffer_with_language_servers(
 4720                                        &buffer,
 4721                                        HashSet::default(),
 4722                                        cx,
 4723                                    );
 4724                                }
 4725                            }
 4726                        }
 4727
 4728                        for buffer in buffers_with_unknown_injections {
 4729                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4730                        }
 4731                    });
 4732                }
 4733            }
 4734        })
 4735    }
 4736
 4737    fn detect_language_for_buffer(
 4738        &mut self,
 4739        buffer_handle: &Entity<Buffer>,
 4740        cx: &mut Context<Self>,
 4741    ) -> Option<language::AvailableLanguage> {
 4742        // If the buffer has a language, set it and start the language server if we haven't already.
 4743        let buffer = buffer_handle.read(cx);
 4744        let file = buffer.file()?;
 4745
 4746        let content = buffer.as_rope();
 4747        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4748        if let Some(available_language) = &available_language {
 4749            if let Some(Ok(Ok(new_language))) = self
 4750                .languages
 4751                .load_language(available_language)
 4752                .now_or_never()
 4753            {
 4754                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4755            }
 4756        } else {
 4757            cx.emit(LspStoreEvent::LanguageDetected {
 4758                buffer: buffer_handle.clone(),
 4759                new_language: None,
 4760            });
 4761        }
 4762
 4763        available_language
 4764    }
 4765
 4766    pub(crate) fn set_language_for_buffer(
 4767        &mut self,
 4768        buffer_entity: &Entity<Buffer>,
 4769        new_language: Arc<Language>,
 4770        cx: &mut Context<Self>,
 4771    ) {
 4772        let buffer = buffer_entity.read(cx);
 4773        let buffer_file = buffer.file().cloned();
 4774        let buffer_id = buffer.remote_id();
 4775        if let Some(local_store) = self.as_local_mut()
 4776            && local_store.registered_buffers.contains_key(&buffer_id)
 4777            && let Some(abs_path) =
 4778                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4779            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4780        {
 4781            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4782        }
 4783        buffer_entity.update(cx, |buffer, cx| {
 4784            if buffer
 4785                .language()
 4786                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4787            {
 4788                buffer.set_language_async(Some(new_language.clone()), cx);
 4789            }
 4790        });
 4791
 4792        let settings =
 4793            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4794        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4795
 4796        let worktree_id = if let Some(file) = buffer_file {
 4797            let worktree = file.worktree.clone();
 4798
 4799            if let Some(local) = self.as_local_mut()
 4800                && local.registered_buffers.contains_key(&buffer_id)
 4801            {
 4802                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4803            }
 4804            Some(worktree.read(cx).id())
 4805        } else {
 4806            None
 4807        };
 4808
 4809        if settings.prettier.allowed
 4810            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4811        {
 4812            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4813            if let Some(prettier_store) = prettier_store {
 4814                prettier_store.update(cx, |prettier_store, cx| {
 4815                    prettier_store.install_default_prettier(
 4816                        worktree_id,
 4817                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4818                        cx,
 4819                    )
 4820                })
 4821            }
 4822        }
 4823
 4824        cx.emit(LspStoreEvent::LanguageDetected {
 4825            buffer: buffer_entity.clone(),
 4826            new_language: Some(new_language),
 4827        })
 4828    }
 4829
 4830    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4831        self.buffer_store.clone()
 4832    }
 4833
 4834    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4835        self.active_entry = active_entry;
 4836    }
 4837
 4838    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4839        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4840            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4841        {
 4842            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4843                summaries
 4844                    .iter()
 4845                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4846            });
 4847            if let Some(summary) = summaries.next() {
 4848                client
 4849                    .send(proto::UpdateDiagnosticSummary {
 4850                        project_id: downstream_project_id,
 4851                        worktree_id: worktree.id().to_proto(),
 4852                        summary: Some(summary),
 4853                        more_summaries: summaries.collect(),
 4854                    })
 4855                    .log_err();
 4856            }
 4857        }
 4858    }
 4859
 4860    fn is_capable_for_proto_request<R>(
 4861        &self,
 4862        buffer: &Entity<Buffer>,
 4863        request: &R,
 4864        cx: &App,
 4865    ) -> bool
 4866    where
 4867        R: LspCommand,
 4868    {
 4869        self.check_if_capable_for_proto_request(
 4870            buffer,
 4871            |capabilities| {
 4872                request.check_capabilities(AdapterServerCapabilities {
 4873                    server_capabilities: capabilities.clone(),
 4874                    code_action_kinds: None,
 4875                })
 4876            },
 4877            cx,
 4878        )
 4879    }
 4880
 4881    fn check_if_capable_for_proto_request<F>(
 4882        &self,
 4883        buffer: &Entity<Buffer>,
 4884        check: F,
 4885        cx: &App,
 4886    ) -> bool
 4887    where
 4888        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4889    {
 4890        let Some(language) = buffer.read(cx).language().cloned() else {
 4891            return false;
 4892        };
 4893        let registered_language_servers = self
 4894            .languages
 4895            .lsp_adapters(&language.name())
 4896            .into_iter()
 4897            .map(|lsp_adapter| lsp_adapter.name())
 4898            .collect::<HashSet<_>>();
 4899        self.language_server_statuses
 4900            .iter()
 4901            .filter_map(|(server_id, server_status)| {
 4902                // Include servers that are either registered for this language OR
 4903                // available to be loaded (for SSH remote mode where adapters like
 4904                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4905                // but only loaded on the server side)
 4906                let is_relevant = registered_language_servers.contains(&server_status.name)
 4907                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4908                is_relevant.then_some(server_id)
 4909            })
 4910            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4911            .any(check)
 4912    }
 4913
 4914    fn all_capable_for_proto_request<F>(
 4915        &self,
 4916        buffer: &Entity<Buffer>,
 4917        mut check: F,
 4918        cx: &App,
 4919    ) -> Vec<(lsp::LanguageServerId, lsp::LanguageServerName)>
 4920    where
 4921        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4922    {
 4923        let Some(language) = buffer.read(cx).language().cloned() else {
 4924            return Vec::default();
 4925        };
 4926        let registered_language_servers = self
 4927            .languages
 4928            .lsp_adapters(&language.name())
 4929            .into_iter()
 4930            .map(|lsp_adapter| lsp_adapter.name())
 4931            .collect::<HashSet<_>>();
 4932        self.language_server_statuses
 4933            .iter()
 4934            .filter_map(|(server_id, server_status)| {
 4935                // Include servers that are either registered for this language OR
 4936                // available to be loaded (for SSH remote mode where adapters like
 4937                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4938                // but only loaded on the server side)
 4939                let is_relevant = registered_language_servers.contains(&server_status.name)
 4940                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4941                is_relevant.then_some((server_id, &server_status.name))
 4942            })
 4943            .filter_map(|(server_id, server_name)| {
 4944                self.lsp_server_capabilities
 4945                    .get(server_id)
 4946                    .map(|c| (server_id, server_name, c))
 4947            })
 4948            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4949            .map(|(server_id, server_name, _)| (*server_id, server_name.clone()))
 4950            .collect()
 4951    }
 4952
 4953    pub fn request_lsp<R>(
 4954        &mut self,
 4955        buffer: Entity<Buffer>,
 4956        server: LanguageServerToQuery,
 4957        request: R,
 4958        cx: &mut Context<Self>,
 4959    ) -> Task<Result<R::Response>>
 4960    where
 4961        R: LspCommand,
 4962        <R::LspRequest as lsp::request::Request>::Result: Send,
 4963        <R::LspRequest as lsp::request::Request>::Params: Send,
 4964    {
 4965        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4966            return self.send_lsp_proto_request(
 4967                buffer,
 4968                upstream_client,
 4969                upstream_project_id,
 4970                request,
 4971                cx,
 4972            );
 4973        }
 4974
 4975        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4976            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4977                local
 4978                    .language_servers_for_buffer(buffer, cx)
 4979                    .find(|(_, server)| {
 4980                        request.check_capabilities(server.adapter_server_capabilities())
 4981                    })
 4982                    .map(|(_, server)| server.clone())
 4983            }),
 4984            LanguageServerToQuery::Other(id) => self
 4985                .language_server_for_local_buffer(buffer, id, cx)
 4986                .and_then(|(_, server)| {
 4987                    request
 4988                        .check_capabilities(server.adapter_server_capabilities())
 4989                        .then(|| Arc::clone(server))
 4990                }),
 4991        }) else {
 4992            return Task::ready(Ok(Default::default()));
 4993        };
 4994
 4995        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4996
 4997        let Some(file) = file else {
 4998            return Task::ready(Ok(Default::default()));
 4999        };
 5000
 5001        let lsp_params = match request.to_lsp_params_or_response(
 5002            &file.abs_path(cx),
 5003            buffer.read(cx),
 5004            &language_server,
 5005            cx,
 5006        ) {
 5007            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 5008            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 5009            Err(err) => {
 5010                let message = format!(
 5011                    "{} via {} failed: {}",
 5012                    request.display_name(),
 5013                    language_server.name(),
 5014                    err
 5015                );
 5016                // rust-analyzer likes to error with this when its still loading up
 5017                if !message.ends_with("content modified") {
 5018                    log::warn!("{message}");
 5019                }
 5020                return Task::ready(Err(anyhow!(message)));
 5021            }
 5022        };
 5023
 5024        let status = request.status();
 5025        let request_timeout = ProjectSettings::get_global(cx)
 5026            .global_lsp_settings
 5027            .get_request_timeout();
 5028
 5029        cx.spawn(async move |this, cx| {
 5030            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5031
 5032            let id = lsp_request.id();
 5033            let _cleanup = if status.is_some() {
 5034                cx.update(|cx| {
 5035                    this.update(cx, |this, cx| {
 5036                        this.on_lsp_work_start(
 5037                            language_server.server_id(),
 5038                            ProgressToken::Number(id),
 5039                            LanguageServerProgress {
 5040                                is_disk_based_diagnostics_progress: false,
 5041                                is_cancellable: false,
 5042                                title: None,
 5043                                message: status.clone(),
 5044                                percentage: None,
 5045                                last_update_at: cx.background_executor().now(),
 5046                            },
 5047                            cx,
 5048                        );
 5049                    })
 5050                })
 5051                .log_err();
 5052
 5053                Some(defer(|| {
 5054                    cx.update(|cx| {
 5055                        this.update(cx, |this, cx| {
 5056                            this.on_lsp_work_end(
 5057                                language_server.server_id(),
 5058                                ProgressToken::Number(id),
 5059                                cx,
 5060                            );
 5061                        })
 5062                    })
 5063                    .log_err();
 5064                }))
 5065            } else {
 5066                None
 5067            };
 5068
 5069            let result = lsp_request.await.into_response();
 5070
 5071            let response = result.map_err(|err| {
 5072                let message = format!(
 5073                    "{} via {} failed: {}",
 5074                    request.display_name(),
 5075                    language_server.name(),
 5076                    err
 5077                );
 5078                // rust-analyzer likes to error with this when its still loading up
 5079                if !message.ends_with("content modified") {
 5080                    log::warn!("{message}");
 5081                }
 5082                anyhow::anyhow!(message)
 5083            })?;
 5084
 5085            request
 5086                .response_from_lsp(
 5087                    response,
 5088                    this.upgrade().context("no app context")?,
 5089                    buffer,
 5090                    language_server.server_id(),
 5091                    cx.clone(),
 5092                )
 5093                .await
 5094        })
 5095    }
 5096
 5097    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5098        let mut language_formatters_to_check = Vec::new();
 5099        for buffer in self.buffer_store.read(cx).buffers() {
 5100            let buffer = buffer.read(cx);
 5101            let buffer_file = File::from_dyn(buffer.file());
 5102            let buffer_language = buffer.language();
 5103            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 5104            if buffer_language.is_some() {
 5105                language_formatters_to_check.push((
 5106                    buffer_file.map(|f| f.worktree_id(cx)),
 5107                    settings.into_owned(),
 5108                ));
 5109            }
 5110        }
 5111
 5112        self.request_workspace_config_refresh();
 5113
 5114        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5115            prettier_store.update(cx, |prettier_store, cx| {
 5116                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5117            })
 5118        }
 5119
 5120        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5121            .global_lsp_settings
 5122            .semantic_token_rules
 5123            .clone();
 5124        self.semantic_token_config
 5125            .update_rules(new_semantic_token_rules);
 5126        // Always clear cached stylizers so that changes to language-specific
 5127        // semantic token rules (e.g. from extension install/uninstall) are
 5128        // picked up. Stylizers are recreated lazily, so this is cheap.
 5129        self.semantic_token_config.clear_stylizers();
 5130
 5131        let new_global_semantic_tokens_mode =
 5132            all_language_settings(None, cx).defaults.semantic_tokens;
 5133        if self
 5134            .semantic_token_config
 5135            .update_global_mode(new_global_semantic_tokens_mode)
 5136        {
 5137            self.restart_all_language_servers(cx);
 5138        }
 5139
 5140        cx.notify();
 5141    }
 5142
 5143    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5144        let buffer_store = self.buffer_store.clone();
 5145        let Some(local) = self.as_local_mut() else {
 5146            return;
 5147        };
 5148        let mut adapters = BTreeMap::default();
 5149        let get_adapter = {
 5150            let languages = local.languages.clone();
 5151            let environment = local.environment.clone();
 5152            let weak = local.weak.clone();
 5153            let worktree_store = local.worktree_store.clone();
 5154            let http_client = local.http_client.clone();
 5155            let fs = local.fs.clone();
 5156            move |worktree_id, cx: &mut App| {
 5157                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5158                Some(LocalLspAdapterDelegate::new(
 5159                    languages.clone(),
 5160                    &environment,
 5161                    weak.clone(),
 5162                    &worktree,
 5163                    http_client.clone(),
 5164                    fs.clone(),
 5165                    cx,
 5166                ))
 5167            }
 5168        };
 5169
 5170        let mut messages_to_report = Vec::new();
 5171        let (new_tree, to_stop) = {
 5172            let mut rebase = local.lsp_tree.rebase();
 5173            let buffers = buffer_store
 5174                .read(cx)
 5175                .buffers()
 5176                .filter_map(|buffer| {
 5177                    let raw_buffer = buffer.read(cx);
 5178                    if !local
 5179                        .registered_buffers
 5180                        .contains_key(&raw_buffer.remote_id())
 5181                    {
 5182                        return None;
 5183                    }
 5184                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5185                    let language = raw_buffer.language().cloned()?;
 5186                    Some((file, language, raw_buffer.remote_id()))
 5187                })
 5188                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5189            for (file, language, buffer_id) in buffers {
 5190                let worktree_id = file.worktree_id(cx);
 5191                let Some(worktree) = local
 5192                    .worktree_store
 5193                    .read(cx)
 5194                    .worktree_for_id(worktree_id, cx)
 5195                else {
 5196                    continue;
 5197                };
 5198
 5199                if let Some((_, apply)) = local.reuse_existing_language_server(
 5200                    rebase.server_tree(),
 5201                    &worktree,
 5202                    &language.name(),
 5203                    cx,
 5204                ) {
 5205                    (apply)(rebase.server_tree());
 5206                } else if let Some(lsp_delegate) = adapters
 5207                    .entry(worktree_id)
 5208                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5209                    .clone()
 5210                {
 5211                    let delegate =
 5212                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5213                    let path = file
 5214                        .path()
 5215                        .parent()
 5216                        .map(Arc::from)
 5217                        .unwrap_or_else(|| file.path().clone());
 5218                    let worktree_path = ProjectPath { worktree_id, path };
 5219                    let abs_path = file.abs_path(cx);
 5220                    let nodes = rebase
 5221                        .walk(
 5222                            worktree_path,
 5223                            language.name(),
 5224                            language.manifest(),
 5225                            delegate.clone(),
 5226                            cx,
 5227                        )
 5228                        .collect::<Vec<_>>();
 5229                    for node in nodes {
 5230                        let server_id = node.server_id_or_init(|disposition| {
 5231                            let path = &disposition.path;
 5232                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5233                            let key = LanguageServerSeed {
 5234                                worktree_id,
 5235                                name: disposition.server_name.clone(),
 5236                                settings: LanguageServerSeedSettings {
 5237                                    binary: disposition.settings.binary.clone(),
 5238                                    initialization_options: disposition
 5239                                        .settings
 5240                                        .initialization_options
 5241                                        .clone(),
 5242                                },
 5243                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5244                                    path.worktree_id,
 5245                                    &path.path,
 5246                                    language.name(),
 5247                                ),
 5248                            };
 5249                            local.language_server_ids.remove(&key);
 5250
 5251                            let server_id = local.get_or_insert_language_server(
 5252                                &worktree,
 5253                                lsp_delegate.clone(),
 5254                                disposition,
 5255                                &language.name(),
 5256                                cx,
 5257                            );
 5258                            if let Some(state) = local.language_servers.get(&server_id)
 5259                                && let Ok(uri) = uri
 5260                            {
 5261                                state.add_workspace_folder(uri);
 5262                            };
 5263                            server_id
 5264                        });
 5265
 5266                        if let Some(language_server_id) = server_id {
 5267                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5268                                language_server_id,
 5269                                name: node.name(),
 5270                                message:
 5271                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5272                                        proto::RegisteredForBuffer {
 5273                                            buffer_abs_path: abs_path
 5274                                                .to_string_lossy()
 5275                                                .into_owned(),
 5276                                            buffer_id: buffer_id.to_proto(),
 5277                                        },
 5278                                    ),
 5279                            });
 5280                        }
 5281                    }
 5282                } else {
 5283                    continue;
 5284                }
 5285            }
 5286            rebase.finish()
 5287        };
 5288        for message in messages_to_report {
 5289            cx.emit(message);
 5290        }
 5291        local.lsp_tree = new_tree;
 5292        for (id, _) in to_stop {
 5293            self.stop_local_language_server(id, cx).detach();
 5294        }
 5295    }
 5296
 5297    pub fn apply_code_action(
 5298        &self,
 5299        buffer_handle: Entity<Buffer>,
 5300        mut action: CodeAction,
 5301        push_to_history: bool,
 5302        cx: &mut Context<Self>,
 5303    ) -> Task<Result<ProjectTransaction>> {
 5304        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5305            let request = proto::ApplyCodeAction {
 5306                project_id,
 5307                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5308                action: Some(Self::serialize_code_action(&action)),
 5309            };
 5310            let buffer_store = self.buffer_store();
 5311            cx.spawn(async move |_, cx| {
 5312                let response = upstream_client
 5313                    .request(request)
 5314                    .await?
 5315                    .transaction
 5316                    .context("missing transaction")?;
 5317
 5318                buffer_store
 5319                    .update(cx, |buffer_store, cx| {
 5320                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5321                    })
 5322                    .await
 5323            })
 5324        } else if self.mode.is_local() {
 5325            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5326                let request_timeout = ProjectSettings::get_global(cx)
 5327                    .global_lsp_settings
 5328                    .get_request_timeout();
 5329                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5330                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5331            }) else {
 5332                return Task::ready(Ok(ProjectTransaction::default()));
 5333            };
 5334
 5335            cx.spawn(async move |this, cx| {
 5336                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5337                    .await
 5338                    .context("resolving a code action")?;
 5339                if let Some(edit) = action.lsp_action.edit()
 5340                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5341                        return LocalLspStore::deserialize_workspace_edit(
 5342                            this.upgrade().context("no app present")?,
 5343                            edit.clone(),
 5344                            push_to_history,
 5345
 5346                            lang_server.clone(),
 5347                            cx,
 5348                        )
 5349                        .await;
 5350                    }
 5351
 5352                let Some(command) = action.lsp_action.command() else {
 5353                    return Ok(ProjectTransaction::default())
 5354                };
 5355
 5356                let server_capabilities = lang_server.capabilities();
 5357                let available_commands = server_capabilities
 5358                    .execute_command_provider
 5359                    .as_ref()
 5360                    .map(|options| options.commands.as_slice())
 5361                    .unwrap_or_default();
 5362
 5363                if !available_commands.contains(&command.command) {
 5364                    log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5365                    return Ok(ProjectTransaction::default())
 5366                }
 5367
 5368                let request_timeout = cx.update(|app|
 5369                    ProjectSettings::get_global(app)
 5370                    .global_lsp_settings
 5371                    .get_request_timeout()
 5372                );
 5373
 5374                this.update(cx, |this, _| {
 5375                    this.as_local_mut()
 5376                        .unwrap()
 5377                        .last_workspace_edits_by_language_server
 5378                        .remove(&lang_server.server_id());
 5379                })?;
 5380
 5381                let _result = lang_server
 5382                    .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5383                        command: command.command.clone(),
 5384                        arguments: command.arguments.clone().unwrap_or_default(),
 5385                        ..lsp::ExecuteCommandParams::default()
 5386                    }, request_timeout)
 5387                    .await.into_response()
 5388                    .context("execute command")?;
 5389
 5390                return this.update(cx, |this, _| {
 5391                    this.as_local_mut()
 5392                        .unwrap()
 5393                        .last_workspace_edits_by_language_server
 5394                        .remove(&lang_server.server_id())
 5395                        .unwrap_or_default()
 5396                });
 5397            })
 5398        } else {
 5399            Task::ready(Err(anyhow!("no upstream client and not local")))
 5400        }
 5401    }
 5402
 5403    pub fn apply_code_action_kind(
 5404        &mut self,
 5405        buffers: HashSet<Entity<Buffer>>,
 5406        kind: CodeActionKind,
 5407        push_to_history: bool,
 5408        cx: &mut Context<Self>,
 5409    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5410        if self.as_local().is_some() {
 5411            cx.spawn(async move |lsp_store, cx| {
 5412                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5413                let result = LocalLspStore::execute_code_action_kind_locally(
 5414                    lsp_store.clone(),
 5415                    buffers,
 5416                    kind,
 5417                    push_to_history,
 5418                    cx,
 5419                )
 5420                .await;
 5421                lsp_store.update(cx, |lsp_store, _| {
 5422                    lsp_store.update_last_formatting_failure(&result);
 5423                })?;
 5424                result
 5425            })
 5426        } else if let Some((client, project_id)) = self.upstream_client() {
 5427            let buffer_store = self.buffer_store();
 5428            cx.spawn(async move |lsp_store, cx| {
 5429                let result = client
 5430                    .request(proto::ApplyCodeActionKind {
 5431                        project_id,
 5432                        kind: kind.as_str().to_owned(),
 5433                        buffer_ids: buffers
 5434                            .iter()
 5435                            .map(|buffer| {
 5436                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5437                            })
 5438                            .collect(),
 5439                    })
 5440                    .await
 5441                    .and_then(|result| result.transaction.context("missing transaction"));
 5442                lsp_store.update(cx, |lsp_store, _| {
 5443                    lsp_store.update_last_formatting_failure(&result);
 5444                })?;
 5445
 5446                let transaction_response = result?;
 5447                buffer_store
 5448                    .update(cx, |buffer_store, cx| {
 5449                        buffer_store.deserialize_project_transaction(
 5450                            transaction_response,
 5451                            push_to_history,
 5452                            cx,
 5453                        )
 5454                    })
 5455                    .await
 5456            })
 5457        } else {
 5458            Task::ready(Ok(ProjectTransaction::default()))
 5459        }
 5460    }
 5461
 5462    pub fn resolved_hint(
 5463        &mut self,
 5464        buffer_id: BufferId,
 5465        id: InlayId,
 5466        cx: &mut Context<Self>,
 5467    ) -> Option<ResolvedHint> {
 5468        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5469
 5470        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5471        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5472        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5473        let (server_id, resolve_data) = match &hint.resolve_state {
 5474            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5475            ResolveState::Resolving => {
 5476                return Some(ResolvedHint::Resolving(
 5477                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5478                ));
 5479            }
 5480            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5481        };
 5482
 5483        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5484        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5485        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5486            id,
 5487            cx.spawn(async move |lsp_store, cx| {
 5488                let resolved_hint = resolve_task.await;
 5489                lsp_store
 5490                    .update(cx, |lsp_store, _| {
 5491                        if let Some(old_inlay_hint) = lsp_store
 5492                            .lsp_data
 5493                            .get_mut(&buffer_id)
 5494                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5495                        {
 5496                            match resolved_hint {
 5497                                Ok(resolved_hint) => {
 5498                                    *old_inlay_hint = resolved_hint;
 5499                                }
 5500                                Err(e) => {
 5501                                    old_inlay_hint.resolve_state =
 5502                                        ResolveState::CanResolve(server_id, resolve_data);
 5503                                    log::error!("Inlay hint resolve failed: {e:#}");
 5504                                }
 5505                            }
 5506                        }
 5507                    })
 5508                    .ok();
 5509            })
 5510            .shared(),
 5511        );
 5512        debug_assert!(
 5513            previous_task.is_none(),
 5514            "Did not change hint's resolve state after spawning its resolve"
 5515        );
 5516        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5517        None
 5518    }
 5519
 5520    pub(crate) fn linked_edits(
 5521        &mut self,
 5522        buffer: &Entity<Buffer>,
 5523        position: Anchor,
 5524        cx: &mut Context<Self>,
 5525    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5526        let snapshot = buffer.read(cx).snapshot();
 5527        let scope = snapshot.language_scope_at(position);
 5528        let Some(server_id) = self
 5529            .as_local()
 5530            .and_then(|local| {
 5531                buffer.update(cx, |buffer, cx| {
 5532                    local
 5533                        .language_servers_for_buffer(buffer, cx)
 5534                        .filter(|(_, server)| {
 5535                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5536                        })
 5537                        .filter(|(adapter, _)| {
 5538                            scope
 5539                                .as_ref()
 5540                                .map(|scope| scope.language_allowed(&adapter.name))
 5541                                .unwrap_or(true)
 5542                        })
 5543                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5544                        .next()
 5545                })
 5546            })
 5547            .or_else(|| {
 5548                self.upstream_client()
 5549                    .is_some()
 5550                    .then_some(LanguageServerToQuery::FirstCapable)
 5551            })
 5552            .filter(|_| {
 5553                maybe!({
 5554                    let language = buffer.read(cx).language_at(position)?;
 5555                    Some(
 5556                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5557                            .linked_edits,
 5558                    )
 5559                }) == Some(true)
 5560            })
 5561        else {
 5562            return Task::ready(Ok(Vec::new()));
 5563        };
 5564
 5565        self.request_lsp(
 5566            buffer.clone(),
 5567            server_id,
 5568            LinkedEditingRange { position },
 5569            cx,
 5570        )
 5571    }
 5572
 5573    fn apply_on_type_formatting(
 5574        &mut self,
 5575        buffer: Entity<Buffer>,
 5576        position: Anchor,
 5577        trigger: String,
 5578        cx: &mut Context<Self>,
 5579    ) -> Task<Result<Option<Transaction>>> {
 5580        if let Some((client, project_id)) = self.upstream_client() {
 5581            if !self.check_if_capable_for_proto_request(
 5582                &buffer,
 5583                |capabilities| {
 5584                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5585                },
 5586                cx,
 5587            ) {
 5588                return Task::ready(Ok(None));
 5589            }
 5590            let request = proto::OnTypeFormatting {
 5591                project_id,
 5592                buffer_id: buffer.read(cx).remote_id().into(),
 5593                position: Some(serialize_anchor(&position)),
 5594                trigger,
 5595                version: serialize_version(&buffer.read(cx).version()),
 5596            };
 5597            cx.background_spawn(async move {
 5598                client
 5599                    .request(request)
 5600                    .await?
 5601                    .transaction
 5602                    .map(language::proto::deserialize_transaction)
 5603                    .transpose()
 5604            })
 5605        } else if let Some(local) = self.as_local_mut() {
 5606            let buffer_id = buffer.read(cx).remote_id();
 5607            local.buffers_being_formatted.insert(buffer_id);
 5608            cx.spawn(async move |this, cx| {
 5609                let _cleanup = defer({
 5610                    let this = this.clone();
 5611                    let mut cx = cx.clone();
 5612                    move || {
 5613                        this.update(&mut cx, |this, _| {
 5614                            if let Some(local) = this.as_local_mut() {
 5615                                local.buffers_being_formatted.remove(&buffer_id);
 5616                            }
 5617                        })
 5618                        .ok();
 5619                    }
 5620                });
 5621
 5622                buffer
 5623                    .update(cx, |buffer, _| {
 5624                        buffer.wait_for_edits(Some(position.timestamp()))
 5625                    })
 5626                    .await?;
 5627                this.update(cx, |this, cx| {
 5628                    let position = position.to_point_utf16(buffer.read(cx));
 5629                    this.on_type_format(buffer, position, trigger, false, cx)
 5630                })?
 5631                .await
 5632            })
 5633        } else {
 5634            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5635        }
 5636    }
 5637
 5638    pub fn on_type_format<T: ToPointUtf16>(
 5639        &mut self,
 5640        buffer: Entity<Buffer>,
 5641        position: T,
 5642        trigger: String,
 5643        push_to_history: bool,
 5644        cx: &mut Context<Self>,
 5645    ) -> Task<Result<Option<Transaction>>> {
 5646        let position = position.to_point_utf16(buffer.read(cx));
 5647        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5648    }
 5649
 5650    fn on_type_format_impl(
 5651        &mut self,
 5652        buffer: Entity<Buffer>,
 5653        position: PointUtf16,
 5654        trigger: String,
 5655        push_to_history: bool,
 5656        cx: &mut Context<Self>,
 5657    ) -> Task<Result<Option<Transaction>>> {
 5658        let options = buffer.update(cx, |buffer, cx| {
 5659            lsp_command::lsp_formatting_options(
 5660                language_settings(
 5661                    buffer.language_at(position).map(|l| l.name()),
 5662                    buffer.file(),
 5663                    cx,
 5664                )
 5665                .as_ref(),
 5666            )
 5667        });
 5668
 5669        cx.spawn(async move |this, cx| {
 5670            if let Some(waiter) =
 5671                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5672            {
 5673                waiter.await?;
 5674            }
 5675            cx.update(|cx| {
 5676                this.update(cx, |this, cx| {
 5677                    this.request_lsp(
 5678                        buffer.clone(),
 5679                        LanguageServerToQuery::FirstCapable,
 5680                        OnTypeFormatting {
 5681                            position,
 5682                            trigger,
 5683                            options,
 5684                            push_to_history,
 5685                        },
 5686                        cx,
 5687                    )
 5688                })
 5689            })?
 5690            .await
 5691        })
 5692    }
 5693
 5694    pub fn definitions(
 5695        &mut self,
 5696        buffer: &Entity<Buffer>,
 5697        position: PointUtf16,
 5698        cx: &mut Context<Self>,
 5699    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5700        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5701            let request = GetDefinitions { position };
 5702            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5703                return Task::ready(Ok(None));
 5704            }
 5705
 5706            let request_timeout = ProjectSettings::get_global(cx)
 5707                .global_lsp_settings
 5708                .get_request_timeout();
 5709
 5710            let request_task = upstream_client.request_lsp(
 5711                project_id,
 5712                None,
 5713                request_timeout,
 5714                cx.background_executor().clone(),
 5715                request.to_proto(project_id, buffer.read(cx)),
 5716            );
 5717            let buffer = buffer.clone();
 5718            cx.spawn(async move |weak_lsp_store, cx| {
 5719                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5720                    return Ok(None);
 5721                };
 5722                let Some(responses) = request_task.await? else {
 5723                    return Ok(None);
 5724                };
 5725                let actions = join_all(responses.payload.into_iter().map(|response| {
 5726                    GetDefinitions { position }.response_from_proto(
 5727                        response.response,
 5728                        lsp_store.clone(),
 5729                        buffer.clone(),
 5730                        cx.clone(),
 5731                    )
 5732                }))
 5733                .await;
 5734
 5735                Ok(Some(
 5736                    actions
 5737                        .into_iter()
 5738                        .collect::<Result<Vec<Vec<_>>>>()?
 5739                        .into_iter()
 5740                        .flatten()
 5741                        .dedup()
 5742                        .collect(),
 5743                ))
 5744            })
 5745        } else {
 5746            let definitions_task = self.request_multiple_lsp_locally(
 5747                buffer,
 5748                Some(position),
 5749                GetDefinitions { position },
 5750                cx,
 5751            );
 5752            cx.background_spawn(async move {
 5753                Ok(Some(
 5754                    definitions_task
 5755                        .await
 5756                        .into_iter()
 5757                        .flat_map(|(_, definitions)| definitions)
 5758                        .dedup()
 5759                        .collect(),
 5760                ))
 5761            })
 5762        }
 5763    }
 5764
 5765    pub fn declarations(
 5766        &mut self,
 5767        buffer: &Entity<Buffer>,
 5768        position: PointUtf16,
 5769        cx: &mut Context<Self>,
 5770    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5771        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5772            let request = GetDeclarations { position };
 5773            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5774                return Task::ready(Ok(None));
 5775            }
 5776            let request_timeout = ProjectSettings::get_global(cx)
 5777                .global_lsp_settings
 5778                .get_request_timeout();
 5779            let request_task = upstream_client.request_lsp(
 5780                project_id,
 5781                None,
 5782                request_timeout,
 5783                cx.background_executor().clone(),
 5784                request.to_proto(project_id, buffer.read(cx)),
 5785            );
 5786            let buffer = buffer.clone();
 5787            cx.spawn(async move |weak_lsp_store, cx| {
 5788                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5789                    return Ok(None);
 5790                };
 5791                let Some(responses) = request_task.await? else {
 5792                    return Ok(None);
 5793                };
 5794                let actions = join_all(responses.payload.into_iter().map(|response| {
 5795                    GetDeclarations { position }.response_from_proto(
 5796                        response.response,
 5797                        lsp_store.clone(),
 5798                        buffer.clone(),
 5799                        cx.clone(),
 5800                    )
 5801                }))
 5802                .await;
 5803
 5804                Ok(Some(
 5805                    actions
 5806                        .into_iter()
 5807                        .collect::<Result<Vec<Vec<_>>>>()?
 5808                        .into_iter()
 5809                        .flatten()
 5810                        .dedup()
 5811                        .collect(),
 5812                ))
 5813            })
 5814        } else {
 5815            let declarations_task = self.request_multiple_lsp_locally(
 5816                buffer,
 5817                Some(position),
 5818                GetDeclarations { position },
 5819                cx,
 5820            );
 5821            cx.background_spawn(async move {
 5822                Ok(Some(
 5823                    declarations_task
 5824                        .await
 5825                        .into_iter()
 5826                        .flat_map(|(_, declarations)| declarations)
 5827                        .dedup()
 5828                        .collect(),
 5829                ))
 5830            })
 5831        }
 5832    }
 5833
 5834    pub fn type_definitions(
 5835        &mut self,
 5836        buffer: &Entity<Buffer>,
 5837        position: PointUtf16,
 5838        cx: &mut Context<Self>,
 5839    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5840        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5841            let request = GetTypeDefinitions { position };
 5842            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5843                return Task::ready(Ok(None));
 5844            }
 5845            let request_timeout = ProjectSettings::get_global(cx)
 5846                .global_lsp_settings
 5847                .get_request_timeout();
 5848            let request_task = upstream_client.request_lsp(
 5849                project_id,
 5850                None,
 5851                request_timeout,
 5852                cx.background_executor().clone(),
 5853                request.to_proto(project_id, buffer.read(cx)),
 5854            );
 5855            let buffer = buffer.clone();
 5856            cx.spawn(async move |weak_lsp_store, cx| {
 5857                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5858                    return Ok(None);
 5859                };
 5860                let Some(responses) = request_task.await? else {
 5861                    return Ok(None);
 5862                };
 5863                let actions = join_all(responses.payload.into_iter().map(|response| {
 5864                    GetTypeDefinitions { position }.response_from_proto(
 5865                        response.response,
 5866                        lsp_store.clone(),
 5867                        buffer.clone(),
 5868                        cx.clone(),
 5869                    )
 5870                }))
 5871                .await;
 5872
 5873                Ok(Some(
 5874                    actions
 5875                        .into_iter()
 5876                        .collect::<Result<Vec<Vec<_>>>>()?
 5877                        .into_iter()
 5878                        .flatten()
 5879                        .dedup()
 5880                        .collect(),
 5881                ))
 5882            })
 5883        } else {
 5884            let type_definitions_task = self.request_multiple_lsp_locally(
 5885                buffer,
 5886                Some(position),
 5887                GetTypeDefinitions { position },
 5888                cx,
 5889            );
 5890            cx.background_spawn(async move {
 5891                Ok(Some(
 5892                    type_definitions_task
 5893                        .await
 5894                        .into_iter()
 5895                        .flat_map(|(_, type_definitions)| type_definitions)
 5896                        .dedup()
 5897                        .collect(),
 5898                ))
 5899            })
 5900        }
 5901    }
 5902
 5903    pub fn implementations(
 5904        &mut self,
 5905        buffer: &Entity<Buffer>,
 5906        position: PointUtf16,
 5907        cx: &mut Context<Self>,
 5908    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5909        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5910            let request = GetImplementations { position };
 5911            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5912                return Task::ready(Ok(None));
 5913            }
 5914
 5915            let request_timeout = ProjectSettings::get_global(cx)
 5916                .global_lsp_settings
 5917                .get_request_timeout();
 5918            let request_task = upstream_client.request_lsp(
 5919                project_id,
 5920                None,
 5921                request_timeout,
 5922                cx.background_executor().clone(),
 5923                request.to_proto(project_id, buffer.read(cx)),
 5924            );
 5925            let buffer = buffer.clone();
 5926            cx.spawn(async move |weak_lsp_store, cx| {
 5927                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5928                    return Ok(None);
 5929                };
 5930                let Some(responses) = request_task.await? else {
 5931                    return Ok(None);
 5932                };
 5933                let actions = join_all(responses.payload.into_iter().map(|response| {
 5934                    GetImplementations { position }.response_from_proto(
 5935                        response.response,
 5936                        lsp_store.clone(),
 5937                        buffer.clone(),
 5938                        cx.clone(),
 5939                    )
 5940                }))
 5941                .await;
 5942
 5943                Ok(Some(
 5944                    actions
 5945                        .into_iter()
 5946                        .collect::<Result<Vec<Vec<_>>>>()?
 5947                        .into_iter()
 5948                        .flatten()
 5949                        .dedup()
 5950                        .collect(),
 5951                ))
 5952            })
 5953        } else {
 5954            let implementations_task = self.request_multiple_lsp_locally(
 5955                buffer,
 5956                Some(position),
 5957                GetImplementations { position },
 5958                cx,
 5959            );
 5960            cx.background_spawn(async move {
 5961                Ok(Some(
 5962                    implementations_task
 5963                        .await
 5964                        .into_iter()
 5965                        .flat_map(|(_, implementations)| implementations)
 5966                        .dedup()
 5967                        .collect(),
 5968                ))
 5969            })
 5970        }
 5971    }
 5972
 5973    pub fn references(
 5974        &mut self,
 5975        buffer: &Entity<Buffer>,
 5976        position: PointUtf16,
 5977        cx: &mut Context<Self>,
 5978    ) -> Task<Result<Option<Vec<Location>>>> {
 5979        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5980            let request = GetReferences { position };
 5981            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5982                return Task::ready(Ok(None));
 5983            }
 5984
 5985            let request_timeout = ProjectSettings::get_global(cx)
 5986                .global_lsp_settings
 5987                .get_request_timeout();
 5988            let request_task = upstream_client.request_lsp(
 5989                project_id,
 5990                None,
 5991                request_timeout,
 5992                cx.background_executor().clone(),
 5993                request.to_proto(project_id, buffer.read(cx)),
 5994            );
 5995            let buffer = buffer.clone();
 5996            cx.spawn(async move |weak_lsp_store, cx| {
 5997                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5998                    return Ok(None);
 5999                };
 6000                let Some(responses) = request_task.await? else {
 6001                    return Ok(None);
 6002                };
 6003
 6004                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 6005                    GetReferences { position }.response_from_proto(
 6006                        lsp_response.response,
 6007                        lsp_store.clone(),
 6008                        buffer.clone(),
 6009                        cx.clone(),
 6010                    )
 6011                }))
 6012                .await
 6013                .into_iter()
 6014                .collect::<Result<Vec<Vec<_>>>>()?
 6015                .into_iter()
 6016                .flatten()
 6017                .dedup()
 6018                .collect();
 6019                Ok(Some(locations))
 6020            })
 6021        } else {
 6022            let references_task = self.request_multiple_lsp_locally(
 6023                buffer,
 6024                Some(position),
 6025                GetReferences { position },
 6026                cx,
 6027            );
 6028            cx.background_spawn(async move {
 6029                Ok(Some(
 6030                    references_task
 6031                        .await
 6032                        .into_iter()
 6033                        .flat_map(|(_, references)| references)
 6034                        .dedup()
 6035                        .collect(),
 6036                ))
 6037            })
 6038        }
 6039    }
 6040
 6041    pub fn code_actions(
 6042        &mut self,
 6043        buffer: &Entity<Buffer>,
 6044        range: Range<Anchor>,
 6045        kinds: Option<Vec<CodeActionKind>>,
 6046        cx: &mut Context<Self>,
 6047    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6048        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6049            let request = GetCodeActions {
 6050                range: range.clone(),
 6051                kinds: kinds.clone(),
 6052            };
 6053            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6054                return Task::ready(Ok(None));
 6055            }
 6056            let request_timeout = ProjectSettings::get_global(cx)
 6057                .global_lsp_settings
 6058                .get_request_timeout();
 6059            let request_task = upstream_client.request_lsp(
 6060                project_id,
 6061                None,
 6062                request_timeout,
 6063                cx.background_executor().clone(),
 6064                request.to_proto(project_id, buffer.read(cx)),
 6065            );
 6066            let buffer = buffer.clone();
 6067            cx.spawn(async move |weak_lsp_store, cx| {
 6068                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6069                    return Ok(None);
 6070                };
 6071                let Some(responses) = request_task.await? else {
 6072                    return Ok(None);
 6073                };
 6074                let actions = join_all(responses.payload.into_iter().map(|response| {
 6075                    GetCodeActions {
 6076                        range: range.clone(),
 6077                        kinds: kinds.clone(),
 6078                    }
 6079                    .response_from_proto(
 6080                        response.response,
 6081                        lsp_store.clone(),
 6082                        buffer.clone(),
 6083                        cx.clone(),
 6084                    )
 6085                }))
 6086                .await;
 6087
 6088                Ok(Some(
 6089                    actions
 6090                        .into_iter()
 6091                        .collect::<Result<Vec<Vec<_>>>>()?
 6092                        .into_iter()
 6093                        .flatten()
 6094                        .collect(),
 6095                ))
 6096            })
 6097        } else {
 6098            let all_actions_task = self.request_multiple_lsp_locally(
 6099                buffer,
 6100                Some(range.start),
 6101                GetCodeActions { range, kinds },
 6102                cx,
 6103            );
 6104            cx.background_spawn(async move {
 6105                Ok(Some(
 6106                    all_actions_task
 6107                        .await
 6108                        .into_iter()
 6109                        .flat_map(|(_, actions)| actions)
 6110                        .collect(),
 6111                ))
 6112            })
 6113        }
 6114    }
 6115
 6116    #[inline(never)]
 6117    pub fn completions(
 6118        &self,
 6119        buffer: &Entity<Buffer>,
 6120        position: PointUtf16,
 6121        context: CompletionContext,
 6122        cx: &mut Context<Self>,
 6123    ) -> Task<Result<Vec<CompletionResponse>>> {
 6124        let language_registry = self.languages.clone();
 6125
 6126        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6127            let snapshot = buffer.read(cx).snapshot();
 6128            let offset = position.to_offset(&snapshot);
 6129            let scope = snapshot.language_scope_at(offset);
 6130            let capable_lsps = self.all_capable_for_proto_request(
 6131                buffer,
 6132                |server_name, capabilities| {
 6133                    capabilities.completion_provider.is_some()
 6134                        && scope
 6135                            .as_ref()
 6136                            .map(|scope| scope.language_allowed(server_name))
 6137                            .unwrap_or(true)
 6138                },
 6139                cx,
 6140            );
 6141            if capable_lsps.is_empty() {
 6142                return Task::ready(Ok(Vec::new()));
 6143            }
 6144
 6145            let language = buffer.read(cx).language().cloned();
 6146
 6147            let buffer = buffer.clone();
 6148
 6149            cx.spawn(async move |this, cx| {
 6150                let requests = join_all(
 6151                    capable_lsps
 6152                        .into_iter()
 6153                        .map(|(id, server_name)| {
 6154                            let request = GetCompletions {
 6155                                position,
 6156                                context: context.clone(),
 6157                                server_id: Some(id),
 6158                            };
 6159                            let buffer = buffer.clone();
 6160                            let language = language.clone();
 6161                            let lsp_adapter = language.as_ref().and_then(|language| {
 6162                                let adapters = language_registry.lsp_adapters(&language.name());
 6163                                adapters
 6164                                    .iter()
 6165                                    .find(|adapter| adapter.name() == server_name)
 6166                                    .or_else(|| adapters.first())
 6167                                    .cloned()
 6168                            });
 6169                            let upstream_client = upstream_client.clone();
 6170                            let response = this
 6171                                .update(cx, |this, cx| {
 6172                                    this.send_lsp_proto_request(
 6173                                        buffer,
 6174                                        upstream_client,
 6175                                        project_id,
 6176                                        request,
 6177                                        cx,
 6178                                    )
 6179                                })
 6180                                .log_err();
 6181                            async move {
 6182                                let response = response?.await.log_err()?;
 6183
 6184                                let completions = populate_labels_for_completions(
 6185                                    response.completions,
 6186                                    language,
 6187                                    lsp_adapter,
 6188                                )
 6189                                .await;
 6190
 6191                                Some(CompletionResponse {
 6192                                    completions,
 6193                                    display_options: CompletionDisplayOptions::default(),
 6194                                    is_incomplete: response.is_incomplete,
 6195                                })
 6196                            }
 6197                        })
 6198                        .collect::<Vec<_>>(),
 6199                );
 6200                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6201            })
 6202        } else if let Some(local) = self.as_local() {
 6203            let snapshot = buffer.read(cx).snapshot();
 6204            let offset = position.to_offset(&snapshot);
 6205            let scope = snapshot.language_scope_at(offset);
 6206            let language = snapshot.language().cloned();
 6207            let completion_settings = language_settings(
 6208                language.as_ref().map(|language| language.name()),
 6209                buffer.read(cx).file(),
 6210                cx,
 6211            )
 6212            .completions
 6213            .clone();
 6214            if !completion_settings.lsp {
 6215                return Task::ready(Ok(Vec::new()));
 6216            }
 6217
 6218            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6219                local
 6220                    .language_servers_for_buffer(buffer, cx)
 6221                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6222                    .filter(|(adapter, _)| {
 6223                        scope
 6224                            .as_ref()
 6225                            .map(|scope| scope.language_allowed(&adapter.name))
 6226                            .unwrap_or(true)
 6227                    })
 6228                    .map(|(_, server)| server.server_id())
 6229                    .collect()
 6230            });
 6231
 6232            let buffer = buffer.clone();
 6233            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6234            let lsp_timeout = if lsp_timeout > 0 {
 6235                Some(Duration::from_millis(lsp_timeout))
 6236            } else {
 6237                None
 6238            };
 6239            cx.spawn(async move |this,  cx| {
 6240                let mut tasks = Vec::with_capacity(server_ids.len());
 6241                this.update(cx, |lsp_store, cx| {
 6242                    for server_id in server_ids {
 6243                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6244                        let lsp_timeout = lsp_timeout
 6245                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6246                        let mut timeout = cx.background_spawn(async move {
 6247                            match lsp_timeout {
 6248                                Some(lsp_timeout) => {
 6249                                    lsp_timeout.await;
 6250                                    true
 6251                                },
 6252                                None => false,
 6253                            }
 6254                        }).fuse();
 6255                        let mut lsp_request = lsp_store.request_lsp(
 6256                            buffer.clone(),
 6257                            LanguageServerToQuery::Other(server_id),
 6258                            GetCompletions {
 6259                                position,
 6260                                context: context.clone(),
 6261                                server_id: Some(server_id),
 6262                            },
 6263                            cx,
 6264                        ).fuse();
 6265                        let new_task = cx.background_spawn(async move {
 6266                            select_biased! {
 6267                                response = lsp_request => anyhow::Ok(Some(response?)),
 6268                                timeout_happened = timeout => {
 6269                                    if timeout_happened {
 6270                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6271                                        Ok(None)
 6272                                    } else {
 6273                                        let completions = lsp_request.await?;
 6274                                        Ok(Some(completions))
 6275                                    }
 6276                                },
 6277                            }
 6278                        });
 6279                        tasks.push((lsp_adapter, new_task));
 6280                    }
 6281                })?;
 6282
 6283                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6284                    let completion_response = task.await.ok()??;
 6285                    let completions = populate_labels_for_completions(
 6286                            completion_response.completions,
 6287                            language.clone(),
 6288                            lsp_adapter,
 6289                        )
 6290                        .await;
 6291                    Some(CompletionResponse {
 6292                        completions,
 6293                        display_options: CompletionDisplayOptions::default(),
 6294                        is_incomplete: completion_response.is_incomplete,
 6295                    })
 6296                });
 6297
 6298                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6299
 6300                Ok(responses.into_iter().flatten().collect())
 6301            })
 6302        } else {
 6303            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6304        }
 6305    }
 6306
 6307    pub fn resolve_completions(
 6308        &self,
 6309        buffer: Entity<Buffer>,
 6310        completion_indices: Vec<usize>,
 6311        completions: Rc<RefCell<Box<[Completion]>>>,
 6312        cx: &mut Context<Self>,
 6313    ) -> Task<Result<bool>> {
 6314        let client = self.upstream_client();
 6315        let buffer_id = buffer.read(cx).remote_id();
 6316        let buffer_snapshot = buffer.read(cx).snapshot();
 6317
 6318        if !self.check_if_capable_for_proto_request(
 6319            &buffer,
 6320            GetCompletions::can_resolve_completions,
 6321            cx,
 6322        ) {
 6323            return Task::ready(Ok(false));
 6324        }
 6325        cx.spawn(async move |lsp_store, cx| {
 6326            let request_timeout = cx.update(|app| {
 6327                ProjectSettings::get_global(app)
 6328                    .global_lsp_settings
 6329                    .get_request_timeout()
 6330            });
 6331
 6332            let mut did_resolve = false;
 6333            if let Some((client, project_id)) = client {
 6334                for completion_index in completion_indices {
 6335                    let server_id = {
 6336                        let completion = &completions.borrow()[completion_index];
 6337                        completion.source.server_id()
 6338                    };
 6339                    if let Some(server_id) = server_id {
 6340                        if Self::resolve_completion_remote(
 6341                            project_id,
 6342                            server_id,
 6343                            buffer_id,
 6344                            completions.clone(),
 6345                            completion_index,
 6346                            client.clone(),
 6347                        )
 6348                        .await
 6349                        .log_err()
 6350                        .is_some()
 6351                        {
 6352                            did_resolve = true;
 6353                        }
 6354                    } else {
 6355                        resolve_word_completion(
 6356                            &buffer_snapshot,
 6357                            &mut completions.borrow_mut()[completion_index],
 6358                        );
 6359                    }
 6360                }
 6361            } else {
 6362                for completion_index in completion_indices {
 6363                    let server_id = {
 6364                        let completion = &completions.borrow()[completion_index];
 6365                        completion.source.server_id()
 6366                    };
 6367                    if let Some(server_id) = server_id {
 6368                        let server_and_adapter = lsp_store
 6369                            .read_with(cx, |lsp_store, _| {
 6370                                let server = lsp_store.language_server_for_id(server_id)?;
 6371                                let adapter =
 6372                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6373                                Some((server, adapter))
 6374                            })
 6375                            .ok()
 6376                            .flatten();
 6377                        let Some((server, adapter)) = server_and_adapter else {
 6378                            continue;
 6379                        };
 6380
 6381                        let resolved = Self::resolve_completion_local(
 6382                            server,
 6383                            completions.clone(),
 6384                            completion_index,
 6385                            request_timeout,
 6386                        )
 6387                        .await
 6388                        .log_err()
 6389                        .is_some();
 6390                        if resolved {
 6391                            Self::regenerate_completion_labels(
 6392                                adapter,
 6393                                &buffer_snapshot,
 6394                                completions.clone(),
 6395                                completion_index,
 6396                            )
 6397                            .await
 6398                            .log_err();
 6399                            did_resolve = true;
 6400                        }
 6401                    } else {
 6402                        resolve_word_completion(
 6403                            &buffer_snapshot,
 6404                            &mut completions.borrow_mut()[completion_index],
 6405                        );
 6406                    }
 6407                }
 6408            }
 6409
 6410            Ok(did_resolve)
 6411        })
 6412    }
 6413
 6414    async fn resolve_completion_local(
 6415        server: Arc<lsp::LanguageServer>,
 6416        completions: Rc<RefCell<Box<[Completion]>>>,
 6417        completion_index: usize,
 6418        request_timeout: Duration,
 6419    ) -> Result<()> {
 6420        let server_id = server.server_id();
 6421        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6422            return Ok(());
 6423        }
 6424
 6425        let request = {
 6426            let completion = &completions.borrow()[completion_index];
 6427            match &completion.source {
 6428                CompletionSource::Lsp {
 6429                    lsp_completion,
 6430                    resolved,
 6431                    server_id: completion_server_id,
 6432                    ..
 6433                } => {
 6434                    if *resolved {
 6435                        return Ok(());
 6436                    }
 6437                    anyhow::ensure!(
 6438                        server_id == *completion_server_id,
 6439                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6440                    );
 6441                    server.request::<lsp::request::ResolveCompletionItem>(
 6442                        *lsp_completion.clone(),
 6443                        request_timeout,
 6444                    )
 6445                }
 6446                CompletionSource::BufferWord { .. }
 6447                | CompletionSource::Dap { .. }
 6448                | CompletionSource::Custom => {
 6449                    return Ok(());
 6450                }
 6451            }
 6452        };
 6453        let resolved_completion = request
 6454            .await
 6455            .into_response()
 6456            .context("resolve completion")?;
 6457
 6458        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6459        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6460
 6461        let mut completions = completions.borrow_mut();
 6462        let completion = &mut completions[completion_index];
 6463        if let CompletionSource::Lsp {
 6464            lsp_completion,
 6465            resolved,
 6466            server_id: completion_server_id,
 6467            ..
 6468        } = &mut completion.source
 6469        {
 6470            if *resolved {
 6471                return Ok(());
 6472            }
 6473            anyhow::ensure!(
 6474                server_id == *completion_server_id,
 6475                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6476            );
 6477            **lsp_completion = resolved_completion;
 6478            *resolved = true;
 6479        }
 6480        Ok(())
 6481    }
 6482
 6483    async fn regenerate_completion_labels(
 6484        adapter: Arc<CachedLspAdapter>,
 6485        snapshot: &BufferSnapshot,
 6486        completions: Rc<RefCell<Box<[Completion]>>>,
 6487        completion_index: usize,
 6488    ) -> Result<()> {
 6489        let completion_item = completions.borrow()[completion_index]
 6490            .source
 6491            .lsp_completion(true)
 6492            .map(Cow::into_owned);
 6493        if let Some(lsp_documentation) = completion_item
 6494            .as_ref()
 6495            .and_then(|completion_item| completion_item.documentation.clone())
 6496        {
 6497            let mut completions = completions.borrow_mut();
 6498            let completion = &mut completions[completion_index];
 6499            completion.documentation = Some(lsp_documentation.into());
 6500        } else {
 6501            let mut completions = completions.borrow_mut();
 6502            let completion = &mut completions[completion_index];
 6503            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6504        }
 6505
 6506        let mut new_label = match completion_item {
 6507            Some(completion_item) => {
 6508                // Some language servers always return `detail` lazily via resolve, regardless of
 6509                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6510                // See: https://github.com/yioneko/vtsls/issues/213
 6511                let language = snapshot.language();
 6512                match language {
 6513                    Some(language) => {
 6514                        adapter
 6515                            .labels_for_completions(
 6516                                std::slice::from_ref(&completion_item),
 6517                                language,
 6518                            )
 6519                            .await?
 6520                    }
 6521                    None => Vec::new(),
 6522                }
 6523                .pop()
 6524                .flatten()
 6525                .unwrap_or_else(|| {
 6526                    CodeLabel::fallback_for_completion(
 6527                        &completion_item,
 6528                        language.map(|language| language.as_ref()),
 6529                    )
 6530                })
 6531            }
 6532            None => CodeLabel::plain(
 6533                completions.borrow()[completion_index].new_text.clone(),
 6534                None,
 6535            ),
 6536        };
 6537        ensure_uniform_list_compatible_label(&mut new_label);
 6538
 6539        let mut completions = completions.borrow_mut();
 6540        let completion = &mut completions[completion_index];
 6541        if completion.label.filter_text() == new_label.filter_text() {
 6542            completion.label = new_label;
 6543        } else {
 6544            log::error!(
 6545                "Resolved completion changed display label from {} to {}. \
 6546                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6547                completion.label.text(),
 6548                new_label.text(),
 6549                completion.label.filter_text(),
 6550                new_label.filter_text()
 6551            );
 6552        }
 6553
 6554        Ok(())
 6555    }
 6556
 6557    async fn resolve_completion_remote(
 6558        project_id: u64,
 6559        server_id: LanguageServerId,
 6560        buffer_id: BufferId,
 6561        completions: Rc<RefCell<Box<[Completion]>>>,
 6562        completion_index: usize,
 6563        client: AnyProtoClient,
 6564    ) -> Result<()> {
 6565        let lsp_completion = {
 6566            let completion = &completions.borrow()[completion_index];
 6567            match &completion.source {
 6568                CompletionSource::Lsp {
 6569                    lsp_completion,
 6570                    resolved,
 6571                    server_id: completion_server_id,
 6572                    ..
 6573                } => {
 6574                    anyhow::ensure!(
 6575                        server_id == *completion_server_id,
 6576                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6577                    );
 6578                    if *resolved {
 6579                        return Ok(());
 6580                    }
 6581                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6582                }
 6583                CompletionSource::Custom
 6584                | CompletionSource::Dap { .. }
 6585                | CompletionSource::BufferWord { .. } => {
 6586                    return Ok(());
 6587                }
 6588            }
 6589        };
 6590        let request = proto::ResolveCompletionDocumentation {
 6591            project_id,
 6592            language_server_id: server_id.0 as u64,
 6593            lsp_completion,
 6594            buffer_id: buffer_id.into(),
 6595        };
 6596
 6597        let response = client
 6598            .request(request)
 6599            .await
 6600            .context("completion documentation resolve proto request")?;
 6601        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6602
 6603        let documentation = if response.documentation.is_empty() {
 6604            CompletionDocumentation::Undocumented
 6605        } else if response.documentation_is_markdown {
 6606            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6607        } else if response.documentation.lines().count() <= 1 {
 6608            CompletionDocumentation::SingleLine(response.documentation.into())
 6609        } else {
 6610            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6611        };
 6612
 6613        let mut completions = completions.borrow_mut();
 6614        let completion = &mut completions[completion_index];
 6615        completion.documentation = Some(documentation);
 6616        if let CompletionSource::Lsp {
 6617            insert_range,
 6618            lsp_completion,
 6619            resolved,
 6620            server_id: completion_server_id,
 6621            lsp_defaults: _,
 6622        } = &mut completion.source
 6623        {
 6624            let completion_insert_range = response
 6625                .old_insert_start
 6626                .and_then(deserialize_anchor)
 6627                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6628            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6629
 6630            if *resolved {
 6631                return Ok(());
 6632            }
 6633            anyhow::ensure!(
 6634                server_id == *completion_server_id,
 6635                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6636            );
 6637            **lsp_completion = resolved_lsp_completion;
 6638            *resolved = true;
 6639        }
 6640
 6641        let replace_range = response
 6642            .old_replace_start
 6643            .and_then(deserialize_anchor)
 6644            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6645        if let Some((old_replace_start, old_replace_end)) = replace_range
 6646            && !response.new_text.is_empty()
 6647        {
 6648            completion.new_text = response.new_text;
 6649            completion.replace_range = old_replace_start..old_replace_end;
 6650        }
 6651
 6652        Ok(())
 6653    }
 6654
 6655    pub fn apply_additional_edits_for_completion(
 6656        &self,
 6657        buffer_handle: Entity<Buffer>,
 6658        completions: Rc<RefCell<Box<[Completion]>>>,
 6659        completion_index: usize,
 6660        push_to_history: bool,
 6661        all_commit_ranges: Vec<Range<language::Anchor>>,
 6662        cx: &mut Context<Self>,
 6663    ) -> Task<Result<Option<Transaction>>> {
 6664        if let Some((client, project_id)) = self.upstream_client() {
 6665            let buffer = buffer_handle.read(cx);
 6666            let buffer_id = buffer.remote_id();
 6667            cx.spawn(async move |_, cx| {
 6668                let request = {
 6669                    let completion = completions.borrow()[completion_index].clone();
 6670                    proto::ApplyCompletionAdditionalEdits {
 6671                        project_id,
 6672                        buffer_id: buffer_id.into(),
 6673                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6674                            replace_range: completion.replace_range,
 6675                            new_text: completion.new_text,
 6676                            source: completion.source,
 6677                        })),
 6678                        all_commit_ranges: all_commit_ranges
 6679                            .iter()
 6680                            .cloned()
 6681                            .map(language::proto::serialize_anchor_range)
 6682                            .collect(),
 6683                    }
 6684                };
 6685
 6686                let Some(transaction) = client.request(request).await?.transaction else {
 6687                    return Ok(None);
 6688                };
 6689
 6690                let transaction = language::proto::deserialize_transaction(transaction)?;
 6691                buffer_handle
 6692                    .update(cx, |buffer, _| {
 6693                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6694                    })
 6695                    .await?;
 6696                if push_to_history {
 6697                    buffer_handle.update(cx, |buffer, _| {
 6698                        buffer.push_transaction(transaction.clone(), Instant::now());
 6699                        buffer.finalize_last_transaction();
 6700                    });
 6701                }
 6702                Ok(Some(transaction))
 6703            })
 6704        } else {
 6705            let request_timeout = ProjectSettings::get_global(cx)
 6706                .global_lsp_settings
 6707                .get_request_timeout();
 6708
 6709            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6710                let completion = &completions.borrow()[completion_index];
 6711                let server_id = completion.source.server_id()?;
 6712                Some(
 6713                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6714                        .1
 6715                        .clone(),
 6716                )
 6717            }) else {
 6718                return Task::ready(Ok(None));
 6719            };
 6720
 6721            cx.spawn(async move |this, cx| {
 6722                Self::resolve_completion_local(
 6723                    server.clone(),
 6724                    completions.clone(),
 6725                    completion_index,
 6726                    request_timeout,
 6727                )
 6728                .await
 6729                .context("resolving completion")?;
 6730                let completion = completions.borrow()[completion_index].clone();
 6731                let additional_text_edits = completion
 6732                    .source
 6733                    .lsp_completion(true)
 6734                    .as_ref()
 6735                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6736                if let Some(edits) = additional_text_edits {
 6737                    let edits = this
 6738                        .update(cx, |this, cx| {
 6739                            this.as_local_mut().unwrap().edits_from_lsp(
 6740                                &buffer_handle,
 6741                                edits,
 6742                                server.server_id(),
 6743                                None,
 6744                                cx,
 6745                            )
 6746                        })?
 6747                        .await?;
 6748
 6749                    buffer_handle.update(cx, |buffer, cx| {
 6750                        buffer.finalize_last_transaction();
 6751                        buffer.start_transaction();
 6752
 6753                        for (range, text) in edits {
 6754                            let primary = &completion.replace_range;
 6755
 6756                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6757                            // and the primary completion is just an insertion (empty range), then this is likely
 6758                            // an auto-import scenario and should not be considered overlapping
 6759                            // https://github.com/zed-industries/zed/issues/26136
 6760                            let is_file_start_auto_import = {
 6761                                let snapshot = buffer.snapshot();
 6762                                let primary_start_point = primary.start.to_point(&snapshot);
 6763                                let range_start_point = range.start.to_point(&snapshot);
 6764
 6765                                let result = primary_start_point.row == 0
 6766                                    && primary_start_point.column == 0
 6767                                    && range_start_point.row == 0
 6768                                    && range_start_point.column == 0;
 6769
 6770                                result
 6771                            };
 6772
 6773                            let has_overlap = if is_file_start_auto_import {
 6774                                false
 6775                            } else {
 6776                                all_commit_ranges.iter().any(|commit_range| {
 6777                                    let start_within =
 6778                                        commit_range.start.cmp(&range.start, buffer).is_le()
 6779                                            && commit_range.end.cmp(&range.start, buffer).is_ge();
 6780                                    let end_within =
 6781                                        range.start.cmp(&commit_range.end, buffer).is_le()
 6782                                            && range.end.cmp(&commit_range.end, buffer).is_ge();
 6783                                    start_within || end_within
 6784                                })
 6785                            };
 6786
 6787                            //Skip additional edits which overlap with the primary completion edit
 6788                            //https://github.com/zed-industries/zed/pull/1871
 6789                            if !has_overlap {
 6790                                buffer.edit([(range, text)], None, cx);
 6791                            }
 6792                        }
 6793
 6794                        let transaction = if buffer.end_transaction(cx).is_some() {
 6795                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6796                            if !push_to_history {
 6797                                buffer.forget_transaction(transaction.id);
 6798                            }
 6799                            Some(transaction)
 6800                        } else {
 6801                            None
 6802                        };
 6803                        Ok(transaction)
 6804                    })
 6805                } else {
 6806                    Ok(None)
 6807                }
 6808            })
 6809        }
 6810    }
 6811
 6812    pub fn pull_diagnostics(
 6813        &mut self,
 6814        buffer: Entity<Buffer>,
 6815        cx: &mut Context<Self>,
 6816    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6817        let buffer_id = buffer.read(cx).remote_id();
 6818
 6819        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6820            let mut suitable_capabilities = None;
 6821            // Are we capable for proto request?
 6822            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6823                &buffer,
 6824                |capabilities| {
 6825                    if let Some(caps) = &capabilities.diagnostic_provider {
 6826                        suitable_capabilities = Some(caps.clone());
 6827                        true
 6828                    } else {
 6829                        false
 6830                    }
 6831                },
 6832                cx,
 6833            );
 6834            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6835            let Some(dynamic_caps) = suitable_capabilities else {
 6836                return Task::ready(Ok(None));
 6837            };
 6838            assert!(any_server_has_diagnostics_provider);
 6839
 6840            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6841            let request = GetDocumentDiagnostics {
 6842                previous_result_id: None,
 6843                identifier,
 6844                registration_id: None,
 6845            };
 6846            let request_timeout = ProjectSettings::get_global(cx)
 6847                .global_lsp_settings
 6848                .get_request_timeout();
 6849            let request_task = client.request_lsp(
 6850                upstream_project_id,
 6851                None,
 6852                request_timeout,
 6853                cx.background_executor().clone(),
 6854                request.to_proto(upstream_project_id, buffer.read(cx)),
 6855            );
 6856            cx.background_spawn(async move {
 6857                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6858                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6859                // Do not attempt to further process the dummy responses here.
 6860                let _response = request_task.await?;
 6861                Ok(None)
 6862            })
 6863        } else {
 6864            let servers = buffer.update(cx, |buffer, cx| {
 6865                self.running_language_servers_for_local_buffer(buffer, cx)
 6866                    .map(|(_, server)| server.clone())
 6867                    .collect::<Vec<_>>()
 6868            });
 6869
 6870            let pull_diagnostics = servers
 6871                .into_iter()
 6872                .flat_map(|server| {
 6873                    let result = maybe!({
 6874                        let local = self.as_local()?;
 6875                        let server_id = server.server_id();
 6876                        let providers_with_identifiers = local
 6877                            .language_server_dynamic_registrations
 6878                            .get(&server_id)
 6879                            .into_iter()
 6880                            .flat_map(|registrations| registrations.diagnostics.clone())
 6881                            .collect::<Vec<_>>();
 6882                        Some(
 6883                            providers_with_identifiers
 6884                                .into_iter()
 6885                                .map(|(registration_id, dynamic_caps)| {
 6886                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6887                                    let registration_id = registration_id.map(SharedString::from);
 6888                                    let result_id = self.result_id_for_buffer_pull(
 6889                                        server_id,
 6890                                        buffer_id,
 6891                                        &registration_id,
 6892                                        cx,
 6893                                    );
 6894                                    self.request_lsp(
 6895                                        buffer.clone(),
 6896                                        LanguageServerToQuery::Other(server_id),
 6897                                        GetDocumentDiagnostics {
 6898                                            previous_result_id: result_id,
 6899                                            registration_id,
 6900                                            identifier,
 6901                                        },
 6902                                        cx,
 6903                                    )
 6904                                })
 6905                                .collect::<Vec<_>>(),
 6906                        )
 6907                    });
 6908
 6909                    result.unwrap_or_default()
 6910                })
 6911                .collect::<Vec<_>>();
 6912
 6913            cx.background_spawn(async move {
 6914                let mut responses = Vec::new();
 6915                for diagnostics in join_all(pull_diagnostics).await {
 6916                    responses.extend(diagnostics?);
 6917                }
 6918                Ok(Some(responses))
 6919            })
 6920        }
 6921    }
 6922
 6923    pub fn applicable_inlay_chunks(
 6924        &mut self,
 6925        buffer: &Entity<Buffer>,
 6926        ranges: &[Range<text::Anchor>],
 6927        cx: &mut Context<Self>,
 6928    ) -> Vec<Range<BufferRow>> {
 6929        let buffer_snapshot = buffer.read(cx).snapshot();
 6930        let ranges = ranges
 6931            .iter()
 6932            .map(|range| range.to_point(&buffer_snapshot))
 6933            .collect::<Vec<_>>();
 6934
 6935        self.latest_lsp_data(buffer, cx)
 6936            .inlay_hints
 6937            .applicable_chunks(ranges.as_slice())
 6938            .map(|chunk| chunk.row_range())
 6939            .collect()
 6940    }
 6941
 6942    pub fn invalidate_inlay_hints<'a>(
 6943        &'a mut self,
 6944        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6945    ) {
 6946        for buffer_id in for_buffers {
 6947            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6948                lsp_data.inlay_hints.clear();
 6949            }
 6950        }
 6951    }
 6952
 6953    pub fn inlay_hints(
 6954        &mut self,
 6955        invalidate: InvalidationStrategy,
 6956        buffer: Entity<Buffer>,
 6957        ranges: Vec<Range<text::Anchor>>,
 6958        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6959        cx: &mut Context<Self>,
 6960    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6961        let next_hint_id = self.next_hint_id.clone();
 6962        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6963        let query_version = lsp_data.buffer_version.clone();
 6964        let mut lsp_refresh_requested = false;
 6965        let for_server = if let InvalidationStrategy::RefreshRequested {
 6966            server_id,
 6967            request_id,
 6968        } = invalidate
 6969        {
 6970            let invalidated = lsp_data
 6971                .inlay_hints
 6972                .invalidate_for_server_refresh(server_id, request_id);
 6973            lsp_refresh_requested = invalidated;
 6974            Some(server_id)
 6975        } else {
 6976            None
 6977        };
 6978        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6979        let known_chunks = known_chunks
 6980            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6981            .map(|(_, known_chunks)| known_chunks)
 6982            .unwrap_or_default();
 6983
 6984        let buffer_snapshot = buffer.read(cx).snapshot();
 6985        let ranges = ranges
 6986            .iter()
 6987            .map(|range| range.to_point(&buffer_snapshot))
 6988            .collect::<Vec<_>>();
 6989
 6990        let mut hint_fetch_tasks = Vec::new();
 6991        let mut cached_inlay_hints = None;
 6992        let mut ranges_to_query = None;
 6993        let applicable_chunks = existing_inlay_hints
 6994            .applicable_chunks(ranges.as_slice())
 6995            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 6996            .collect::<Vec<_>>();
 6997        if applicable_chunks.is_empty() {
 6998            return HashMap::default();
 6999        }
 7000
 7001        for row_chunk in applicable_chunks {
 7002            match (
 7003                existing_inlay_hints
 7004                    .cached_hints(&row_chunk)
 7005                    .filter(|_| !lsp_refresh_requested)
 7006                    .cloned(),
 7007                existing_inlay_hints
 7008                    .fetched_hints(&row_chunk)
 7009                    .as_ref()
 7010                    .filter(|_| !lsp_refresh_requested)
 7011                    .cloned(),
 7012            ) {
 7013                (None, None) => {
 7014                    let chunk_range = row_chunk.anchor_range();
 7015                    ranges_to_query
 7016                        .get_or_insert_with(Vec::new)
 7017                        .push((row_chunk, chunk_range));
 7018                }
 7019                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7020                (Some(cached_hints), None) => {
 7021                    for (server_id, cached_hints) in cached_hints {
 7022                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7023                            cached_inlay_hints
 7024                                .get_or_insert_with(HashMap::default)
 7025                                .entry(row_chunk.row_range())
 7026                                .or_insert_with(HashMap::default)
 7027                                .entry(server_id)
 7028                                .or_insert_with(Vec::new)
 7029                                .extend(cached_hints);
 7030                        }
 7031                    }
 7032                }
 7033                (Some(cached_hints), Some(fetched_hints)) => {
 7034                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7035                    for (server_id, cached_hints) in cached_hints {
 7036                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7037                            cached_inlay_hints
 7038                                .get_or_insert_with(HashMap::default)
 7039                                .entry(row_chunk.row_range())
 7040                                .or_insert_with(HashMap::default)
 7041                                .entry(server_id)
 7042                                .or_insert_with(Vec::new)
 7043                                .extend(cached_hints);
 7044                        }
 7045                    }
 7046                }
 7047            }
 7048        }
 7049
 7050        if hint_fetch_tasks.is_empty()
 7051            && ranges_to_query
 7052                .as_ref()
 7053                .is_none_or(|ranges| ranges.is_empty())
 7054            && let Some(cached_inlay_hints) = cached_inlay_hints
 7055        {
 7056            cached_inlay_hints
 7057                .into_iter()
 7058                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7059                .collect()
 7060        } else {
 7061            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7062                // When a server refresh was requested, other servers' cached hints
 7063                // are unaffected by the refresh and must be included in the result.
 7064                // Otherwise apply_fetched_hints (with should_invalidate()=true)
 7065                // removes all visible hints but only adds back the requesting
 7066                // server's new hints, permanently losing other servers' hints.
 7067                let other_servers_cached: CacheInlayHints = if lsp_refresh_requested {
 7068                    lsp_data
 7069                        .inlay_hints
 7070                        .cached_hints(&chunk)
 7071                        .cloned()
 7072                        .unwrap_or_default()
 7073                } else {
 7074                    HashMap::default()
 7075                };
 7076
 7077                let next_hint_id = next_hint_id.clone();
 7078                let buffer = buffer.clone();
 7079                let query_version = query_version.clone();
 7080                let new_inlay_hints = cx
 7081                    .spawn(async move |lsp_store, cx| {
 7082                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7083                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7084                        })?;
 7085                        new_fetch_task
 7086                            .await
 7087                            .and_then(|new_hints_by_server| {
 7088                                lsp_store.update(cx, |lsp_store, cx| {
 7089                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7090                                    let update_cache = lsp_data.buffer_version == query_version;
 7091                                    if new_hints_by_server.is_empty() {
 7092                                        if update_cache {
 7093                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7094                                        }
 7095                                        other_servers_cached
 7096                                    } else {
 7097                                        let mut result = other_servers_cached;
 7098                                        for (server_id, new_hints) in new_hints_by_server {
 7099                                            let new_hints = new_hints
 7100                                                .into_iter()
 7101                                                .map(|new_hint| {
 7102                                                    (
 7103                                                        InlayId::Hint(next_hint_id.fetch_add(
 7104                                                            1,
 7105                                                            atomic::Ordering::AcqRel,
 7106                                                        )),
 7107                                                        new_hint,
 7108                                                    )
 7109                                                })
 7110                                                .collect::<Vec<_>>();
 7111                                            if update_cache {
 7112                                                lsp_data.inlay_hints.insert_new_hints(
 7113                                                    chunk,
 7114                                                    server_id,
 7115                                                    new_hints.clone(),
 7116                                                );
 7117                                            }
 7118                                            result.insert(server_id, new_hints);
 7119                                        }
 7120                                        result
 7121                                    }
 7122                                })
 7123                            })
 7124                            .map_err(Arc::new)
 7125                    })
 7126                    .shared();
 7127
 7128                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7129                *fetch_task = Some(new_inlay_hints.clone());
 7130                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7131            }
 7132
 7133            cached_inlay_hints
 7134                .unwrap_or_default()
 7135                .into_iter()
 7136                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7137                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7138                    (
 7139                        chunk.row_range(),
 7140                        cx.spawn(async move |_, _| {
 7141                            hints_fetch.await.map_err(|e| {
 7142                                if e.error_code() != ErrorCode::Internal {
 7143                                    anyhow!(e.error_code())
 7144                                } else {
 7145                                    anyhow!("{e:#}")
 7146                                }
 7147                            })
 7148                        }),
 7149                    )
 7150                }))
 7151                .collect()
 7152        }
 7153    }
 7154
 7155    fn fetch_inlay_hints(
 7156        &mut self,
 7157        for_server: Option<LanguageServerId>,
 7158        buffer: &Entity<Buffer>,
 7159        range: Range<Anchor>,
 7160        cx: &mut Context<Self>,
 7161    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7162        let request = InlayHints {
 7163            range: range.clone(),
 7164        };
 7165        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7166            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7167                return Task::ready(Ok(HashMap::default()));
 7168            }
 7169            let request_timeout = ProjectSettings::get_global(cx)
 7170                .global_lsp_settings
 7171                .get_request_timeout();
 7172            let request_task = upstream_client.request_lsp(
 7173                project_id,
 7174                for_server.map(|id| id.to_proto()),
 7175                request_timeout,
 7176                cx.background_executor().clone(),
 7177                request.to_proto(project_id, buffer.read(cx)),
 7178            );
 7179            let buffer = buffer.clone();
 7180            cx.spawn(async move |weak_lsp_store, cx| {
 7181                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7182                    return Ok(HashMap::default());
 7183                };
 7184                let Some(responses) = request_task.await? else {
 7185                    return Ok(HashMap::default());
 7186                };
 7187
 7188                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7189                    let lsp_store = lsp_store.clone();
 7190                    let buffer = buffer.clone();
 7191                    let cx = cx.clone();
 7192                    let request = request.clone();
 7193                    async move {
 7194                        (
 7195                            LanguageServerId::from_proto(response.server_id),
 7196                            request
 7197                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7198                                .await,
 7199                        )
 7200                    }
 7201                }))
 7202                .await;
 7203
 7204                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7205                let mut has_errors = false;
 7206                let inlay_hints = inlay_hints
 7207                    .into_iter()
 7208                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7209                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7210                        Err(e) => {
 7211                            has_errors = true;
 7212                            log::error!("{e:#}");
 7213                            None
 7214                        }
 7215                    })
 7216                    .map(|(server_id, mut new_hints)| {
 7217                        new_hints.retain(|hint| {
 7218                            hint.position.is_valid(&buffer_snapshot)
 7219                                && range.start.is_valid(&buffer_snapshot)
 7220                                && range.end.is_valid(&buffer_snapshot)
 7221                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7222                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7223                        });
 7224                        (server_id, new_hints)
 7225                    })
 7226                    .collect::<HashMap<_, _>>();
 7227                anyhow::ensure!(
 7228                    !has_errors || !inlay_hints.is_empty(),
 7229                    "Failed to fetch inlay hints"
 7230                );
 7231                Ok(inlay_hints)
 7232            })
 7233        } else {
 7234            let inlay_hints_task = match for_server {
 7235                Some(server_id) => {
 7236                    let server_task = self.request_lsp(
 7237                        buffer.clone(),
 7238                        LanguageServerToQuery::Other(server_id),
 7239                        request,
 7240                        cx,
 7241                    );
 7242                    cx.background_spawn(async move {
 7243                        let mut responses = Vec::new();
 7244                        match server_task.await {
 7245                            Ok(response) => responses.push((server_id, response)),
 7246                            // rust-analyzer likes to error with this when its still loading up
 7247                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7248                            Err(e) => log::error!(
 7249                                "Error handling response for inlay hints request: {e:#}"
 7250                            ),
 7251                        }
 7252                        responses
 7253                    })
 7254                }
 7255                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7256            };
 7257            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7258            cx.background_spawn(async move {
 7259                Ok(inlay_hints_task
 7260                    .await
 7261                    .into_iter()
 7262                    .map(|(server_id, mut new_hints)| {
 7263                        new_hints.retain(|hint| {
 7264                            hint.position.is_valid(&buffer_snapshot)
 7265                                && range.start.is_valid(&buffer_snapshot)
 7266                                && range.end.is_valid(&buffer_snapshot)
 7267                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7268                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7269                        });
 7270                        (server_id, new_hints)
 7271                    })
 7272                    .collect())
 7273            })
 7274        }
 7275    }
 7276
 7277    fn diagnostic_registration_exists(
 7278        &self,
 7279        server_id: LanguageServerId,
 7280        registration_id: &Option<SharedString>,
 7281    ) -> bool {
 7282        let Some(local) = self.as_local() else {
 7283            return false;
 7284        };
 7285        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7286        else {
 7287            return false;
 7288        };
 7289        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7290        registrations.diagnostics.contains_key(&registration_key)
 7291    }
 7292
 7293    pub fn pull_diagnostics_for_buffer(
 7294        &mut self,
 7295        buffer: Entity<Buffer>,
 7296        cx: &mut Context<Self>,
 7297    ) -> Task<anyhow::Result<()>> {
 7298        let diagnostics = self.pull_diagnostics(buffer, cx);
 7299        cx.spawn(async move |lsp_store, cx| {
 7300            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7301                return Ok(());
 7302            };
 7303            lsp_store.update(cx, |lsp_store, cx| {
 7304                if lsp_store.as_local().is_none() {
 7305                    return;
 7306                }
 7307
 7308                let mut unchanged_buffers = HashMap::default();
 7309                let server_diagnostics_updates = diagnostics
 7310                    .into_iter()
 7311                    .filter_map(|diagnostics_set| match diagnostics_set {
 7312                        LspPullDiagnostics::Response {
 7313                            server_id,
 7314                            uri,
 7315                            diagnostics,
 7316                            registration_id,
 7317                        } => Some((server_id, uri, diagnostics, registration_id)),
 7318                        LspPullDiagnostics::Default => None,
 7319                    })
 7320                    .filter(|(server_id, _, _, registration_id)| {
 7321                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7322                    })
 7323                    .fold(
 7324                        HashMap::default(),
 7325                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7326                            let (result_id, diagnostics) = match diagnostics {
 7327                                PulledDiagnostics::Unchanged { result_id } => {
 7328                                    unchanged_buffers
 7329                                        .entry(new_registration_id.clone())
 7330                                        .or_insert_with(HashSet::default)
 7331                                        .insert(uri.clone());
 7332                                    (Some(result_id), Vec::new())
 7333                                }
 7334                                PulledDiagnostics::Changed {
 7335                                    result_id,
 7336                                    diagnostics,
 7337                                } => (result_id, diagnostics),
 7338                            };
 7339                            let disk_based_sources = Cow::Owned(
 7340                                lsp_store
 7341                                    .language_server_adapter_for_id(server_id)
 7342                                    .as_ref()
 7343                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7344                                    .unwrap_or(&[])
 7345                                    .to_vec(),
 7346                            );
 7347                            acc.entry(server_id)
 7348                                .or_insert_with(HashMap::default)
 7349                                .entry(new_registration_id.clone())
 7350                                .or_insert_with(Vec::new)
 7351                                .push(DocumentDiagnosticsUpdate {
 7352                                    server_id,
 7353                                    diagnostics: lsp::PublishDiagnosticsParams {
 7354                                        uri,
 7355                                        diagnostics,
 7356                                        version: None,
 7357                                    },
 7358                                    result_id: result_id.map(SharedString::new),
 7359                                    disk_based_sources,
 7360                                    registration_id: new_registration_id,
 7361                                });
 7362                            acc
 7363                        },
 7364                    );
 7365
 7366                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7367                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7368                        lsp_store
 7369                            .merge_lsp_diagnostics(
 7370                                DiagnosticSourceKind::Pulled,
 7371                                diagnostic_updates,
 7372                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7373                                    DiagnosticSourceKind::Pulled => {
 7374                                        old_diagnostic.registration_id != registration_id
 7375                                            || unchanged_buffers
 7376                                                .get(&old_diagnostic.registration_id)
 7377                                                .is_some_and(|unchanged_buffers| {
 7378                                                    unchanged_buffers.contains(&document_uri)
 7379                                                })
 7380                                    }
 7381                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7382                                        true
 7383                                    }
 7384                                },
 7385                                cx,
 7386                            )
 7387                            .log_err();
 7388                    }
 7389                }
 7390            })
 7391        })
 7392    }
 7393
 7394    pub fn signature_help<T: ToPointUtf16>(
 7395        &mut self,
 7396        buffer: &Entity<Buffer>,
 7397        position: T,
 7398        cx: &mut Context<Self>,
 7399    ) -> Task<Option<Vec<SignatureHelp>>> {
 7400        let position = position.to_point_utf16(buffer.read(cx));
 7401
 7402        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7403            let request = GetSignatureHelp { position };
 7404            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7405                return Task::ready(None);
 7406            }
 7407            let request_timeout = ProjectSettings::get_global(cx)
 7408                .global_lsp_settings
 7409                .get_request_timeout();
 7410            let request_task = client.request_lsp(
 7411                upstream_project_id,
 7412                None,
 7413                request_timeout,
 7414                cx.background_executor().clone(),
 7415                request.to_proto(upstream_project_id, buffer.read(cx)),
 7416            );
 7417            let buffer = buffer.clone();
 7418            cx.spawn(async move |weak_lsp_store, cx| {
 7419                let lsp_store = weak_lsp_store.upgrade()?;
 7420                let signatures = join_all(
 7421                    request_task
 7422                        .await
 7423                        .log_err()
 7424                        .flatten()
 7425                        .map(|response| response.payload)
 7426                        .unwrap_or_default()
 7427                        .into_iter()
 7428                        .map(|response| {
 7429                            let response = GetSignatureHelp { position }.response_from_proto(
 7430                                response.response,
 7431                                lsp_store.clone(),
 7432                                buffer.clone(),
 7433                                cx.clone(),
 7434                            );
 7435                            async move { response.await.log_err().flatten() }
 7436                        }),
 7437                )
 7438                .await
 7439                .into_iter()
 7440                .flatten()
 7441                .collect();
 7442                Some(signatures)
 7443            })
 7444        } else {
 7445            let all_actions_task = self.request_multiple_lsp_locally(
 7446                buffer,
 7447                Some(position),
 7448                GetSignatureHelp { position },
 7449                cx,
 7450            );
 7451            cx.background_spawn(async move {
 7452                Some(
 7453                    all_actions_task
 7454                        .await
 7455                        .into_iter()
 7456                        .flat_map(|(_, actions)| actions)
 7457                        .collect::<Vec<_>>(),
 7458                )
 7459            })
 7460        }
 7461    }
 7462
 7463    pub fn hover(
 7464        &mut self,
 7465        buffer: &Entity<Buffer>,
 7466        position: PointUtf16,
 7467        cx: &mut Context<Self>,
 7468    ) -> Task<Option<Vec<Hover>>> {
 7469        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7470            let request = GetHover { position };
 7471            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7472                return Task::ready(None);
 7473            }
 7474            let request_timeout = ProjectSettings::get_global(cx)
 7475                .global_lsp_settings
 7476                .get_request_timeout();
 7477            let request_task = client.request_lsp(
 7478                upstream_project_id,
 7479                None,
 7480                request_timeout,
 7481                cx.background_executor().clone(),
 7482                request.to_proto(upstream_project_id, buffer.read(cx)),
 7483            );
 7484            let buffer = buffer.clone();
 7485            cx.spawn(async move |weak_lsp_store, cx| {
 7486                let lsp_store = weak_lsp_store.upgrade()?;
 7487                let hovers = join_all(
 7488                    request_task
 7489                        .await
 7490                        .log_err()
 7491                        .flatten()
 7492                        .map(|response| response.payload)
 7493                        .unwrap_or_default()
 7494                        .into_iter()
 7495                        .map(|response| {
 7496                            let response = GetHover { position }.response_from_proto(
 7497                                response.response,
 7498                                lsp_store.clone(),
 7499                                buffer.clone(),
 7500                                cx.clone(),
 7501                            );
 7502                            async move {
 7503                                response
 7504                                    .await
 7505                                    .log_err()
 7506                                    .flatten()
 7507                                    .and_then(remove_empty_hover_blocks)
 7508                            }
 7509                        }),
 7510                )
 7511                .await
 7512                .into_iter()
 7513                .flatten()
 7514                .collect();
 7515                Some(hovers)
 7516            })
 7517        } else {
 7518            let all_actions_task = self.request_multiple_lsp_locally(
 7519                buffer,
 7520                Some(position),
 7521                GetHover { position },
 7522                cx,
 7523            );
 7524            cx.background_spawn(async move {
 7525                Some(
 7526                    all_actions_task
 7527                        .await
 7528                        .into_iter()
 7529                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7530                        .collect::<Vec<Hover>>(),
 7531                )
 7532            })
 7533        }
 7534    }
 7535
 7536    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7537        let language_registry = self.languages.clone();
 7538
 7539        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7540            let request = upstream_client.request(proto::GetProjectSymbols {
 7541                project_id: *project_id,
 7542                query: query.to_string(),
 7543            });
 7544            cx.foreground_executor().spawn(async move {
 7545                let response = request.await?;
 7546                let mut symbols = Vec::new();
 7547                let core_symbols = response
 7548                    .symbols
 7549                    .into_iter()
 7550                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7551                    .collect::<Vec<_>>();
 7552                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7553                    .await;
 7554                Ok(symbols)
 7555            })
 7556        } else if let Some(local) = self.as_local() {
 7557            struct WorkspaceSymbolsResult {
 7558                server_id: LanguageServerId,
 7559                lsp_adapter: Arc<CachedLspAdapter>,
 7560                worktree: WeakEntity<Worktree>,
 7561                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7562            }
 7563
 7564            let mut requests = Vec::new();
 7565            let mut requested_servers = BTreeSet::new();
 7566            let request_timeout = ProjectSettings::get_global(cx)
 7567                .global_lsp_settings
 7568                .get_request_timeout();
 7569
 7570            for (seed, state) in local.language_server_ids.iter() {
 7571                let Some(worktree_handle) = self
 7572                    .worktree_store
 7573                    .read(cx)
 7574                    .worktree_for_id(seed.worktree_id, cx)
 7575                else {
 7576                    continue;
 7577                };
 7578
 7579                let worktree = worktree_handle.read(cx);
 7580                if !worktree.is_visible() {
 7581                    continue;
 7582                }
 7583
 7584                if !requested_servers.insert(state.id) {
 7585                    continue;
 7586                }
 7587
 7588                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7589                    Some(LanguageServerState::Running {
 7590                        adapter, server, ..
 7591                    }) => (adapter.clone(), server),
 7592
 7593                    _ => continue,
 7594                };
 7595
 7596                let supports_workspace_symbol_request =
 7597                    match server.capabilities().workspace_symbol_provider {
 7598                        Some(OneOf::Left(supported)) => supported,
 7599                        Some(OneOf::Right(_)) => true,
 7600                        None => false,
 7601                    };
 7602
 7603                if !supports_workspace_symbol_request {
 7604                    continue;
 7605                }
 7606
 7607                let worktree_handle = worktree_handle.clone();
 7608                let server_id = server.server_id();
 7609                requests.push(
 7610                    server
 7611                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7612                            lsp::WorkspaceSymbolParams {
 7613                                query: query.to_string(),
 7614                                ..Default::default()
 7615                            },
 7616                            request_timeout,
 7617                        )
 7618                        .map(move |response| {
 7619                            let lsp_symbols = response
 7620                                .into_response()
 7621                                .context("workspace symbols request")
 7622                                .log_err()
 7623                                .flatten()
 7624                                .map(|symbol_response| match symbol_response {
 7625                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7626                                        flat_responses
 7627                                            .into_iter()
 7628                                            .map(|lsp_symbol| {
 7629                                                (
 7630                                                    lsp_symbol.name,
 7631                                                    lsp_symbol.kind,
 7632                                                    lsp_symbol.location,
 7633                                                    lsp_symbol.container_name,
 7634                                                )
 7635                                            })
 7636                                            .collect::<Vec<_>>()
 7637                                    }
 7638                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7639                                        nested_responses
 7640                                            .into_iter()
 7641                                            .filter_map(|lsp_symbol| {
 7642                                                let location = match lsp_symbol.location {
 7643                                                    OneOf::Left(location) => location,
 7644                                                    OneOf::Right(_) => {
 7645                                                        log::error!(
 7646                                                            "Unexpected: client capabilities \
 7647                                                            forbid symbol resolutions in \
 7648                                                            workspace.symbol.resolveSupport"
 7649                                                        );
 7650                                                        return None;
 7651                                                    }
 7652                                                };
 7653                                                Some((
 7654                                                    lsp_symbol.name,
 7655                                                    lsp_symbol.kind,
 7656                                                    location,
 7657                                                    lsp_symbol.container_name,
 7658                                                ))
 7659                                            })
 7660                                            .collect::<Vec<_>>()
 7661                                    }
 7662                                })
 7663                                .unwrap_or_default();
 7664
 7665                            WorkspaceSymbolsResult {
 7666                                server_id,
 7667                                lsp_adapter,
 7668                                worktree: worktree_handle.downgrade(),
 7669                                lsp_symbols,
 7670                            }
 7671                        }),
 7672                );
 7673            }
 7674
 7675            cx.spawn(async move |this, cx| {
 7676                let responses = futures::future::join_all(requests).await;
 7677                let this = match this.upgrade() {
 7678                    Some(this) => this,
 7679                    None => return Ok(Vec::new()),
 7680                };
 7681
 7682                let mut symbols = Vec::new();
 7683                for result in responses {
 7684                    let core_symbols = this.update(cx, |this, cx| {
 7685                        result
 7686                            .lsp_symbols
 7687                            .into_iter()
 7688                            .filter_map(
 7689                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7690                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7691                                    let source_worktree = result.worktree.upgrade()?;
 7692                                    let source_worktree_id = source_worktree.read(cx).id();
 7693
 7694                                    let path = if let Some((tree, rel_path)) =
 7695                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7696                                    {
 7697                                        let worktree_id = tree.read(cx).id();
 7698                                        SymbolLocation::InProject(ProjectPath {
 7699                                            worktree_id,
 7700                                            path: rel_path,
 7701                                        })
 7702                                    } else {
 7703                                        SymbolLocation::OutsideProject {
 7704                                            signature: this.symbol_signature(&abs_path),
 7705                                            abs_path: abs_path.into(),
 7706                                        }
 7707                                    };
 7708
 7709                                    Some(CoreSymbol {
 7710                                        source_language_server_id: result.server_id,
 7711                                        language_server_name: result.lsp_adapter.name.clone(),
 7712                                        source_worktree_id,
 7713                                        path,
 7714                                        kind: symbol_kind,
 7715                                        name: collapse_newlines(&symbol_name, ""),
 7716                                        range: range_from_lsp(symbol_location.range),
 7717                                        container_name: container_name
 7718                                            .map(|c| collapse_newlines(&c, "")),
 7719                                    })
 7720                                },
 7721                            )
 7722                            .collect::<Vec<_>>()
 7723                    });
 7724
 7725                    populate_labels_for_symbols(
 7726                        core_symbols,
 7727                        &language_registry,
 7728                        Some(result.lsp_adapter),
 7729                        &mut symbols,
 7730                    )
 7731                    .await;
 7732                }
 7733
 7734                Ok(symbols)
 7735            })
 7736        } else {
 7737            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7738        }
 7739    }
 7740
 7741    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7742        let mut summary = DiagnosticSummary::default();
 7743        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7744            summary.error_count += path_summary.error_count;
 7745            summary.warning_count += path_summary.warning_count;
 7746        }
 7747        summary
 7748    }
 7749
 7750    /// Returns the diagnostic summary for a specific project path.
 7751    pub fn diagnostic_summary_for_path(
 7752        &self,
 7753        project_path: &ProjectPath,
 7754        _: &App,
 7755    ) -> DiagnosticSummary {
 7756        if let Some(summaries) = self
 7757            .diagnostic_summaries
 7758            .get(&project_path.worktree_id)
 7759            .and_then(|map| map.get(&project_path.path))
 7760        {
 7761            let (error_count, warning_count) = summaries.iter().fold(
 7762                (0, 0),
 7763                |(error_count, warning_count), (_language_server_id, summary)| {
 7764                    (
 7765                        error_count + summary.error_count,
 7766                        warning_count + summary.warning_count,
 7767                    )
 7768                },
 7769            );
 7770
 7771            DiagnosticSummary {
 7772                error_count,
 7773                warning_count,
 7774            }
 7775        } else {
 7776            DiagnosticSummary::default()
 7777        }
 7778    }
 7779
 7780    pub fn diagnostic_summaries<'a>(
 7781        &'a self,
 7782        include_ignored: bool,
 7783        cx: &'a App,
 7784    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7785        self.worktree_store
 7786            .read(cx)
 7787            .visible_worktrees(cx)
 7788            .filter_map(|worktree| {
 7789                let worktree = worktree.read(cx);
 7790                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7791            })
 7792            .flat_map(move |(worktree, summaries)| {
 7793                let worktree_id = worktree.id();
 7794                summaries
 7795                    .iter()
 7796                    .filter(move |(path, _)| {
 7797                        include_ignored
 7798                            || worktree
 7799                                .entry_for_path(path.as_ref())
 7800                                .is_some_and(|entry| !entry.is_ignored)
 7801                    })
 7802                    .flat_map(move |(path, summaries)| {
 7803                        summaries.iter().map(move |(server_id, summary)| {
 7804                            (
 7805                                ProjectPath {
 7806                                    worktree_id,
 7807                                    path: path.clone(),
 7808                                },
 7809                                *server_id,
 7810                                *summary,
 7811                            )
 7812                        })
 7813                    })
 7814            })
 7815    }
 7816
 7817    pub fn on_buffer_edited(
 7818        &mut self,
 7819        buffer: Entity<Buffer>,
 7820        cx: &mut Context<Self>,
 7821    ) -> Option<()> {
 7822        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7823            Some(
 7824                self.as_local()?
 7825                    .language_servers_for_buffer(buffer, cx)
 7826                    .map(|i| i.1.clone())
 7827                    .collect(),
 7828            )
 7829        })?;
 7830
 7831        let buffer = buffer.read(cx);
 7832        let file = File::from_dyn(buffer.file())?;
 7833        let abs_path = file.as_local()?.abs_path(cx);
 7834        let uri = lsp::Uri::from_file_path(&abs_path)
 7835            .ok()
 7836            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7837            .log_err()?;
 7838        let next_snapshot = buffer.text_snapshot();
 7839        for language_server in language_servers {
 7840            let language_server = language_server.clone();
 7841
 7842            let buffer_snapshots = self
 7843                .as_local_mut()?
 7844                .buffer_snapshots
 7845                .get_mut(&buffer.remote_id())
 7846                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7847            let previous_snapshot = buffer_snapshots.last()?;
 7848
 7849            let build_incremental_change = || {
 7850                buffer
 7851                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7852                        previous_snapshot.snapshot.version(),
 7853                    )
 7854                    .map(|edit| {
 7855                        let edit_start = edit.new.start.0;
 7856                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7857                        let new_text = next_snapshot
 7858                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7859                            .collect();
 7860                        lsp::TextDocumentContentChangeEvent {
 7861                            range: Some(lsp::Range::new(
 7862                                point_to_lsp(edit_start),
 7863                                point_to_lsp(edit_end),
 7864                            )),
 7865                            range_length: None,
 7866                            text: new_text,
 7867                        }
 7868                    })
 7869                    .collect()
 7870            };
 7871
 7872            let document_sync_kind = language_server
 7873                .capabilities()
 7874                .text_document_sync
 7875                .as_ref()
 7876                .and_then(|sync| match sync {
 7877                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7878                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7879                });
 7880
 7881            let content_changes: Vec<_> = match document_sync_kind {
 7882                Some(lsp::TextDocumentSyncKind::FULL) => {
 7883                    vec![lsp::TextDocumentContentChangeEvent {
 7884                        range: None,
 7885                        range_length: None,
 7886                        text: next_snapshot.text(),
 7887                    }]
 7888                }
 7889                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7890                _ => {
 7891                    #[cfg(any(test, feature = "test-support"))]
 7892                    {
 7893                        build_incremental_change()
 7894                    }
 7895
 7896                    #[cfg(not(any(test, feature = "test-support")))]
 7897                    {
 7898                        continue;
 7899                    }
 7900                }
 7901            };
 7902
 7903            let next_version = previous_snapshot.version + 1;
 7904            buffer_snapshots.push(LspBufferSnapshot {
 7905                version: next_version,
 7906                snapshot: next_snapshot.clone(),
 7907            });
 7908
 7909            language_server
 7910                .notify::<lsp::notification::DidChangeTextDocument>(
 7911                    lsp::DidChangeTextDocumentParams {
 7912                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7913                            uri.clone(),
 7914                            next_version,
 7915                        ),
 7916                        content_changes,
 7917                    },
 7918                )
 7919                .ok();
 7920            self.pull_workspace_diagnostics(language_server.server_id());
 7921        }
 7922
 7923        None
 7924    }
 7925
 7926    pub fn on_buffer_saved(
 7927        &mut self,
 7928        buffer: Entity<Buffer>,
 7929        cx: &mut Context<Self>,
 7930    ) -> Option<()> {
 7931        let file = File::from_dyn(buffer.read(cx).file())?;
 7932        let worktree_id = file.worktree_id(cx);
 7933        let abs_path = file.as_local()?.abs_path(cx);
 7934        let text_document = lsp::TextDocumentIdentifier {
 7935            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7936        };
 7937        let local = self.as_local()?;
 7938
 7939        for server in local.language_servers_for_worktree(worktree_id) {
 7940            if let Some(include_text) = include_text(server.as_ref()) {
 7941                let text = if include_text {
 7942                    Some(buffer.read(cx).text())
 7943                } else {
 7944                    None
 7945                };
 7946                server
 7947                    .notify::<lsp::notification::DidSaveTextDocument>(
 7948                        lsp::DidSaveTextDocumentParams {
 7949                            text_document: text_document.clone(),
 7950                            text,
 7951                        },
 7952                    )
 7953                    .ok();
 7954            }
 7955        }
 7956
 7957        let language_servers = buffer.update(cx, |buffer, cx| {
 7958            local.language_server_ids_for_buffer(buffer, cx)
 7959        });
 7960        for language_server_id in language_servers {
 7961            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7962        }
 7963
 7964        None
 7965    }
 7966
 7967    fn on_buffer_reloaded(&mut self, buffer: Entity<Buffer>, cx: &mut Context<Self>) {
 7968        let buffer_id = buffer.read(cx).remote_id();
 7969        let task = self.pull_diagnostics_for_buffer(buffer, cx);
 7970        self.buffer_reload_tasks.insert(buffer_id, task);
 7971    }
 7972
 7973    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7974        maybe!(async move {
 7975            let mut refreshed_servers = HashSet::default();
 7976            let servers = lsp_store
 7977                .update(cx, |lsp_store, cx| {
 7978                    let local = lsp_store.as_local()?;
 7979
 7980                    let servers = local
 7981                        .language_server_ids
 7982                        .iter()
 7983                        .filter_map(|(seed, state)| {
 7984                            let worktree = lsp_store
 7985                                .worktree_store
 7986                                .read(cx)
 7987                                .worktree_for_id(seed.worktree_id, cx);
 7988                            let delegate: Arc<dyn LspAdapterDelegate> =
 7989                                worktree.map(|worktree| {
 7990                                    LocalLspAdapterDelegate::new(
 7991                                        local.languages.clone(),
 7992                                        &local.environment,
 7993                                        cx.weak_entity(),
 7994                                        &worktree,
 7995                                        local.http_client.clone(),
 7996                                        local.fs.clone(),
 7997                                        cx,
 7998                                    )
 7999                                })?;
 8000                            let server_id = state.id;
 8001
 8002                            let states = local.language_servers.get(&server_id)?;
 8003
 8004                            match states {
 8005                                LanguageServerState::Starting { .. } => None,
 8006                                LanguageServerState::Running {
 8007                                    adapter, server, ..
 8008                                } => {
 8009                                    let adapter = adapter.clone();
 8010                                    let server = server.clone();
 8011                                    refreshed_servers.insert(server.name());
 8012                                    let toolchain = seed.toolchain.clone();
 8013                                    Some(cx.spawn(async move |_, cx| {
 8014                                        let settings =
 8015                                            LocalLspStore::workspace_configuration_for_adapter(
 8016                                                adapter.adapter.clone(),
 8017                                                &delegate,
 8018                                                toolchain,
 8019                                                None,
 8020                                                cx,
 8021                                            )
 8022                                            .await
 8023                                            .ok()?;
 8024                                        server
 8025                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8026                                                lsp::DidChangeConfigurationParams { settings },
 8027                                            )
 8028                                            .ok()?;
 8029                                        Some(())
 8030                                    }))
 8031                                }
 8032                            }
 8033                        })
 8034                        .collect::<Vec<_>>();
 8035
 8036                    Some(servers)
 8037                })
 8038                .ok()
 8039                .flatten()?;
 8040
 8041            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8042            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8043            // to stop and unregister its language server wrapper.
 8044            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8045            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8046            let _: Vec<Option<()>> = join_all(servers).await;
 8047
 8048            Some(())
 8049        })
 8050        .await;
 8051    }
 8052
 8053    fn maintain_workspace_config(
 8054        external_refresh_requests: watch::Receiver<()>,
 8055        cx: &mut Context<Self>,
 8056    ) -> Task<Result<()>> {
 8057        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8058        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8059
 8060        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8061            *settings_changed_tx.borrow_mut() = ();
 8062        });
 8063
 8064        let mut joint_future =
 8065            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8066        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8067        // - 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).
 8068        // - 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.
 8069        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8070        // - 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,
 8071        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8072        cx.spawn(async move |this, cx| {
 8073            while let Some(()) = joint_future.next().await {
 8074                this.update(cx, |this, cx| {
 8075                    this.refresh_server_tree(cx);
 8076                })
 8077                .ok();
 8078
 8079                Self::refresh_workspace_configurations(&this, cx).await;
 8080            }
 8081
 8082            drop(settings_observation);
 8083            anyhow::Ok(())
 8084        })
 8085    }
 8086
 8087    pub fn running_language_servers_for_local_buffer<'a>(
 8088        &'a self,
 8089        buffer: &Buffer,
 8090        cx: &mut App,
 8091    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8092        let local = self.as_local();
 8093        let language_server_ids = local
 8094            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8095            .unwrap_or_default();
 8096
 8097        language_server_ids
 8098            .into_iter()
 8099            .filter_map(
 8100                move |server_id| match local?.language_servers.get(&server_id)? {
 8101                    LanguageServerState::Running {
 8102                        adapter, server, ..
 8103                    } => Some((adapter, server)),
 8104                    _ => None,
 8105                },
 8106            )
 8107    }
 8108
 8109    pub fn language_servers_for_local_buffer(
 8110        &self,
 8111        buffer: &Buffer,
 8112        cx: &mut App,
 8113    ) -> Vec<LanguageServerId> {
 8114        let local = self.as_local();
 8115        local
 8116            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8117            .unwrap_or_default()
 8118    }
 8119
 8120    pub fn language_server_for_local_buffer<'a>(
 8121        &'a self,
 8122        buffer: &'a Buffer,
 8123        server_id: LanguageServerId,
 8124        cx: &'a mut App,
 8125    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8126        self.as_local()?
 8127            .language_servers_for_buffer(buffer, cx)
 8128            .find(|(_, s)| s.server_id() == server_id)
 8129    }
 8130
 8131    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8132        self.diagnostic_summaries.remove(&id_to_remove);
 8133        if let Some(local) = self.as_local_mut() {
 8134            let to_remove = local.remove_worktree(id_to_remove, cx);
 8135            for server in to_remove {
 8136                self.language_server_statuses.remove(&server);
 8137            }
 8138        }
 8139    }
 8140
 8141    fn invalidate_diagnostic_summaries_for_removed_entries(
 8142        &mut self,
 8143        worktree_id: WorktreeId,
 8144        changes: &UpdatedEntriesSet,
 8145        cx: &mut Context<Self>,
 8146    ) {
 8147        let Some(summaries_for_tree) = self.diagnostic_summaries.get_mut(&worktree_id) else {
 8148            return;
 8149        };
 8150
 8151        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
 8152        let mut cleared_server_ids: HashSet<LanguageServerId> = HashSet::default();
 8153        let downstream = self.downstream_client.clone();
 8154
 8155        for (path, _, _) in changes
 8156            .iter()
 8157            .filter(|(_, _, change)| *change == PathChange::Removed)
 8158        {
 8159            if let Some(summaries_by_server_id) = summaries_for_tree.remove(path) {
 8160                for (server_id, _) in &summaries_by_server_id {
 8161                    cleared_server_ids.insert(*server_id);
 8162                    if let Some((client, project_id)) = &downstream {
 8163                        client
 8164                            .send(proto::UpdateDiagnosticSummary {
 8165                                project_id: *project_id,
 8166                                worktree_id: worktree_id.to_proto(),
 8167                                summary: Some(proto::DiagnosticSummary {
 8168                                    path: path.as_ref().to_proto(),
 8169                                    language_server_id: server_id.0 as u64,
 8170                                    error_count: 0,
 8171                                    warning_count: 0,
 8172                                }),
 8173                                more_summaries: Vec::new(),
 8174                            })
 8175                            .ok();
 8176                    }
 8177                }
 8178                cleared_paths.push(ProjectPath {
 8179                    worktree_id,
 8180                    path: path.clone(),
 8181                });
 8182            }
 8183        }
 8184
 8185        if !cleared_paths.is_empty() {
 8186            for server_id in cleared_server_ids {
 8187                cx.emit(LspStoreEvent::DiagnosticsUpdated {
 8188                    server_id,
 8189                    paths: cleared_paths.clone(),
 8190                });
 8191            }
 8192        }
 8193    }
 8194
 8195    pub fn shared(
 8196        &mut self,
 8197        project_id: u64,
 8198        downstream_client: AnyProtoClient,
 8199        _: &mut Context<Self>,
 8200    ) {
 8201        self.downstream_client = Some((downstream_client.clone(), project_id));
 8202
 8203        for (server_id, status) in &self.language_server_statuses {
 8204            if let Some(server) = self.language_server_for_id(*server_id) {
 8205                downstream_client
 8206                    .send(proto::StartLanguageServer {
 8207                        project_id,
 8208                        server: Some(proto::LanguageServer {
 8209                            id: server_id.to_proto(),
 8210                            name: status.name.to_string(),
 8211                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8212                        }),
 8213                        capabilities: serde_json::to_string(&server.capabilities())
 8214                            .expect("serializing server LSP capabilities"),
 8215                    })
 8216                    .log_err();
 8217            }
 8218        }
 8219    }
 8220
 8221    pub fn disconnected_from_host(&mut self) {
 8222        self.downstream_client.take();
 8223    }
 8224
 8225    pub fn disconnected_from_ssh_remote(&mut self) {
 8226        if let LspStoreMode::Remote(RemoteLspStore {
 8227            upstream_client, ..
 8228        }) = &mut self.mode
 8229        {
 8230            upstream_client.take();
 8231        }
 8232    }
 8233
 8234    pub(crate) fn set_language_server_statuses_from_proto(
 8235        &mut self,
 8236        project: WeakEntity<Project>,
 8237        language_servers: Vec<proto::LanguageServer>,
 8238        server_capabilities: Vec<String>,
 8239        cx: &mut Context<Self>,
 8240    ) {
 8241        let lsp_logs = cx
 8242            .try_global::<GlobalLogStore>()
 8243            .map(|lsp_store| lsp_store.0.clone());
 8244
 8245        self.language_server_statuses = language_servers
 8246            .into_iter()
 8247            .zip(server_capabilities)
 8248            .map(|(server, server_capabilities)| {
 8249                let server_id = LanguageServerId(server.id as usize);
 8250                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8251                    self.lsp_server_capabilities
 8252                        .insert(server_id, server_capabilities);
 8253                }
 8254
 8255                let name = LanguageServerName::from_proto(server.name);
 8256                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8257
 8258                if let Some(lsp_logs) = &lsp_logs {
 8259                    lsp_logs.update(cx, |lsp_logs, cx| {
 8260                        lsp_logs.add_language_server(
 8261                            // Only remote clients get their language servers set from proto
 8262                            LanguageServerKind::Remote {
 8263                                project: project.clone(),
 8264                            },
 8265                            server_id,
 8266                            Some(name.clone()),
 8267                            worktree,
 8268                            None,
 8269                            cx,
 8270                        );
 8271                    });
 8272                }
 8273
 8274                (
 8275                    server_id,
 8276                    LanguageServerStatus {
 8277                        name,
 8278                        server_version: None,
 8279                        server_readable_version: None,
 8280                        pending_work: Default::default(),
 8281                        has_pending_diagnostic_updates: false,
 8282                        progress_tokens: Default::default(),
 8283                        worktree,
 8284                        binary: None,
 8285                        configuration: None,
 8286                        workspace_folders: BTreeSet::new(),
 8287                        process_id: None,
 8288                    },
 8289                )
 8290            })
 8291            .collect();
 8292    }
 8293
 8294    #[cfg(feature = "test-support")]
 8295    pub fn update_diagnostic_entries(
 8296        &mut self,
 8297        server_id: LanguageServerId,
 8298        abs_path: PathBuf,
 8299        result_id: Option<SharedString>,
 8300        version: Option<i32>,
 8301        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8302        cx: &mut Context<Self>,
 8303    ) -> anyhow::Result<()> {
 8304        self.merge_diagnostic_entries(
 8305            vec![DocumentDiagnosticsUpdate {
 8306                diagnostics: DocumentDiagnostics {
 8307                    diagnostics,
 8308                    document_abs_path: abs_path,
 8309                    version,
 8310                },
 8311                result_id,
 8312                server_id,
 8313                disk_based_sources: Cow::Borrowed(&[]),
 8314                registration_id: None,
 8315            }],
 8316            |_, _, _| false,
 8317            cx,
 8318        )?;
 8319        Ok(())
 8320    }
 8321
 8322    pub fn merge_diagnostic_entries<'a>(
 8323        &mut self,
 8324        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8325        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8326        cx: &mut Context<Self>,
 8327    ) -> anyhow::Result<()> {
 8328        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8329        let mut updated_diagnostics_paths = HashMap::default();
 8330        for mut update in diagnostic_updates {
 8331            let abs_path = &update.diagnostics.document_abs_path;
 8332            let server_id = update.server_id;
 8333            let Some((worktree, relative_path)) =
 8334                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8335            else {
 8336                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8337                return Ok(());
 8338            };
 8339
 8340            let worktree_id = worktree.read(cx).id();
 8341            let project_path = ProjectPath {
 8342                worktree_id,
 8343                path: relative_path,
 8344            };
 8345
 8346            let document_uri = lsp::Uri::from_file_path(abs_path)
 8347                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8348            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8349                let snapshot = buffer_handle.read(cx).snapshot();
 8350                let buffer = buffer_handle.read(cx);
 8351                let reused_diagnostics = buffer
 8352                    .buffer_diagnostics(Some(server_id))
 8353                    .iter()
 8354                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8355                    .map(|v| {
 8356                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8357                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8358                        DiagnosticEntry {
 8359                            range: start..end,
 8360                            diagnostic: v.diagnostic.clone(),
 8361                        }
 8362                    })
 8363                    .collect::<Vec<_>>();
 8364
 8365                self.as_local_mut()
 8366                    .context("cannot merge diagnostics on a remote LspStore")?
 8367                    .update_buffer_diagnostics(
 8368                        &buffer_handle,
 8369                        server_id,
 8370                        Some(update.registration_id),
 8371                        update.result_id,
 8372                        update.diagnostics.version,
 8373                        update.diagnostics.diagnostics.clone(),
 8374                        reused_diagnostics.clone(),
 8375                        cx,
 8376                    )?;
 8377
 8378                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8379            } else if let Some(local) = self.as_local() {
 8380                let reused_diagnostics = local
 8381                    .diagnostics
 8382                    .get(&worktree_id)
 8383                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8384                    .and_then(|diagnostics_by_server_id| {
 8385                        diagnostics_by_server_id
 8386                            .binary_search_by_key(&server_id, |e| e.0)
 8387                            .ok()
 8388                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8389                    })
 8390                    .into_iter()
 8391                    .flatten()
 8392                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8393
 8394                update
 8395                    .diagnostics
 8396                    .diagnostics
 8397                    .extend(reused_diagnostics.cloned());
 8398            }
 8399
 8400            let updated = worktree.update(cx, |worktree, cx| {
 8401                self.update_worktree_diagnostics(
 8402                    worktree.id(),
 8403                    server_id,
 8404                    project_path.path.clone(),
 8405                    update.diagnostics.diagnostics,
 8406                    cx,
 8407                )
 8408            })?;
 8409            match updated {
 8410                ControlFlow::Continue(new_summary) => {
 8411                    if let Some((project_id, new_summary)) = new_summary {
 8412                        match &mut diagnostics_summary {
 8413                            Some(diagnostics_summary) => {
 8414                                diagnostics_summary
 8415                                    .more_summaries
 8416                                    .push(proto::DiagnosticSummary {
 8417                                        path: project_path.path.as_ref().to_proto(),
 8418                                        language_server_id: server_id.0 as u64,
 8419                                        error_count: new_summary.error_count,
 8420                                        warning_count: new_summary.warning_count,
 8421                                    })
 8422                            }
 8423                            None => {
 8424                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8425                                    project_id,
 8426                                    worktree_id: worktree_id.to_proto(),
 8427                                    summary: Some(proto::DiagnosticSummary {
 8428                                        path: project_path.path.as_ref().to_proto(),
 8429                                        language_server_id: server_id.0 as u64,
 8430                                        error_count: new_summary.error_count,
 8431                                        warning_count: new_summary.warning_count,
 8432                                    }),
 8433                                    more_summaries: Vec::new(),
 8434                                })
 8435                            }
 8436                        }
 8437                    }
 8438                    updated_diagnostics_paths
 8439                        .entry(server_id)
 8440                        .or_insert_with(Vec::new)
 8441                        .push(project_path);
 8442                }
 8443                ControlFlow::Break(()) => {}
 8444            }
 8445        }
 8446
 8447        if let Some((diagnostics_summary, (downstream_client, _))) =
 8448            diagnostics_summary.zip(self.downstream_client.as_ref())
 8449        {
 8450            downstream_client.send(diagnostics_summary).log_err();
 8451        }
 8452        for (server_id, paths) in updated_diagnostics_paths {
 8453            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8454        }
 8455        Ok(())
 8456    }
 8457
 8458    fn update_worktree_diagnostics(
 8459        &mut self,
 8460        worktree_id: WorktreeId,
 8461        server_id: LanguageServerId,
 8462        path_in_worktree: Arc<RelPath>,
 8463        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8464        _: &mut Context<Worktree>,
 8465    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8466        let local = match &mut self.mode {
 8467            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8468            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8469        };
 8470
 8471        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8472        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8473        let summaries_by_server_id = summaries_for_tree
 8474            .entry(path_in_worktree.clone())
 8475            .or_default();
 8476
 8477        let old_summary = summaries_by_server_id
 8478            .remove(&server_id)
 8479            .unwrap_or_default();
 8480
 8481        let new_summary = DiagnosticSummary::new(&diagnostics);
 8482        if diagnostics.is_empty() {
 8483            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8484            {
 8485                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8486                    diagnostics_by_server_id.remove(ix);
 8487                }
 8488                if diagnostics_by_server_id.is_empty() {
 8489                    diagnostics_for_tree.remove(&path_in_worktree);
 8490                }
 8491            }
 8492        } else {
 8493            summaries_by_server_id.insert(server_id, new_summary);
 8494            let diagnostics_by_server_id = diagnostics_for_tree
 8495                .entry(path_in_worktree.clone())
 8496                .or_default();
 8497            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8498                Ok(ix) => {
 8499                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8500                }
 8501                Err(ix) => {
 8502                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8503                }
 8504            }
 8505        }
 8506
 8507        if !old_summary.is_empty() || !new_summary.is_empty() {
 8508            if let Some((_, project_id)) = &self.downstream_client {
 8509                Ok(ControlFlow::Continue(Some((
 8510                    *project_id,
 8511                    proto::DiagnosticSummary {
 8512                        path: path_in_worktree.to_proto(),
 8513                        language_server_id: server_id.0 as u64,
 8514                        error_count: new_summary.error_count as u32,
 8515                        warning_count: new_summary.warning_count as u32,
 8516                    },
 8517                ))))
 8518            } else {
 8519                Ok(ControlFlow::Continue(None))
 8520            }
 8521        } else {
 8522            Ok(ControlFlow::Break(()))
 8523        }
 8524    }
 8525
 8526    pub fn open_buffer_for_symbol(
 8527        &mut self,
 8528        symbol: &Symbol,
 8529        cx: &mut Context<Self>,
 8530    ) -> Task<Result<Entity<Buffer>>> {
 8531        if let Some((client, project_id)) = self.upstream_client() {
 8532            let request = client.request(proto::OpenBufferForSymbol {
 8533                project_id,
 8534                symbol: Some(Self::serialize_symbol(symbol)),
 8535            });
 8536            cx.spawn(async move |this, cx| {
 8537                let response = request.await?;
 8538                let buffer_id = BufferId::new(response.buffer_id)?;
 8539                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8540                    .await
 8541            })
 8542        } else if let Some(local) = self.as_local() {
 8543            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8544                seed.worktree_id == symbol.source_worktree_id
 8545                    && state.id == symbol.source_language_server_id
 8546                    && symbol.language_server_name == seed.name
 8547            });
 8548            if !is_valid {
 8549                return Task::ready(Err(anyhow!(
 8550                    "language server for worktree and language not found"
 8551                )));
 8552            };
 8553
 8554            let symbol_abs_path = match &symbol.path {
 8555                SymbolLocation::InProject(project_path) => self
 8556                    .worktree_store
 8557                    .read(cx)
 8558                    .absolutize(&project_path, cx)
 8559                    .context("no such worktree"),
 8560                SymbolLocation::OutsideProject {
 8561                    abs_path,
 8562                    signature: _,
 8563                } => Ok(abs_path.to_path_buf()),
 8564            };
 8565            let symbol_abs_path = match symbol_abs_path {
 8566                Ok(abs_path) => abs_path,
 8567                Err(err) => return Task::ready(Err(err)),
 8568            };
 8569            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8570                uri
 8571            } else {
 8572                return Task::ready(Err(anyhow!("invalid symbol path")));
 8573            };
 8574
 8575            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8576        } else {
 8577            Task::ready(Err(anyhow!("no upstream client or local store")))
 8578        }
 8579    }
 8580
 8581    pub(crate) fn open_local_buffer_via_lsp(
 8582        &mut self,
 8583        abs_path: lsp::Uri,
 8584        language_server_id: LanguageServerId,
 8585        cx: &mut Context<Self>,
 8586    ) -> Task<Result<Entity<Buffer>>> {
 8587        let path_style = self.worktree_store.read(cx).path_style();
 8588        cx.spawn(async move |lsp_store, cx| {
 8589            // Escape percent-encoded string.
 8590            let current_scheme = abs_path.scheme().to_owned();
 8591            // Uri is immutable, so we can't modify the scheme
 8592
 8593            let abs_path = abs_path
 8594                .to_file_path_ext(path_style)
 8595                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8596            let p = abs_path.clone();
 8597            let yarn_worktree = lsp_store
 8598                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8599                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8600                        cx.spawn(async move |this, cx| {
 8601                            let t = this
 8602                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8603                                .ok()?;
 8604                            t.await
 8605                        })
 8606                    }),
 8607                    None => Task::ready(None),
 8608                })?
 8609                .await;
 8610            let (worktree_root_target, known_relative_path) =
 8611                if let Some((zip_root, relative_path)) = yarn_worktree {
 8612                    (zip_root, Some(relative_path))
 8613                } else {
 8614                    (Arc::<Path>::from(abs_path.as_path()), None)
 8615                };
 8616            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8617                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8618                    worktree_store.find_worktree(&worktree_root_target, cx)
 8619                })
 8620            })?;
 8621            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8622                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8623                (result.0, relative_path, None)
 8624            } else {
 8625                let worktree = lsp_store
 8626                    .update(cx, |lsp_store, cx| {
 8627                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8628                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8629                        })
 8630                    })?
 8631                    .await?;
 8632                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8633                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8634                    lsp_store
 8635                        .update(cx, |lsp_store, cx| {
 8636                            if let Some(local) = lsp_store.as_local_mut() {
 8637                                local.register_language_server_for_invisible_worktree(
 8638                                    &worktree,
 8639                                    language_server_id,
 8640                                    cx,
 8641                                )
 8642                            }
 8643                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8644                                Some(status) => status.worktree,
 8645                                None => None,
 8646                            }
 8647                        })
 8648                        .ok()
 8649                        .flatten()
 8650                        .zip(Some(worktree_root.clone()))
 8651                } else {
 8652                    None
 8653                };
 8654                let relative_path = if let Some(known_path) = known_relative_path {
 8655                    known_path
 8656                } else {
 8657                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8658                        .into_arc()
 8659                };
 8660                (worktree, relative_path, source_ws)
 8661            };
 8662            let project_path = ProjectPath {
 8663                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8664                path: relative_path,
 8665            };
 8666            let buffer = lsp_store
 8667                .update(cx, |lsp_store, cx| {
 8668                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8669                        buffer_store.open_buffer(project_path, cx)
 8670                    })
 8671                })?
 8672                .await?;
 8673            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8674            if let Some((source_ws, worktree_root)) = source_ws {
 8675                buffer.update(cx, |buffer, cx| {
 8676                    let settings = WorktreeSettings::get(
 8677                        Some(
 8678                            (&ProjectPath {
 8679                                worktree_id: source_ws,
 8680                                path: Arc::from(RelPath::empty()),
 8681                            })
 8682                                .into(),
 8683                        ),
 8684                        cx,
 8685                    );
 8686                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8687                    if is_read_only {
 8688                        buffer.set_capability(Capability::ReadOnly, cx);
 8689                    }
 8690                });
 8691            }
 8692            Ok(buffer)
 8693        })
 8694    }
 8695
 8696    fn local_lsp_servers_for_buffer(
 8697        &self,
 8698        buffer: &Entity<Buffer>,
 8699        cx: &mut Context<Self>,
 8700    ) -> Vec<LanguageServerId> {
 8701        let Some(local) = self.as_local() else {
 8702            return Vec::new();
 8703        };
 8704
 8705        let snapshot = buffer.read(cx).snapshot();
 8706
 8707        buffer.update(cx, |buffer, cx| {
 8708            local
 8709                .language_servers_for_buffer(buffer, cx)
 8710                .map(|(_, server)| server.server_id())
 8711                .filter(|server_id| {
 8712                    self.as_local().is_none_or(|local| {
 8713                        local
 8714                            .buffers_opened_in_servers
 8715                            .get(&snapshot.remote_id())
 8716                            .is_some_and(|servers| servers.contains(server_id))
 8717                    })
 8718                })
 8719                .collect()
 8720        })
 8721    }
 8722
 8723    fn request_multiple_lsp_locally<P, R>(
 8724        &mut self,
 8725        buffer: &Entity<Buffer>,
 8726        position: Option<P>,
 8727        request: R,
 8728        cx: &mut Context<Self>,
 8729    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8730    where
 8731        P: ToOffset,
 8732        R: LspCommand + Clone,
 8733        <R::LspRequest as lsp::request::Request>::Result: Send,
 8734        <R::LspRequest as lsp::request::Request>::Params: Send,
 8735    {
 8736        let Some(local) = self.as_local() else {
 8737            return Task::ready(Vec::new());
 8738        };
 8739
 8740        let snapshot = buffer.read(cx).snapshot();
 8741        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8742
 8743        let server_ids = buffer.update(cx, |buffer, cx| {
 8744            local
 8745                .language_servers_for_buffer(buffer, cx)
 8746                .filter(|(adapter, _)| {
 8747                    scope
 8748                        .as_ref()
 8749                        .map(|scope| scope.language_allowed(&adapter.name))
 8750                        .unwrap_or(true)
 8751                })
 8752                .map(|(_, server)| server.server_id())
 8753                .filter(|server_id| {
 8754                    self.as_local().is_none_or(|local| {
 8755                        local
 8756                            .buffers_opened_in_servers
 8757                            .get(&snapshot.remote_id())
 8758                            .is_some_and(|servers| servers.contains(server_id))
 8759                    })
 8760                })
 8761                .collect::<Vec<_>>()
 8762        });
 8763
 8764        let mut response_results = server_ids
 8765            .into_iter()
 8766            .map(|server_id| {
 8767                let task = self.request_lsp(
 8768                    buffer.clone(),
 8769                    LanguageServerToQuery::Other(server_id),
 8770                    request.clone(),
 8771                    cx,
 8772                );
 8773                async move { (server_id, task.await) }
 8774            })
 8775            .collect::<FuturesUnordered<_>>();
 8776
 8777        cx.background_spawn(async move {
 8778            let mut responses = Vec::with_capacity(response_results.len());
 8779            while let Some((server_id, response_result)) = response_results.next().await {
 8780                match response_result {
 8781                    Ok(response) => responses.push((server_id, response)),
 8782                    // rust-analyzer likes to error with this when its still loading up
 8783                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8784                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8785                }
 8786            }
 8787            responses
 8788        })
 8789    }
 8790
 8791    async fn handle_lsp_get_completions(
 8792        this: Entity<Self>,
 8793        envelope: TypedEnvelope<proto::GetCompletions>,
 8794        mut cx: AsyncApp,
 8795    ) -> Result<proto::GetCompletionsResponse> {
 8796        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8797
 8798        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8799        let buffer_handle = this.update(&mut cx, |this, cx| {
 8800            this.buffer_store.read(cx).get_existing(buffer_id)
 8801        })?;
 8802        let request = GetCompletions::from_proto(
 8803            envelope.payload,
 8804            this.clone(),
 8805            buffer_handle.clone(),
 8806            cx.clone(),
 8807        )
 8808        .await?;
 8809
 8810        let server_to_query = match request.server_id {
 8811            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8812            None => LanguageServerToQuery::FirstCapable,
 8813        };
 8814
 8815        let response = this
 8816            .update(&mut cx, |this, cx| {
 8817                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8818            })
 8819            .await?;
 8820        this.update(&mut cx, |this, cx| {
 8821            Ok(GetCompletions::response_to_proto(
 8822                response,
 8823                this,
 8824                sender_id,
 8825                &buffer_handle.read(cx).version(),
 8826                cx,
 8827            ))
 8828        })
 8829    }
 8830
 8831    async fn handle_lsp_command<T: LspCommand>(
 8832        this: Entity<Self>,
 8833        envelope: TypedEnvelope<T::ProtoRequest>,
 8834        mut cx: AsyncApp,
 8835    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8836    where
 8837        <T::LspRequest as lsp::request::Request>::Params: Send,
 8838        <T::LspRequest as lsp::request::Request>::Result: Send,
 8839    {
 8840        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8841        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8842        let buffer_handle = this.update(&mut cx, |this, cx| {
 8843            this.buffer_store.read(cx).get_existing(buffer_id)
 8844        })?;
 8845        let request = T::from_proto(
 8846            envelope.payload,
 8847            this.clone(),
 8848            buffer_handle.clone(),
 8849            cx.clone(),
 8850        )
 8851        .await?;
 8852        let response = this
 8853            .update(&mut cx, |this, cx| {
 8854                this.request_lsp(
 8855                    buffer_handle.clone(),
 8856                    LanguageServerToQuery::FirstCapable,
 8857                    request,
 8858                    cx,
 8859                )
 8860            })
 8861            .await?;
 8862        this.update(&mut cx, |this, cx| {
 8863            Ok(T::response_to_proto(
 8864                response,
 8865                this,
 8866                sender_id,
 8867                &buffer_handle.read(cx).version(),
 8868                cx,
 8869            ))
 8870        })
 8871    }
 8872
 8873    async fn handle_lsp_query(
 8874        lsp_store: Entity<Self>,
 8875        envelope: TypedEnvelope<proto::LspQuery>,
 8876        mut cx: AsyncApp,
 8877    ) -> Result<proto::Ack> {
 8878        use proto::lsp_query::Request;
 8879        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8880        let lsp_query = envelope.payload;
 8881        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8882        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8883        match lsp_query.request.context("invalid LSP query request")? {
 8884            Request::GetReferences(get_references) => {
 8885                let position = get_references.position.clone().and_then(deserialize_anchor);
 8886                Self::query_lsp_locally::<GetReferences>(
 8887                    lsp_store,
 8888                    server_id,
 8889                    sender_id,
 8890                    lsp_request_id,
 8891                    get_references,
 8892                    position,
 8893                    &mut cx,
 8894                )
 8895                .await?;
 8896            }
 8897            Request::GetDocumentColor(get_document_color) => {
 8898                Self::query_lsp_locally::<GetDocumentColor>(
 8899                    lsp_store,
 8900                    server_id,
 8901                    sender_id,
 8902                    lsp_request_id,
 8903                    get_document_color,
 8904                    None,
 8905                    &mut cx,
 8906                )
 8907                .await?;
 8908            }
 8909            Request::GetFoldingRanges(get_folding_ranges) => {
 8910                Self::query_lsp_locally::<GetFoldingRanges>(
 8911                    lsp_store,
 8912                    server_id,
 8913                    sender_id,
 8914                    lsp_request_id,
 8915                    get_folding_ranges,
 8916                    None,
 8917                    &mut cx,
 8918                )
 8919                .await?;
 8920            }
 8921            Request::GetDocumentSymbols(get_document_symbols) => {
 8922                Self::query_lsp_locally::<GetDocumentSymbols>(
 8923                    lsp_store,
 8924                    server_id,
 8925                    sender_id,
 8926                    lsp_request_id,
 8927                    get_document_symbols,
 8928                    None,
 8929                    &mut cx,
 8930                )
 8931                .await?;
 8932            }
 8933            Request::GetHover(get_hover) => {
 8934                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8935                Self::query_lsp_locally::<GetHover>(
 8936                    lsp_store,
 8937                    server_id,
 8938                    sender_id,
 8939                    lsp_request_id,
 8940                    get_hover,
 8941                    position,
 8942                    &mut cx,
 8943                )
 8944                .await?;
 8945            }
 8946            Request::GetCodeActions(get_code_actions) => {
 8947                Self::query_lsp_locally::<GetCodeActions>(
 8948                    lsp_store,
 8949                    server_id,
 8950                    sender_id,
 8951                    lsp_request_id,
 8952                    get_code_actions,
 8953                    None,
 8954                    &mut cx,
 8955                )
 8956                .await?;
 8957            }
 8958            Request::GetSignatureHelp(get_signature_help) => {
 8959                let position = get_signature_help
 8960                    .position
 8961                    .clone()
 8962                    .and_then(deserialize_anchor);
 8963                Self::query_lsp_locally::<GetSignatureHelp>(
 8964                    lsp_store,
 8965                    server_id,
 8966                    sender_id,
 8967                    lsp_request_id,
 8968                    get_signature_help,
 8969                    position,
 8970                    &mut cx,
 8971                )
 8972                .await?;
 8973            }
 8974            Request::GetCodeLens(get_code_lens) => {
 8975                Self::query_lsp_locally::<GetCodeLens>(
 8976                    lsp_store,
 8977                    server_id,
 8978                    sender_id,
 8979                    lsp_request_id,
 8980                    get_code_lens,
 8981                    None,
 8982                    &mut cx,
 8983                )
 8984                .await?;
 8985            }
 8986            Request::GetDefinition(get_definition) => {
 8987                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8988                Self::query_lsp_locally::<GetDefinitions>(
 8989                    lsp_store,
 8990                    server_id,
 8991                    sender_id,
 8992                    lsp_request_id,
 8993                    get_definition,
 8994                    position,
 8995                    &mut cx,
 8996                )
 8997                .await?;
 8998            }
 8999            Request::GetDeclaration(get_declaration) => {
 9000                let position = get_declaration
 9001                    .position
 9002                    .clone()
 9003                    .and_then(deserialize_anchor);
 9004                Self::query_lsp_locally::<GetDeclarations>(
 9005                    lsp_store,
 9006                    server_id,
 9007                    sender_id,
 9008                    lsp_request_id,
 9009                    get_declaration,
 9010                    position,
 9011                    &mut cx,
 9012                )
 9013                .await?;
 9014            }
 9015            Request::GetTypeDefinition(get_type_definition) => {
 9016                let position = get_type_definition
 9017                    .position
 9018                    .clone()
 9019                    .and_then(deserialize_anchor);
 9020                Self::query_lsp_locally::<GetTypeDefinitions>(
 9021                    lsp_store,
 9022                    server_id,
 9023                    sender_id,
 9024                    lsp_request_id,
 9025                    get_type_definition,
 9026                    position,
 9027                    &mut cx,
 9028                )
 9029                .await?;
 9030            }
 9031            Request::GetImplementation(get_implementation) => {
 9032                let position = get_implementation
 9033                    .position
 9034                    .clone()
 9035                    .and_then(deserialize_anchor);
 9036                Self::query_lsp_locally::<GetImplementations>(
 9037                    lsp_store,
 9038                    server_id,
 9039                    sender_id,
 9040                    lsp_request_id,
 9041                    get_implementation,
 9042                    position,
 9043                    &mut cx,
 9044                )
 9045                .await?;
 9046            }
 9047            Request::InlayHints(inlay_hints) => {
 9048                let query_start = inlay_hints
 9049                    .start
 9050                    .clone()
 9051                    .and_then(deserialize_anchor)
 9052                    .context("invalid inlay hints range start")?;
 9053                let query_end = inlay_hints
 9054                    .end
 9055                    .clone()
 9056                    .and_then(deserialize_anchor)
 9057                    .context("invalid inlay hints range end")?;
 9058                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9059                    &lsp_store,
 9060                    server_id,
 9061                    lsp_request_id,
 9062                    &inlay_hints,
 9063                    query_start..query_end,
 9064                    &mut cx,
 9065                )
 9066                .await
 9067                .context("preparing inlay hints request")?;
 9068                Self::query_lsp_locally::<InlayHints>(
 9069                    lsp_store,
 9070                    server_id,
 9071                    sender_id,
 9072                    lsp_request_id,
 9073                    inlay_hints,
 9074                    None,
 9075                    &mut cx,
 9076                )
 9077                .await
 9078                .context("querying for inlay hints")?
 9079            }
 9080            //////////////////////////////
 9081            // Below are LSP queries that need to fetch more data,
 9082            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 9083            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9084                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 9085                    &lsp_store,
 9086                    &get_document_diagnostics,
 9087                    &mut cx,
 9088                )
 9089                .await?;
 9090                lsp_store.update(&mut cx, |lsp_store, cx| {
 9091                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9092                    let key = LspKey {
 9093                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9094                        server_queried: server_id,
 9095                    };
 9096                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9097                    ) {
 9098                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9099                            lsp_requests.clear();
 9100                        };
 9101                    }
 9102
 9103                    lsp_data.lsp_requests.entry(key).or_default().insert(
 9104                        lsp_request_id,
 9105                        cx.spawn(async move |lsp_store, cx| {
 9106                            let diagnostics_pull = lsp_store
 9107                                .update(cx, |lsp_store, cx| {
 9108                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9109                                })
 9110                                .ok();
 9111                            if let Some(diagnostics_pull) = diagnostics_pull {
 9112                                match diagnostics_pull.await {
 9113                                    Ok(()) => {}
 9114                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9115                                };
 9116                            }
 9117                        }),
 9118                    );
 9119                });
 9120            }
 9121            Request::SemanticTokens(semantic_tokens) => {
 9122                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9123                    &lsp_store,
 9124                    &semantic_tokens,
 9125                    &mut cx,
 9126                )
 9127                .await?;
 9128                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9129                lsp_store.update(&mut cx, |lsp_store, cx| {
 9130                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9131                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9132                        let key = LspKey {
 9133                            request_type: TypeId::of::<SemanticTokensFull>(),
 9134                            server_queried: server_id,
 9135                        };
 9136                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9137                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9138                                lsp_requests.clear();
 9139                            };
 9140                        }
 9141
 9142                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9143                            lsp_request_id,
 9144                            cx.spawn(async move |lsp_store, cx| {
 9145                                let tokens_fetch = lsp_store
 9146                                    .update(cx, |lsp_store, cx| {
 9147                                        lsp_store
 9148                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9149                                    })
 9150                                    .ok();
 9151                                if let Some(tokens_fetch) = tokens_fetch {
 9152                                    let new_tokens = tokens_fetch.await;
 9153                                    if let Some(new_tokens) = new_tokens {
 9154                                        lsp_store
 9155                                            .update(cx, |lsp_store, cx| {
 9156                                                let response = new_tokens
 9157                                                    .into_iter()
 9158                                                    .map(|(server_id, response)| {
 9159                                                        (
 9160                                                            server_id.to_proto(),
 9161                                                            SemanticTokensFull::response_to_proto(
 9162                                                                response,
 9163                                                                lsp_store,
 9164                                                                sender_id,
 9165                                                                &buffer_version,
 9166                                                                cx,
 9167                                                            ),
 9168                                                        )
 9169                                                    })
 9170                                                    .collect::<HashMap<_, _>>();
 9171                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9172                                                    project_id,
 9173                                                    lsp_request_id,
 9174                                                    response,
 9175                                                ) {
 9176                                                    Ok(()) => {}
 9177                                                    Err(e) => {
 9178                                                        log::error!(
 9179                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9180                                                        )
 9181                                                    }
 9182                                                }
 9183                                            })
 9184                                            .ok();
 9185                                    }
 9186                                }
 9187                            }),
 9188                        );
 9189                    }
 9190                });
 9191            }
 9192        }
 9193        Ok(proto::Ack {})
 9194    }
 9195
 9196    async fn handle_lsp_query_response(
 9197        lsp_store: Entity<Self>,
 9198        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9199        cx: AsyncApp,
 9200    ) -> Result<()> {
 9201        lsp_store.read_with(&cx, |lsp_store, _| {
 9202            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9203                upstream_client.handle_lsp_response(envelope.clone());
 9204            }
 9205        });
 9206        Ok(())
 9207    }
 9208
 9209    async fn handle_apply_code_action(
 9210        this: Entity<Self>,
 9211        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9212        mut cx: AsyncApp,
 9213    ) -> Result<proto::ApplyCodeActionResponse> {
 9214        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9215        let action =
 9216            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9217        let apply_code_action = this.update(&mut cx, |this, cx| {
 9218            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9219            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9220            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9221        })?;
 9222
 9223        let project_transaction = apply_code_action.await?;
 9224        let project_transaction = this.update(&mut cx, |this, cx| {
 9225            this.buffer_store.update(cx, |buffer_store, cx| {
 9226                buffer_store.serialize_project_transaction_for_peer(
 9227                    project_transaction,
 9228                    sender_id,
 9229                    cx,
 9230                )
 9231            })
 9232        });
 9233        Ok(proto::ApplyCodeActionResponse {
 9234            transaction: Some(project_transaction),
 9235        })
 9236    }
 9237
 9238    async fn handle_register_buffer_with_language_servers(
 9239        this: Entity<Self>,
 9240        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9241        mut cx: AsyncApp,
 9242    ) -> Result<proto::Ack> {
 9243        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9244        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9245        this.update(&mut cx, |this, cx| {
 9246            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9247                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9248                    project_id: upstream_project_id,
 9249                    buffer_id: buffer_id.to_proto(),
 9250                    only_servers: envelope.payload.only_servers,
 9251                });
 9252            }
 9253
 9254            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9255                anyhow::bail!("buffer is not open");
 9256            };
 9257
 9258            let handle = this.register_buffer_with_language_servers(
 9259                &buffer,
 9260                envelope
 9261                    .payload
 9262                    .only_servers
 9263                    .into_iter()
 9264                    .filter_map(|selector| {
 9265                        Some(match selector.selector? {
 9266                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9267                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9268                            }
 9269                            proto::language_server_selector::Selector::Name(name) => {
 9270                                LanguageServerSelector::Name(LanguageServerName(
 9271                                    SharedString::from(name),
 9272                                ))
 9273                            }
 9274                        })
 9275                    })
 9276                    .collect(),
 9277                false,
 9278                cx,
 9279            );
 9280            // Pull diagnostics for the buffer even if it was already registered.
 9281            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9282            // but it's unclear if we need it.
 9283            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9284                .detach();
 9285            this.buffer_store().update(cx, |buffer_store, _| {
 9286                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9287            });
 9288
 9289            Ok(())
 9290        })?;
 9291        Ok(proto::Ack {})
 9292    }
 9293
 9294    async fn handle_rename_project_entry(
 9295        this: Entity<Self>,
 9296        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9297        mut cx: AsyncApp,
 9298    ) -> Result<proto::ProjectEntryResponse> {
 9299        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9300        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9301        let new_path =
 9302            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9303
 9304        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9305            .update(&mut cx, |this, cx| {
 9306                let (worktree, entry) = this
 9307                    .worktree_store
 9308                    .read(cx)
 9309                    .worktree_and_entry_for_id(entry_id, cx)?;
 9310                let new_worktree = this
 9311                    .worktree_store
 9312                    .read(cx)
 9313                    .worktree_for_id(new_worktree_id, cx)?;
 9314                Some((
 9315                    this.worktree_store.clone(),
 9316                    worktree,
 9317                    new_worktree,
 9318                    entry.clone(),
 9319                ))
 9320            })
 9321            .context("worktree not found")?;
 9322        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9323            (worktree.absolutize(&old_entry.path), worktree.id())
 9324        });
 9325        let new_abs_path =
 9326            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9327
 9328        let _transaction = Self::will_rename_entry(
 9329            this.downgrade(),
 9330            old_worktree_id,
 9331            &old_abs_path,
 9332            &new_abs_path,
 9333            old_entry.is_dir(),
 9334            cx.clone(),
 9335        )
 9336        .await;
 9337        let response = WorktreeStore::handle_rename_project_entry(
 9338            worktree_store,
 9339            envelope.payload,
 9340            cx.clone(),
 9341        )
 9342        .await;
 9343        this.read_with(&cx, |this, _| {
 9344            this.did_rename_entry(
 9345                old_worktree_id,
 9346                &old_abs_path,
 9347                &new_abs_path,
 9348                old_entry.is_dir(),
 9349            );
 9350        });
 9351        response
 9352    }
 9353
 9354    async fn handle_update_diagnostic_summary(
 9355        this: Entity<Self>,
 9356        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9357        mut cx: AsyncApp,
 9358    ) -> Result<()> {
 9359        this.update(&mut cx, |lsp_store, cx| {
 9360            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9361            let mut updated_diagnostics_paths = HashMap::default();
 9362            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9363            for message_summary in envelope
 9364                .payload
 9365                .summary
 9366                .into_iter()
 9367                .chain(envelope.payload.more_summaries)
 9368            {
 9369                let project_path = ProjectPath {
 9370                    worktree_id,
 9371                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9372                };
 9373                let path = project_path.path.clone();
 9374                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9375                let summary = DiagnosticSummary {
 9376                    error_count: message_summary.error_count as usize,
 9377                    warning_count: message_summary.warning_count as usize,
 9378                };
 9379
 9380                if summary.is_empty() {
 9381                    if let Some(worktree_summaries) =
 9382                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9383                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9384                    {
 9385                        summaries.remove(&server_id);
 9386                        if summaries.is_empty() {
 9387                            worktree_summaries.remove(&path);
 9388                        }
 9389                    }
 9390                } else {
 9391                    lsp_store
 9392                        .diagnostic_summaries
 9393                        .entry(worktree_id)
 9394                        .or_default()
 9395                        .entry(path)
 9396                        .or_default()
 9397                        .insert(server_id, summary);
 9398                }
 9399
 9400                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9401                    match &mut diagnostics_summary {
 9402                        Some(diagnostics_summary) => {
 9403                            diagnostics_summary
 9404                                .more_summaries
 9405                                .push(proto::DiagnosticSummary {
 9406                                    path: project_path.path.as_ref().to_proto(),
 9407                                    language_server_id: server_id.0 as u64,
 9408                                    error_count: summary.error_count as u32,
 9409                                    warning_count: summary.warning_count as u32,
 9410                                })
 9411                        }
 9412                        None => {
 9413                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9414                                project_id: *project_id,
 9415                                worktree_id: worktree_id.to_proto(),
 9416                                summary: Some(proto::DiagnosticSummary {
 9417                                    path: project_path.path.as_ref().to_proto(),
 9418                                    language_server_id: server_id.0 as u64,
 9419                                    error_count: summary.error_count as u32,
 9420                                    warning_count: summary.warning_count as u32,
 9421                                }),
 9422                                more_summaries: Vec::new(),
 9423                            })
 9424                        }
 9425                    }
 9426                }
 9427                updated_diagnostics_paths
 9428                    .entry(server_id)
 9429                    .or_insert_with(Vec::new)
 9430                    .push(project_path);
 9431            }
 9432
 9433            if let Some((diagnostics_summary, (downstream_client, _))) =
 9434                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9435            {
 9436                downstream_client.send(diagnostics_summary).log_err();
 9437            }
 9438            for (server_id, paths) in updated_diagnostics_paths {
 9439                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9440            }
 9441            Ok(())
 9442        })
 9443    }
 9444
 9445    async fn handle_start_language_server(
 9446        lsp_store: Entity<Self>,
 9447        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9448        mut cx: AsyncApp,
 9449    ) -> Result<()> {
 9450        let server = envelope.payload.server.context("invalid server")?;
 9451        let server_capabilities =
 9452            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9453                .with_context(|| {
 9454                    format!(
 9455                        "incorrect server capabilities {}",
 9456                        envelope.payload.capabilities
 9457                    )
 9458                })?;
 9459        lsp_store.update(&mut cx, |lsp_store, cx| {
 9460            let server_id = LanguageServerId(server.id as usize);
 9461            let server_name = LanguageServerName::from_proto(server.name.clone());
 9462            lsp_store
 9463                .lsp_server_capabilities
 9464                .insert(server_id, server_capabilities);
 9465            lsp_store.language_server_statuses.insert(
 9466                server_id,
 9467                LanguageServerStatus {
 9468                    name: server_name.clone(),
 9469                    server_version: None,
 9470                    server_readable_version: None,
 9471                    pending_work: Default::default(),
 9472                    has_pending_diagnostic_updates: false,
 9473                    progress_tokens: Default::default(),
 9474                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9475                    binary: None,
 9476                    configuration: None,
 9477                    workspace_folders: BTreeSet::new(),
 9478                    process_id: None,
 9479                },
 9480            );
 9481            cx.emit(LspStoreEvent::LanguageServerAdded(
 9482                server_id,
 9483                server_name,
 9484                server.worktree_id.map(WorktreeId::from_proto),
 9485            ));
 9486            cx.notify();
 9487        });
 9488        Ok(())
 9489    }
 9490
 9491    async fn handle_update_language_server(
 9492        lsp_store: Entity<Self>,
 9493        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9494        mut cx: AsyncApp,
 9495    ) -> Result<()> {
 9496        lsp_store.update(&mut cx, |lsp_store, cx| {
 9497            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9498
 9499            match envelope.payload.variant.context("invalid variant")? {
 9500                proto::update_language_server::Variant::WorkStart(payload) => {
 9501                    lsp_store.on_lsp_work_start(
 9502                        language_server_id,
 9503                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9504                            .context("invalid progress token value")?,
 9505                        LanguageServerProgress {
 9506                            title: payload.title,
 9507                            is_disk_based_diagnostics_progress: false,
 9508                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9509                            message: payload.message,
 9510                            percentage: payload.percentage.map(|p| p as usize),
 9511                            last_update_at: cx.background_executor().now(),
 9512                        },
 9513                        cx,
 9514                    );
 9515                }
 9516                proto::update_language_server::Variant::WorkProgress(payload) => {
 9517                    lsp_store.on_lsp_work_progress(
 9518                        language_server_id,
 9519                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9520                            .context("invalid progress token value")?,
 9521                        LanguageServerProgress {
 9522                            title: None,
 9523                            is_disk_based_diagnostics_progress: false,
 9524                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9525                            message: payload.message,
 9526                            percentage: payload.percentage.map(|p| p as usize),
 9527                            last_update_at: cx.background_executor().now(),
 9528                        },
 9529                        cx,
 9530                    );
 9531                }
 9532
 9533                proto::update_language_server::Variant::WorkEnd(payload) => {
 9534                    lsp_store.on_lsp_work_end(
 9535                        language_server_id,
 9536                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9537                            .context("invalid progress token value")?,
 9538                        cx,
 9539                    );
 9540                }
 9541
 9542                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9543                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9544                }
 9545
 9546                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9547                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9548                }
 9549
 9550                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9551                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9552                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9553                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9554                        language_server_id,
 9555                        name: envelope
 9556                            .payload
 9557                            .server_name
 9558                            .map(SharedString::new)
 9559                            .map(LanguageServerName),
 9560                        message: non_lsp,
 9561                    });
 9562                }
 9563            }
 9564
 9565            Ok(())
 9566        })
 9567    }
 9568
 9569    async fn handle_language_server_log(
 9570        this: Entity<Self>,
 9571        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9572        mut cx: AsyncApp,
 9573    ) -> Result<()> {
 9574        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9575        let log_type = envelope
 9576            .payload
 9577            .log_type
 9578            .map(LanguageServerLogType::from_proto)
 9579            .context("invalid language server log type")?;
 9580
 9581        let message = envelope.payload.message;
 9582
 9583        this.update(&mut cx, |_, cx| {
 9584            cx.emit(LspStoreEvent::LanguageServerLog(
 9585                language_server_id,
 9586                log_type,
 9587                message,
 9588            ));
 9589        });
 9590        Ok(())
 9591    }
 9592
 9593    async fn handle_lsp_ext_cancel_flycheck(
 9594        lsp_store: Entity<Self>,
 9595        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9596        cx: AsyncApp,
 9597    ) -> Result<proto::Ack> {
 9598        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9599        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9600            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9601                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9602            } else {
 9603                None
 9604            }
 9605        });
 9606        if let Some(task) = task {
 9607            task.context("handling lsp ext cancel flycheck")?;
 9608        }
 9609
 9610        Ok(proto::Ack {})
 9611    }
 9612
 9613    async fn handle_lsp_ext_run_flycheck(
 9614        lsp_store: Entity<Self>,
 9615        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9616        mut cx: AsyncApp,
 9617    ) -> Result<proto::Ack> {
 9618        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9619        lsp_store.update(&mut cx, |lsp_store, cx| {
 9620            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9621                let text_document = if envelope.payload.current_file_only {
 9622                    let buffer_id = envelope
 9623                        .payload
 9624                        .buffer_id
 9625                        .map(|id| BufferId::new(id))
 9626                        .transpose()?;
 9627                    buffer_id
 9628                        .and_then(|buffer_id| {
 9629                            lsp_store
 9630                                .buffer_store()
 9631                                .read(cx)
 9632                                .get(buffer_id)
 9633                                .and_then(|buffer| {
 9634                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9635                                })
 9636                                .map(|path| make_text_document_identifier(&path))
 9637                        })
 9638                        .transpose()?
 9639                } else {
 9640                    None
 9641                };
 9642                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9643                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9644                )?;
 9645            }
 9646            anyhow::Ok(())
 9647        })?;
 9648
 9649        Ok(proto::Ack {})
 9650    }
 9651
 9652    async fn handle_lsp_ext_clear_flycheck(
 9653        lsp_store: Entity<Self>,
 9654        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9655        cx: AsyncApp,
 9656    ) -> Result<proto::Ack> {
 9657        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9658        lsp_store.read_with(&cx, |lsp_store, _| {
 9659            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9660                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9661            } else {
 9662                None
 9663            }
 9664        });
 9665
 9666        Ok(proto::Ack {})
 9667    }
 9668
 9669    pub fn disk_based_diagnostics_started(
 9670        &mut self,
 9671        language_server_id: LanguageServerId,
 9672        cx: &mut Context<Self>,
 9673    ) {
 9674        if let Some(language_server_status) =
 9675            self.language_server_statuses.get_mut(&language_server_id)
 9676        {
 9677            language_server_status.has_pending_diagnostic_updates = true;
 9678        }
 9679
 9680        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9681        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9682            language_server_id,
 9683            name: self
 9684                .language_server_adapter_for_id(language_server_id)
 9685                .map(|adapter| adapter.name()),
 9686            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9687                Default::default(),
 9688            ),
 9689        })
 9690    }
 9691
 9692    pub fn disk_based_diagnostics_finished(
 9693        &mut self,
 9694        language_server_id: LanguageServerId,
 9695        cx: &mut Context<Self>,
 9696    ) {
 9697        if let Some(language_server_status) =
 9698            self.language_server_statuses.get_mut(&language_server_id)
 9699        {
 9700            language_server_status.has_pending_diagnostic_updates = false;
 9701        }
 9702
 9703        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9704        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9705            language_server_id,
 9706            name: self
 9707                .language_server_adapter_for_id(language_server_id)
 9708                .map(|adapter| adapter.name()),
 9709            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9710                Default::default(),
 9711            ),
 9712        })
 9713    }
 9714
 9715    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9716    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9717    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9718    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9719    // the language server might take some time to publish diagnostics.
 9720    fn simulate_disk_based_diagnostics_events_if_needed(
 9721        &mut self,
 9722        language_server_id: LanguageServerId,
 9723        cx: &mut Context<Self>,
 9724    ) {
 9725        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9726
 9727        let Some(LanguageServerState::Running {
 9728            simulate_disk_based_diagnostics_completion,
 9729            adapter,
 9730            ..
 9731        }) = self
 9732            .as_local_mut()
 9733            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9734        else {
 9735            return;
 9736        };
 9737
 9738        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9739            return;
 9740        }
 9741
 9742        let prev_task =
 9743            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9744                cx.background_executor()
 9745                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9746                    .await;
 9747
 9748                this.update(cx, |this, cx| {
 9749                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9750
 9751                    if let Some(LanguageServerState::Running {
 9752                        simulate_disk_based_diagnostics_completion,
 9753                        ..
 9754                    }) = this.as_local_mut().and_then(|local_store| {
 9755                        local_store.language_servers.get_mut(&language_server_id)
 9756                    }) {
 9757                        *simulate_disk_based_diagnostics_completion = None;
 9758                    }
 9759                })
 9760                .ok();
 9761            }));
 9762
 9763        if prev_task.is_none() {
 9764            self.disk_based_diagnostics_started(language_server_id, cx);
 9765        }
 9766    }
 9767
 9768    pub fn language_server_statuses(
 9769        &self,
 9770    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9771        self.language_server_statuses
 9772            .iter()
 9773            .map(|(key, value)| (*key, value))
 9774    }
 9775
 9776    pub(super) fn did_rename_entry(
 9777        &self,
 9778        worktree_id: WorktreeId,
 9779        old_path: &Path,
 9780        new_path: &Path,
 9781        is_dir: bool,
 9782    ) {
 9783        maybe!({
 9784            let local_store = self.as_local()?;
 9785
 9786            let old_uri = lsp::Uri::from_file_path(old_path)
 9787                .ok()
 9788                .map(|uri| uri.to_string())?;
 9789            let new_uri = lsp::Uri::from_file_path(new_path)
 9790                .ok()
 9791                .map(|uri| uri.to_string())?;
 9792
 9793            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9794                let Some(filter) = local_store
 9795                    .language_server_paths_watched_for_rename
 9796                    .get(&language_server.server_id())
 9797                else {
 9798                    continue;
 9799                };
 9800
 9801                if filter.should_send_did_rename(&old_uri, is_dir) {
 9802                    language_server
 9803                        .notify::<DidRenameFiles>(RenameFilesParams {
 9804                            files: vec![FileRename {
 9805                                old_uri: old_uri.clone(),
 9806                                new_uri: new_uri.clone(),
 9807                            }],
 9808                        })
 9809                        .ok();
 9810                }
 9811            }
 9812            Some(())
 9813        });
 9814    }
 9815
 9816    pub(super) fn will_rename_entry(
 9817        this: WeakEntity<Self>,
 9818        worktree_id: WorktreeId,
 9819        old_path: &Path,
 9820        new_path: &Path,
 9821        is_dir: bool,
 9822        cx: AsyncApp,
 9823    ) -> Task<ProjectTransaction> {
 9824        let old_uri = lsp::Uri::from_file_path(old_path)
 9825            .ok()
 9826            .map(|uri| uri.to_string());
 9827        let new_uri = lsp::Uri::from_file_path(new_path)
 9828            .ok()
 9829            .map(|uri| uri.to_string());
 9830        cx.spawn(async move |cx| {
 9831            let mut tasks = vec![];
 9832            this.update(cx, |this, cx| {
 9833                let local_store = this.as_local()?;
 9834                let old_uri = old_uri?;
 9835                let new_uri = new_uri?;
 9836                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9837                    let Some(filter) = local_store
 9838                        .language_server_paths_watched_for_rename
 9839                        .get(&language_server.server_id())
 9840                    else {
 9841                        continue;
 9842                    };
 9843
 9844                    if !filter.should_send_will_rename(&old_uri, is_dir) {
 9845                        continue;
 9846                    }
 9847                    let request_timeout = ProjectSettings::get_global(cx)
 9848                        .global_lsp_settings
 9849                        .get_request_timeout();
 9850
 9851                    let apply_edit = cx.spawn({
 9852                        let old_uri = old_uri.clone();
 9853                        let new_uri = new_uri.clone();
 9854                        let language_server = language_server.clone();
 9855                        async move |this, cx| {
 9856                            let edit = language_server
 9857                                .request::<WillRenameFiles>(
 9858                                    RenameFilesParams {
 9859                                        files: vec![FileRename { old_uri, new_uri }],
 9860                                    },
 9861                                    request_timeout,
 9862                                )
 9863                                .await
 9864                                .into_response()
 9865                                .context("will rename files")
 9866                                .log_err()
 9867                                .flatten()?;
 9868
 9869                            LocalLspStore::deserialize_workspace_edit(
 9870                                this.upgrade()?,
 9871                                edit,
 9872                                false,
 9873                                language_server.clone(),
 9874                                cx,
 9875                            )
 9876                            .await
 9877                            .ok()
 9878                        }
 9879                    });
 9880                    tasks.push(apply_edit);
 9881                }
 9882                Some(())
 9883            })
 9884            .ok()
 9885            .flatten();
 9886            let mut merged_transaction = ProjectTransaction::default();
 9887            for task in tasks {
 9888                // Await on tasks sequentially so that the order of application of edits is deterministic
 9889                // (at least with regards to the order of registration of language servers)
 9890                if let Some(transaction) = task.await {
 9891                    for (buffer, buffer_transaction) in transaction.0 {
 9892                        merged_transaction.0.insert(buffer, buffer_transaction);
 9893                    }
 9894                }
 9895            }
 9896            merged_transaction
 9897        })
 9898    }
 9899
 9900    fn lsp_notify_abs_paths_changed(
 9901        &mut self,
 9902        server_id: LanguageServerId,
 9903        changes: Vec<PathEvent>,
 9904    ) {
 9905        maybe!({
 9906            let server = self.language_server_for_id(server_id)?;
 9907            let changes = changes
 9908                .into_iter()
 9909                .filter_map(|event| {
 9910                    let typ = match event.kind? {
 9911                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9912                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9913                        PathEventKind::Changed | PathEventKind::Rescan => {
 9914                            lsp::FileChangeType::CHANGED
 9915                        }
 9916                    };
 9917                    Some(lsp::FileEvent {
 9918                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9919                        typ,
 9920                    })
 9921                })
 9922                .collect::<Vec<_>>();
 9923            if !changes.is_empty() {
 9924                server
 9925                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9926                        lsp::DidChangeWatchedFilesParams { changes },
 9927                    )
 9928                    .ok();
 9929            }
 9930            Some(())
 9931        });
 9932    }
 9933
 9934    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9935        self.as_local()?.language_server_for_id(id)
 9936    }
 9937
 9938    fn on_lsp_progress(
 9939        &mut self,
 9940        progress_params: lsp::ProgressParams,
 9941        language_server_id: LanguageServerId,
 9942        disk_based_diagnostics_progress_token: Option<String>,
 9943        cx: &mut Context<Self>,
 9944    ) {
 9945        match progress_params.value {
 9946            lsp::ProgressParamsValue::WorkDone(progress) => {
 9947                self.handle_work_done_progress(
 9948                    progress,
 9949                    language_server_id,
 9950                    disk_based_diagnostics_progress_token,
 9951                    ProgressToken::from_lsp(progress_params.token),
 9952                    cx,
 9953                );
 9954            }
 9955            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9956                let registration_id = match progress_params.token {
 9957                    lsp::NumberOrString::Number(_) => None,
 9958                    lsp::NumberOrString::String(token) => token
 9959                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9960                        .map(|(_, id)| id.to_owned()),
 9961                };
 9962                if let Some(LanguageServerState::Running {
 9963                    workspace_diagnostics_refresh_tasks,
 9964                    ..
 9965                }) = self
 9966                    .as_local_mut()
 9967                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9968                    && let Some(workspace_diagnostics) =
 9969                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9970                {
 9971                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9972                    self.apply_workspace_diagnostic_report(
 9973                        language_server_id,
 9974                        report,
 9975                        registration_id.map(SharedString::from),
 9976                        cx,
 9977                    )
 9978                }
 9979            }
 9980        }
 9981    }
 9982
 9983    fn handle_work_done_progress(
 9984        &mut self,
 9985        progress: lsp::WorkDoneProgress,
 9986        language_server_id: LanguageServerId,
 9987        disk_based_diagnostics_progress_token: Option<String>,
 9988        token: ProgressToken,
 9989        cx: &mut Context<Self>,
 9990    ) {
 9991        let language_server_status =
 9992            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9993                status
 9994            } else {
 9995                return;
 9996            };
 9997
 9998        if !language_server_status.progress_tokens.contains(&token) {
 9999            return;
10000        }
10001
10002        let is_disk_based_diagnostics_progress =
10003            if let (Some(disk_based_token), ProgressToken::String(token)) =
10004                (&disk_based_diagnostics_progress_token, &token)
10005            {
10006                token.starts_with(disk_based_token)
10007            } else {
10008                false
10009            };
10010
10011        match progress {
10012            lsp::WorkDoneProgress::Begin(report) => {
10013                if is_disk_based_diagnostics_progress {
10014                    self.disk_based_diagnostics_started(language_server_id, cx);
10015                }
10016                self.on_lsp_work_start(
10017                    language_server_id,
10018                    token.clone(),
10019                    LanguageServerProgress {
10020                        title: Some(report.title),
10021                        is_disk_based_diagnostics_progress,
10022                        is_cancellable: report.cancellable.unwrap_or(false),
10023                        message: report.message.clone(),
10024                        percentage: report.percentage.map(|p| p as usize),
10025                        last_update_at: cx.background_executor().now(),
10026                    },
10027                    cx,
10028                );
10029            }
10030            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10031                language_server_id,
10032                token,
10033                LanguageServerProgress {
10034                    title: None,
10035                    is_disk_based_diagnostics_progress,
10036                    is_cancellable: report.cancellable.unwrap_or(false),
10037                    message: report.message,
10038                    percentage: report.percentage.map(|p| p as usize),
10039                    last_update_at: cx.background_executor().now(),
10040                },
10041                cx,
10042            ),
10043            lsp::WorkDoneProgress::End(_) => {
10044                language_server_status.progress_tokens.remove(&token);
10045                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10046                if is_disk_based_diagnostics_progress {
10047                    self.disk_based_diagnostics_finished(language_server_id, cx);
10048                }
10049            }
10050        }
10051    }
10052
10053    fn on_lsp_work_start(
10054        &mut self,
10055        language_server_id: LanguageServerId,
10056        token: ProgressToken,
10057        progress: LanguageServerProgress,
10058        cx: &mut Context<Self>,
10059    ) {
10060        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10061            status.pending_work.insert(token.clone(), progress.clone());
10062            cx.notify();
10063        }
10064        cx.emit(LspStoreEvent::LanguageServerUpdate {
10065            language_server_id,
10066            name: self
10067                .language_server_adapter_for_id(language_server_id)
10068                .map(|adapter| adapter.name()),
10069            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10070                token: Some(token.to_proto()),
10071                title: progress.title,
10072                message: progress.message,
10073                percentage: progress.percentage.map(|p| p as u32),
10074                is_cancellable: Some(progress.is_cancellable),
10075            }),
10076        })
10077    }
10078
10079    fn on_lsp_work_progress(
10080        &mut self,
10081        language_server_id: LanguageServerId,
10082        token: ProgressToken,
10083        progress: LanguageServerProgress,
10084        cx: &mut Context<Self>,
10085    ) {
10086        let mut did_update = false;
10087        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10088            match status.pending_work.entry(token.clone()) {
10089                btree_map::Entry::Vacant(entry) => {
10090                    entry.insert(progress.clone());
10091                    did_update = true;
10092                }
10093                btree_map::Entry::Occupied(mut entry) => {
10094                    let entry = entry.get_mut();
10095                    if (progress.last_update_at - entry.last_update_at)
10096                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10097                    {
10098                        entry.last_update_at = progress.last_update_at;
10099                        if progress.message.is_some() {
10100                            entry.message = progress.message.clone();
10101                        }
10102                        if progress.percentage.is_some() {
10103                            entry.percentage = progress.percentage;
10104                        }
10105                        if progress.is_cancellable != entry.is_cancellable {
10106                            entry.is_cancellable = progress.is_cancellable;
10107                        }
10108                        did_update = true;
10109                    }
10110                }
10111            }
10112        }
10113
10114        if did_update {
10115            cx.emit(LspStoreEvent::LanguageServerUpdate {
10116                language_server_id,
10117                name: self
10118                    .language_server_adapter_for_id(language_server_id)
10119                    .map(|adapter| adapter.name()),
10120                message: proto::update_language_server::Variant::WorkProgress(
10121                    proto::LspWorkProgress {
10122                        token: Some(token.to_proto()),
10123                        message: progress.message,
10124                        percentage: progress.percentage.map(|p| p as u32),
10125                        is_cancellable: Some(progress.is_cancellable),
10126                    },
10127                ),
10128            })
10129        }
10130    }
10131
10132    fn on_lsp_work_end(
10133        &mut self,
10134        language_server_id: LanguageServerId,
10135        token: ProgressToken,
10136        cx: &mut Context<Self>,
10137    ) {
10138        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10139            if let Some(work) = status.pending_work.remove(&token)
10140                && !work.is_disk_based_diagnostics_progress
10141            {
10142                cx.emit(LspStoreEvent::RefreshInlayHints {
10143                    server_id: language_server_id,
10144                    request_id: None,
10145                });
10146            }
10147            cx.notify();
10148        }
10149
10150        cx.emit(LspStoreEvent::LanguageServerUpdate {
10151            language_server_id,
10152            name: self
10153                .language_server_adapter_for_id(language_server_id)
10154                .map(|adapter| adapter.name()),
10155            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10156                token: Some(token.to_proto()),
10157            }),
10158        })
10159    }
10160
10161    pub async fn handle_resolve_completion_documentation(
10162        this: Entity<Self>,
10163        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10164        mut cx: AsyncApp,
10165    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10166        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10167
10168        let completion = this
10169            .read_with(&cx, |this, cx| {
10170                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10171                let server = this
10172                    .language_server_for_id(id)
10173                    .with_context(|| format!("No language server {id}"))?;
10174
10175                let request_timeout = ProjectSettings::get_global(cx)
10176                    .global_lsp_settings
10177                    .get_request_timeout();
10178
10179                anyhow::Ok(cx.background_spawn(async move {
10180                    let can_resolve = server
10181                        .capabilities()
10182                        .completion_provider
10183                        .as_ref()
10184                        .and_then(|options| options.resolve_provider)
10185                        .unwrap_or(false);
10186                    if can_resolve {
10187                        server
10188                            .request::<lsp::request::ResolveCompletionItem>(
10189                                lsp_completion,
10190                                request_timeout,
10191                            )
10192                            .await
10193                            .into_response()
10194                            .context("resolve completion item")
10195                    } else {
10196                        anyhow::Ok(lsp_completion)
10197                    }
10198                }))
10199            })?
10200            .await?;
10201
10202        let mut documentation_is_markdown = false;
10203        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10204        let documentation = match completion.documentation {
10205            Some(lsp::Documentation::String(text)) => text,
10206
10207            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10208                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10209                value
10210            }
10211
10212            _ => String::new(),
10213        };
10214
10215        // If we have a new buffer_id, that means we're talking to a new client
10216        // and want to check for new text_edits in the completion too.
10217        let mut old_replace_start = None;
10218        let mut old_replace_end = None;
10219        let mut old_insert_start = None;
10220        let mut old_insert_end = None;
10221        let mut new_text = String::default();
10222        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10223            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10224                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10225                anyhow::Ok(buffer.read(cx).snapshot())
10226            })?;
10227
10228            if let Some(text_edit) = completion.text_edit.as_ref() {
10229                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10230
10231                if let Some(mut edit) = edit {
10232                    LineEnding::normalize(&mut edit.new_text);
10233
10234                    new_text = edit.new_text;
10235                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10236                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10237                    if let Some(insert_range) = edit.insert_range {
10238                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10239                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10240                    }
10241                }
10242            }
10243        }
10244
10245        Ok(proto::ResolveCompletionDocumentationResponse {
10246            documentation,
10247            documentation_is_markdown,
10248            old_replace_start,
10249            old_replace_end,
10250            new_text,
10251            lsp_completion,
10252            old_insert_start,
10253            old_insert_end,
10254        })
10255    }
10256
10257    async fn handle_on_type_formatting(
10258        this: Entity<Self>,
10259        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10260        mut cx: AsyncApp,
10261    ) -> Result<proto::OnTypeFormattingResponse> {
10262        let on_type_formatting = this.update(&mut cx, |this, cx| {
10263            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10264            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10265            let position = envelope
10266                .payload
10267                .position
10268                .and_then(deserialize_anchor)
10269                .context("invalid position")?;
10270            anyhow::Ok(this.apply_on_type_formatting(
10271                buffer,
10272                position,
10273                envelope.payload.trigger.clone(),
10274                cx,
10275            ))
10276        })?;
10277
10278        let transaction = on_type_formatting
10279            .await?
10280            .as_ref()
10281            .map(language::proto::serialize_transaction);
10282        Ok(proto::OnTypeFormattingResponse { transaction })
10283    }
10284
10285    async fn handle_pull_workspace_diagnostics(
10286        lsp_store: Entity<Self>,
10287        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10288        mut cx: AsyncApp,
10289    ) -> Result<proto::Ack> {
10290        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10291        lsp_store.update(&mut cx, |lsp_store, _| {
10292            lsp_store.pull_workspace_diagnostics(server_id);
10293        });
10294        Ok(proto::Ack {})
10295    }
10296
10297    async fn handle_open_buffer_for_symbol(
10298        this: Entity<Self>,
10299        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10300        mut cx: AsyncApp,
10301    ) -> Result<proto::OpenBufferForSymbolResponse> {
10302        let peer_id = envelope.original_sender_id().unwrap_or_default();
10303        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10304        let symbol = Self::deserialize_symbol(symbol)?;
10305        this.read_with(&cx, |this, _| {
10306            if let SymbolLocation::OutsideProject {
10307                abs_path,
10308                signature,
10309            } = &symbol.path
10310            {
10311                let new_signature = this.symbol_signature(&abs_path);
10312                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10313            }
10314            Ok(())
10315        })?;
10316        let buffer = this
10317            .update(&mut cx, |this, cx| {
10318                this.open_buffer_for_symbol(
10319                    &Symbol {
10320                        language_server_name: symbol.language_server_name,
10321                        source_worktree_id: symbol.source_worktree_id,
10322                        source_language_server_id: symbol.source_language_server_id,
10323                        path: symbol.path,
10324                        name: symbol.name,
10325                        kind: symbol.kind,
10326                        range: symbol.range,
10327                        label: CodeLabel::default(),
10328                        container_name: symbol.container_name,
10329                    },
10330                    cx,
10331                )
10332            })
10333            .await?;
10334
10335        this.update(&mut cx, |this, cx| {
10336            let is_private = buffer
10337                .read(cx)
10338                .file()
10339                .map(|f| f.is_private())
10340                .unwrap_or_default();
10341            if is_private {
10342                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10343            } else {
10344                this.buffer_store
10345                    .update(cx, |buffer_store, cx| {
10346                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10347                    })
10348                    .detach_and_log_err(cx);
10349                let buffer_id = buffer.read(cx).remote_id().to_proto();
10350                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10351            }
10352        })
10353    }
10354
10355    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10356        let mut hasher = Sha256::new();
10357        hasher.update(abs_path.to_string_lossy().as_bytes());
10358        hasher.update(self.nonce.to_be_bytes());
10359        hasher.finalize().as_slice().try_into().unwrap()
10360    }
10361
10362    pub async fn handle_get_project_symbols(
10363        this: Entity<Self>,
10364        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10365        mut cx: AsyncApp,
10366    ) -> Result<proto::GetProjectSymbolsResponse> {
10367        let symbols = this
10368            .update(&mut cx, |this, cx| {
10369                this.symbols(&envelope.payload.query, cx)
10370            })
10371            .await?;
10372
10373        Ok(proto::GetProjectSymbolsResponse {
10374            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10375        })
10376    }
10377
10378    pub async fn handle_restart_language_servers(
10379        this: Entity<Self>,
10380        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10381        mut cx: AsyncApp,
10382    ) -> Result<proto::Ack> {
10383        this.update(&mut cx, |lsp_store, cx| {
10384            let buffers =
10385                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10386            lsp_store.restart_language_servers_for_buffers(
10387                buffers,
10388                envelope
10389                    .payload
10390                    .only_servers
10391                    .into_iter()
10392                    .filter_map(|selector| {
10393                        Some(match selector.selector? {
10394                            proto::language_server_selector::Selector::ServerId(server_id) => {
10395                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10396                            }
10397                            proto::language_server_selector::Selector::Name(name) => {
10398                                LanguageServerSelector::Name(LanguageServerName(
10399                                    SharedString::from(name),
10400                                ))
10401                            }
10402                        })
10403                    })
10404                    .collect(),
10405                cx,
10406            );
10407        });
10408
10409        Ok(proto::Ack {})
10410    }
10411
10412    pub async fn handle_stop_language_servers(
10413        lsp_store: Entity<Self>,
10414        envelope: TypedEnvelope<proto::StopLanguageServers>,
10415        mut cx: AsyncApp,
10416    ) -> Result<proto::Ack> {
10417        lsp_store.update(&mut cx, |lsp_store, cx| {
10418            if envelope.payload.all
10419                && envelope.payload.also_servers.is_empty()
10420                && envelope.payload.buffer_ids.is_empty()
10421            {
10422                lsp_store.stop_all_language_servers(cx);
10423            } else {
10424                let buffers =
10425                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10426                lsp_store
10427                    .stop_language_servers_for_buffers(
10428                        buffers,
10429                        envelope
10430                            .payload
10431                            .also_servers
10432                            .into_iter()
10433                            .filter_map(|selector| {
10434                                Some(match selector.selector? {
10435                                    proto::language_server_selector::Selector::ServerId(
10436                                        server_id,
10437                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10438                                        server_id,
10439                                    )),
10440                                    proto::language_server_selector::Selector::Name(name) => {
10441                                        LanguageServerSelector::Name(LanguageServerName(
10442                                            SharedString::from(name),
10443                                        ))
10444                                    }
10445                                })
10446                            })
10447                            .collect(),
10448                        cx,
10449                    )
10450                    .detach_and_log_err(cx);
10451            }
10452        });
10453
10454        Ok(proto::Ack {})
10455    }
10456
10457    pub async fn handle_cancel_language_server_work(
10458        lsp_store: Entity<Self>,
10459        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10460        mut cx: AsyncApp,
10461    ) -> Result<proto::Ack> {
10462        lsp_store.update(&mut cx, |lsp_store, cx| {
10463            if let Some(work) = envelope.payload.work {
10464                match work {
10465                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10466                        let buffers =
10467                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10468                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10469                    }
10470                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10471                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10472                        let token = work
10473                            .token
10474                            .map(|token| {
10475                                ProgressToken::from_proto(token)
10476                                    .context("invalid work progress token")
10477                            })
10478                            .transpose()?;
10479                        lsp_store.cancel_language_server_work(server_id, token, cx);
10480                    }
10481                }
10482            }
10483            anyhow::Ok(())
10484        })?;
10485
10486        Ok(proto::Ack {})
10487    }
10488
10489    fn buffer_ids_to_buffers(
10490        &mut self,
10491        buffer_ids: impl Iterator<Item = u64>,
10492        cx: &mut Context<Self>,
10493    ) -> Vec<Entity<Buffer>> {
10494        buffer_ids
10495            .into_iter()
10496            .flat_map(|buffer_id| {
10497                self.buffer_store
10498                    .read(cx)
10499                    .get(BufferId::new(buffer_id).log_err()?)
10500            })
10501            .collect::<Vec<_>>()
10502    }
10503
10504    async fn handle_apply_additional_edits_for_completion(
10505        this: Entity<Self>,
10506        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10507        mut cx: AsyncApp,
10508    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10509        let (buffer, completion, all_commit_ranges) = this.update(&mut cx, |this, cx| {
10510            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10511            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10512            let completion = Self::deserialize_completion(
10513                envelope.payload.completion.context("invalid completion")?,
10514            )?;
10515            let all_commit_ranges = envelope
10516                .payload
10517                .all_commit_ranges
10518                .into_iter()
10519                .map(language::proto::deserialize_anchor_range)
10520                .collect::<Result<Vec<_>, _>>()?;
10521            anyhow::Ok((buffer, completion, all_commit_ranges))
10522        })?;
10523
10524        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10525            this.apply_additional_edits_for_completion(
10526                buffer,
10527                Rc::new(RefCell::new(Box::new([Completion {
10528                    replace_range: completion.replace_range,
10529                    new_text: completion.new_text,
10530                    source: completion.source,
10531                    documentation: None,
10532                    label: CodeLabel::default(),
10533                    match_start: None,
10534                    snippet_deduplication_key: None,
10535                    insert_text_mode: None,
10536                    icon_path: None,
10537                    confirm: None,
10538                }]))),
10539                0,
10540                false,
10541                all_commit_ranges,
10542                cx,
10543            )
10544        });
10545
10546        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10547            transaction: apply_additional_edits
10548                .await?
10549                .as_ref()
10550                .map(language::proto::serialize_transaction),
10551        })
10552    }
10553
10554    pub fn last_formatting_failure(&self) -> Option<&str> {
10555        self.last_formatting_failure.as_deref()
10556    }
10557
10558    pub fn reset_last_formatting_failure(&mut self) {
10559        self.last_formatting_failure = None;
10560    }
10561
10562    pub fn environment_for_buffer(
10563        &self,
10564        buffer: &Entity<Buffer>,
10565        cx: &mut Context<Self>,
10566    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10567        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10568            environment.update(cx, |env, cx| {
10569                env.buffer_environment(buffer, &self.worktree_store, cx)
10570            })
10571        } else {
10572            Task::ready(None).shared()
10573        }
10574    }
10575
10576    pub fn format(
10577        &mut self,
10578        buffers: HashSet<Entity<Buffer>>,
10579        target: LspFormatTarget,
10580        push_to_history: bool,
10581        trigger: FormatTrigger,
10582        cx: &mut Context<Self>,
10583    ) -> Task<anyhow::Result<ProjectTransaction>> {
10584        let logger = zlog::scoped!("format");
10585        if self.as_local().is_some() {
10586            zlog::trace!(logger => "Formatting locally");
10587            let logger = zlog::scoped!(logger => "local");
10588            let buffers = buffers
10589                .into_iter()
10590                .map(|buffer_handle| {
10591                    let buffer = buffer_handle.read(cx);
10592                    let buffer_abs_path = File::from_dyn(buffer.file())
10593                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10594
10595                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10596                })
10597                .collect::<Vec<_>>();
10598
10599            cx.spawn(async move |lsp_store, cx| {
10600                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10601
10602                for (handle, abs_path, id) in buffers {
10603                    let env = lsp_store
10604                        .update(cx, |lsp_store, cx| {
10605                            lsp_store.environment_for_buffer(&handle, cx)
10606                        })?
10607                        .await;
10608
10609                    let ranges = match &target {
10610                        LspFormatTarget::Buffers => None,
10611                        LspFormatTarget::Ranges(ranges) => {
10612                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10613                        }
10614                    };
10615
10616                    formattable_buffers.push(FormattableBuffer {
10617                        handle,
10618                        abs_path,
10619                        env,
10620                        ranges,
10621                    });
10622                }
10623                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10624
10625                let format_timer = zlog::time!(logger => "Formatting buffers");
10626                let result = LocalLspStore::format_locally(
10627                    lsp_store.clone(),
10628                    formattable_buffers,
10629                    push_to_history,
10630                    trigger,
10631                    logger,
10632                    cx,
10633                )
10634                .await;
10635                format_timer.end();
10636
10637                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10638
10639                lsp_store.update(cx, |lsp_store, _| {
10640                    lsp_store.update_last_formatting_failure(&result);
10641                })?;
10642
10643                result
10644            })
10645        } else if let Some((client, project_id)) = self.upstream_client() {
10646            zlog::trace!(logger => "Formatting remotely");
10647            let logger = zlog::scoped!(logger => "remote");
10648
10649            let buffer_ranges = match &target {
10650                LspFormatTarget::Buffers => Vec::new(),
10651                LspFormatTarget::Ranges(ranges) => ranges
10652                    .iter()
10653                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10654                        buffer_id: buffer_id.to_proto(),
10655                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10656                    })
10657                    .collect(),
10658            };
10659
10660            let buffer_store = self.buffer_store();
10661            cx.spawn(async move |lsp_store, cx| {
10662                zlog::trace!(logger => "Sending remote format request");
10663                let request_timer = zlog::time!(logger => "remote format request");
10664                let result = client
10665                    .request(proto::FormatBuffers {
10666                        project_id,
10667                        trigger: trigger as i32,
10668                        buffer_ids: buffers
10669                            .iter()
10670                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10671                            .collect(),
10672                        buffer_ranges,
10673                    })
10674                    .await
10675                    .and_then(|result| result.transaction.context("missing transaction"));
10676                request_timer.end();
10677
10678                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10679
10680                lsp_store.update(cx, |lsp_store, _| {
10681                    lsp_store.update_last_formatting_failure(&result);
10682                })?;
10683
10684                let transaction_response = result?;
10685                let _timer = zlog::time!(logger => "deserializing project transaction");
10686                buffer_store
10687                    .update(cx, |buffer_store, cx| {
10688                        buffer_store.deserialize_project_transaction(
10689                            transaction_response,
10690                            push_to_history,
10691                            cx,
10692                        )
10693                    })
10694                    .await
10695            })
10696        } else {
10697            zlog::trace!(logger => "Not formatting");
10698            Task::ready(Ok(ProjectTransaction::default()))
10699        }
10700    }
10701
10702    async fn handle_format_buffers(
10703        this: Entity<Self>,
10704        envelope: TypedEnvelope<proto::FormatBuffers>,
10705        mut cx: AsyncApp,
10706    ) -> Result<proto::FormatBuffersResponse> {
10707        let sender_id = envelope.original_sender_id().unwrap_or_default();
10708        let format = this.update(&mut cx, |this, cx| {
10709            let mut buffers = HashSet::default();
10710            for buffer_id in &envelope.payload.buffer_ids {
10711                let buffer_id = BufferId::new(*buffer_id)?;
10712                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10713            }
10714
10715            let target = if envelope.payload.buffer_ranges.is_empty() {
10716                LspFormatTarget::Buffers
10717            } else {
10718                let mut ranges_map = BTreeMap::new();
10719                for buffer_range in &envelope.payload.buffer_ranges {
10720                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10721                    let ranges: Result<Vec<_>> = buffer_range
10722                        .ranges
10723                        .iter()
10724                        .map(|range| {
10725                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10726                        })
10727                        .collect();
10728                    ranges_map.insert(buffer_id, ranges?);
10729                }
10730                LspFormatTarget::Ranges(ranges_map)
10731            };
10732
10733            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10734            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10735        })?;
10736
10737        let project_transaction = format.await?;
10738        let project_transaction = this.update(&mut cx, |this, cx| {
10739            this.buffer_store.update(cx, |buffer_store, cx| {
10740                buffer_store.serialize_project_transaction_for_peer(
10741                    project_transaction,
10742                    sender_id,
10743                    cx,
10744                )
10745            })
10746        });
10747        Ok(proto::FormatBuffersResponse {
10748            transaction: Some(project_transaction),
10749        })
10750    }
10751
10752    async fn handle_apply_code_action_kind(
10753        this: Entity<Self>,
10754        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10755        mut cx: AsyncApp,
10756    ) -> Result<proto::ApplyCodeActionKindResponse> {
10757        let sender_id = envelope.original_sender_id().unwrap_or_default();
10758        let format = this.update(&mut cx, |this, cx| {
10759            let mut buffers = HashSet::default();
10760            for buffer_id in &envelope.payload.buffer_ids {
10761                let buffer_id = BufferId::new(*buffer_id)?;
10762                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10763            }
10764            let kind = match envelope.payload.kind.as_str() {
10765                "" => CodeActionKind::EMPTY,
10766                "quickfix" => CodeActionKind::QUICKFIX,
10767                "refactor" => CodeActionKind::REFACTOR,
10768                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10769                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10770                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10771                "source" => CodeActionKind::SOURCE,
10772                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10773                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10774                _ => anyhow::bail!(
10775                    "Invalid code action kind {}",
10776                    envelope.payload.kind.as_str()
10777                ),
10778            };
10779            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10780        })?;
10781
10782        let project_transaction = format.await?;
10783        let project_transaction = this.update(&mut cx, |this, cx| {
10784            this.buffer_store.update(cx, |buffer_store, cx| {
10785                buffer_store.serialize_project_transaction_for_peer(
10786                    project_transaction,
10787                    sender_id,
10788                    cx,
10789                )
10790            })
10791        });
10792        Ok(proto::ApplyCodeActionKindResponse {
10793            transaction: Some(project_transaction),
10794        })
10795    }
10796
10797    async fn shutdown_language_server(
10798        server_state: Option<LanguageServerState>,
10799        name: LanguageServerName,
10800        cx: &mut AsyncApp,
10801    ) {
10802        let server = match server_state {
10803            Some(LanguageServerState::Starting { startup, .. }) => {
10804                let mut timer = cx
10805                    .background_executor()
10806                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10807                    .fuse();
10808
10809                select! {
10810                    server = startup.fuse() => server,
10811                    () = timer => {
10812                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10813                        None
10814                    },
10815                }
10816            }
10817
10818            Some(LanguageServerState::Running { server, .. }) => Some(server),
10819
10820            None => None,
10821        };
10822
10823        let Some(server) = server else { return };
10824        if let Some(shutdown) = server.shutdown() {
10825            shutdown.await;
10826        }
10827    }
10828
10829    // Returns a list of all of the worktrees which no longer have a language server and the root path
10830    // for the stopped server
10831    fn stop_local_language_server(
10832        &mut self,
10833        server_id: LanguageServerId,
10834        cx: &mut Context<Self>,
10835    ) -> Task<()> {
10836        let local = match &mut self.mode {
10837            LspStoreMode::Local(local) => local,
10838            _ => {
10839                return Task::ready(());
10840            }
10841        };
10842
10843        // Remove this server ID from all entries in the given worktree.
10844        local
10845            .language_server_ids
10846            .retain(|_, state| state.id != server_id);
10847        self.buffer_store.update(cx, |buffer_store, cx| {
10848            for buffer in buffer_store.buffers() {
10849                buffer.update(cx, |buffer, cx| {
10850                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10851                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10852                });
10853            }
10854        });
10855
10856        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
10857        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10858            summaries.retain(|path, summaries_by_server_id| {
10859                if summaries_by_server_id.remove(&server_id).is_some() {
10860                    if let Some((client, project_id)) = self.downstream_client.clone() {
10861                        client
10862                            .send(proto::UpdateDiagnosticSummary {
10863                                project_id,
10864                                worktree_id: worktree_id.to_proto(),
10865                                summary: Some(proto::DiagnosticSummary {
10866                                    path: path.as_ref().to_proto(),
10867                                    language_server_id: server_id.0 as u64,
10868                                    error_count: 0,
10869                                    warning_count: 0,
10870                                }),
10871                                more_summaries: Vec::new(),
10872                            })
10873                            .log_err();
10874                    }
10875                    cleared_paths.push(ProjectPath {
10876                        worktree_id: *worktree_id,
10877                        path: path.clone(),
10878                    });
10879                    !summaries_by_server_id.is_empty()
10880                } else {
10881                    true
10882                }
10883            });
10884        }
10885        if !cleared_paths.is_empty() {
10886            cx.emit(LspStoreEvent::DiagnosticsUpdated {
10887                server_id,
10888                paths: cleared_paths,
10889            });
10890        }
10891
10892        let local = self.as_local_mut().unwrap();
10893        for diagnostics in local.diagnostics.values_mut() {
10894            diagnostics.retain(|_, diagnostics_by_server_id| {
10895                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10896                    diagnostics_by_server_id.remove(ix);
10897                    !diagnostics_by_server_id.is_empty()
10898                } else {
10899                    true
10900                }
10901            });
10902        }
10903        local.language_server_watched_paths.remove(&server_id);
10904
10905        let server_state = local.language_servers.remove(&server_id);
10906        self.cleanup_lsp_data(server_id);
10907        let name = self
10908            .language_server_statuses
10909            .remove(&server_id)
10910            .map(|status| status.name)
10911            .or_else(|| {
10912                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10913                    Some(adapter.name())
10914                } else {
10915                    None
10916                }
10917            });
10918
10919        if let Some(name) = name {
10920            log::info!("stopping language server {name}");
10921            self.languages
10922                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10923            cx.notify();
10924
10925            return cx.spawn(async move |lsp_store, cx| {
10926                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10927                lsp_store
10928                    .update(cx, |lsp_store, cx| {
10929                        lsp_store
10930                            .languages
10931                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10932                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10933                        cx.notify();
10934                    })
10935                    .ok();
10936            });
10937        }
10938
10939        if server_state.is_some() {
10940            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10941        }
10942        Task::ready(())
10943    }
10944
10945    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10946        self.shutdown_all_language_servers(cx).detach();
10947    }
10948
10949    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
10950        if let Some((client, project_id)) = self.upstream_client() {
10951            let request = client.request(proto::StopLanguageServers {
10952                project_id,
10953                buffer_ids: Vec::new(),
10954                also_servers: Vec::new(),
10955                all: true,
10956            });
10957            cx.background_spawn(async move {
10958                request.await.ok();
10959            })
10960        } else {
10961            let Some(local) = self.as_local_mut() else {
10962                return Task::ready(());
10963            };
10964            let language_servers_to_stop = local
10965                .language_server_ids
10966                .values()
10967                .map(|state| state.id)
10968                .collect();
10969            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10970            let tasks = language_servers_to_stop
10971                .into_iter()
10972                .map(|server| self.stop_local_language_server(server, cx))
10973                .collect::<Vec<_>>();
10974            cx.background_spawn(async move {
10975                futures::future::join_all(tasks).await;
10976            })
10977        }
10978    }
10979
10980    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
10981        let buffers = self.buffer_store.read(cx).buffers().collect();
10982        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
10983    }
10984
10985    pub fn restart_language_servers_for_buffers(
10986        &mut self,
10987        buffers: Vec<Entity<Buffer>>,
10988        only_restart_servers: HashSet<LanguageServerSelector>,
10989        cx: &mut Context<Self>,
10990    ) {
10991        if let Some((client, project_id)) = self.upstream_client() {
10992            let request = client.request(proto::RestartLanguageServers {
10993                project_id,
10994                buffer_ids: buffers
10995                    .into_iter()
10996                    .map(|b| b.read(cx).remote_id().to_proto())
10997                    .collect(),
10998                only_servers: only_restart_servers
10999                    .into_iter()
11000                    .map(|selector| {
11001                        let selector = match selector {
11002                            LanguageServerSelector::Id(language_server_id) => {
11003                                proto::language_server_selector::Selector::ServerId(
11004                                    language_server_id.to_proto(),
11005                                )
11006                            }
11007                            LanguageServerSelector::Name(language_server_name) => {
11008                                proto::language_server_selector::Selector::Name(
11009                                    language_server_name.to_string(),
11010                                )
11011                            }
11012                        };
11013                        proto::LanguageServerSelector {
11014                            selector: Some(selector),
11015                        }
11016                    })
11017                    .collect(),
11018                all: false,
11019            });
11020            cx.background_spawn(request).detach_and_log_err(cx);
11021        } else {
11022            let stop_task = if only_restart_servers.is_empty() {
11023                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11024            } else {
11025                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11026            };
11027            cx.spawn(async move |lsp_store, cx| {
11028                stop_task.await;
11029                lsp_store.update(cx, |lsp_store, cx| {
11030                    for buffer in buffers {
11031                        lsp_store.register_buffer_with_language_servers(
11032                            &buffer,
11033                            only_restart_servers.clone(),
11034                            true,
11035                            cx,
11036                        );
11037                    }
11038                })
11039            })
11040            .detach();
11041        }
11042    }
11043
11044    pub fn stop_language_servers_for_buffers(
11045        &mut self,
11046        buffers: Vec<Entity<Buffer>>,
11047        also_stop_servers: HashSet<LanguageServerSelector>,
11048        cx: &mut Context<Self>,
11049    ) -> Task<Result<()>> {
11050        if let Some((client, project_id)) = self.upstream_client() {
11051            let request = client.request(proto::StopLanguageServers {
11052                project_id,
11053                buffer_ids: buffers
11054                    .into_iter()
11055                    .map(|b| b.read(cx).remote_id().to_proto())
11056                    .collect(),
11057                also_servers: also_stop_servers
11058                    .into_iter()
11059                    .map(|selector| {
11060                        let selector = match selector {
11061                            LanguageServerSelector::Id(language_server_id) => {
11062                                proto::language_server_selector::Selector::ServerId(
11063                                    language_server_id.to_proto(),
11064                                )
11065                            }
11066                            LanguageServerSelector::Name(language_server_name) => {
11067                                proto::language_server_selector::Selector::Name(
11068                                    language_server_name.to_string(),
11069                                )
11070                            }
11071                        };
11072                        proto::LanguageServerSelector {
11073                            selector: Some(selector),
11074                        }
11075                    })
11076                    .collect(),
11077                all: false,
11078            });
11079            cx.background_spawn(async move {
11080                let _ = request.await?;
11081                Ok(())
11082            })
11083        } else {
11084            let task =
11085                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11086            cx.background_spawn(async move {
11087                task.await;
11088                Ok(())
11089            })
11090        }
11091    }
11092
11093    fn stop_local_language_servers_for_buffers(
11094        &mut self,
11095        buffers: &[Entity<Buffer>],
11096        also_stop_servers: HashSet<LanguageServerSelector>,
11097        cx: &mut Context<Self>,
11098    ) -> Task<()> {
11099        let Some(local) = self.as_local_mut() else {
11100            return Task::ready(());
11101        };
11102        let mut language_server_names_to_stop = BTreeSet::default();
11103        let mut language_servers_to_stop = also_stop_servers
11104            .into_iter()
11105            .flat_map(|selector| match selector {
11106                LanguageServerSelector::Id(id) => Some(id),
11107                LanguageServerSelector::Name(name) => {
11108                    language_server_names_to_stop.insert(name);
11109                    None
11110                }
11111            })
11112            .collect::<BTreeSet<_>>();
11113
11114        let mut covered_worktrees = HashSet::default();
11115        for buffer in buffers {
11116            buffer.update(cx, |buffer, cx| {
11117                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11118                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11119                    && covered_worktrees.insert(worktree_id)
11120                {
11121                    language_server_names_to_stop.retain(|name| {
11122                        let old_ids_count = language_servers_to_stop.len();
11123                        let all_language_servers_with_this_name = local
11124                            .language_server_ids
11125                            .iter()
11126                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11127                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11128                        old_ids_count == language_servers_to_stop.len()
11129                    });
11130                }
11131            });
11132        }
11133        for name in language_server_names_to_stop {
11134            language_servers_to_stop.extend(
11135                local
11136                    .language_server_ids
11137                    .iter()
11138                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11139            );
11140        }
11141
11142        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11143        let tasks = language_servers_to_stop
11144            .into_iter()
11145            .map(|server| self.stop_local_language_server(server, cx))
11146            .collect::<Vec<_>>();
11147
11148        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11149    }
11150
11151    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11152        let (worktree, relative_path) =
11153            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11154
11155        let project_path = ProjectPath {
11156            worktree_id: worktree.read(cx).id(),
11157            path: relative_path,
11158        };
11159
11160        Some(
11161            self.buffer_store()
11162                .read(cx)
11163                .get_by_path(&project_path)?
11164                .read(cx),
11165        )
11166    }
11167
11168    #[cfg(any(test, feature = "test-support"))]
11169    pub fn update_diagnostics(
11170        &mut self,
11171        server_id: LanguageServerId,
11172        diagnostics: lsp::PublishDiagnosticsParams,
11173        result_id: Option<SharedString>,
11174        source_kind: DiagnosticSourceKind,
11175        disk_based_sources: &[String],
11176        cx: &mut Context<Self>,
11177    ) -> Result<()> {
11178        self.merge_lsp_diagnostics(
11179            source_kind,
11180            vec![DocumentDiagnosticsUpdate {
11181                diagnostics,
11182                result_id,
11183                server_id,
11184                disk_based_sources: Cow::Borrowed(disk_based_sources),
11185                registration_id: None,
11186            }],
11187            |_, _, _| false,
11188            cx,
11189        )
11190    }
11191
11192    pub fn merge_lsp_diagnostics(
11193        &mut self,
11194        source_kind: DiagnosticSourceKind,
11195        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11196        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11197        cx: &mut Context<Self>,
11198    ) -> Result<()> {
11199        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11200        let updates = lsp_diagnostics
11201            .into_iter()
11202            .filter_map(|update| {
11203                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11204                Some(DocumentDiagnosticsUpdate {
11205                    diagnostics: self.lsp_to_document_diagnostics(
11206                        abs_path,
11207                        source_kind,
11208                        update.server_id,
11209                        update.diagnostics,
11210                        &update.disk_based_sources,
11211                        update.registration_id.clone(),
11212                    ),
11213                    result_id: update.result_id,
11214                    server_id: update.server_id,
11215                    disk_based_sources: update.disk_based_sources,
11216                    registration_id: update.registration_id,
11217                })
11218            })
11219            .collect();
11220        self.merge_diagnostic_entries(updates, merge, cx)?;
11221        Ok(())
11222    }
11223
11224    fn lsp_to_document_diagnostics(
11225        &mut self,
11226        document_abs_path: PathBuf,
11227        source_kind: DiagnosticSourceKind,
11228        server_id: LanguageServerId,
11229        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11230        disk_based_sources: &[String],
11231        registration_id: Option<SharedString>,
11232    ) -> DocumentDiagnostics {
11233        let mut diagnostics = Vec::default();
11234        let mut primary_diagnostic_group_ids = HashMap::default();
11235        let mut sources_by_group_id = HashMap::default();
11236        let mut supporting_diagnostics = HashMap::default();
11237
11238        let adapter = self.language_server_adapter_for_id(server_id);
11239
11240        // Ensure that primary diagnostics are always the most severe
11241        lsp_diagnostics
11242            .diagnostics
11243            .sort_by_key(|item| item.severity);
11244
11245        for diagnostic in &lsp_diagnostics.diagnostics {
11246            let source = diagnostic.source.as_ref();
11247            let range = range_from_lsp(diagnostic.range);
11248            let is_supporting = diagnostic
11249                .related_information
11250                .as_ref()
11251                .is_some_and(|infos| {
11252                    infos.iter().any(|info| {
11253                        primary_diagnostic_group_ids.contains_key(&(
11254                            source,
11255                            diagnostic.code.clone(),
11256                            range_from_lsp(info.location.range),
11257                        ))
11258                    })
11259                });
11260
11261            let is_unnecessary = diagnostic
11262                .tags
11263                .as_ref()
11264                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11265
11266            let underline = self
11267                .language_server_adapter_for_id(server_id)
11268                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11269
11270            if is_supporting {
11271                supporting_diagnostics.insert(
11272                    (source, diagnostic.code.clone(), range),
11273                    (diagnostic.severity, is_unnecessary),
11274                );
11275            } else {
11276                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11277                let is_disk_based =
11278                    source.is_some_and(|source| disk_based_sources.contains(source));
11279
11280                sources_by_group_id.insert(group_id, source);
11281                primary_diagnostic_group_ids
11282                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11283
11284                diagnostics.push(DiagnosticEntry {
11285                    range,
11286                    diagnostic: Diagnostic {
11287                        source: diagnostic.source.clone(),
11288                        source_kind,
11289                        code: diagnostic.code.clone(),
11290                        code_description: diagnostic
11291                            .code_description
11292                            .as_ref()
11293                            .and_then(|d| d.href.clone()),
11294                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11295                        markdown: adapter.as_ref().and_then(|adapter| {
11296                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11297                        }),
11298                        message: diagnostic.message.trim().to_string(),
11299                        group_id,
11300                        is_primary: true,
11301                        is_disk_based,
11302                        is_unnecessary,
11303                        underline,
11304                        data: diagnostic.data.clone(),
11305                        registration_id: registration_id.clone(),
11306                    },
11307                });
11308                if let Some(infos) = &diagnostic.related_information {
11309                    for info in infos {
11310                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11311                            let range = range_from_lsp(info.location.range);
11312                            diagnostics.push(DiagnosticEntry {
11313                                range,
11314                                diagnostic: Diagnostic {
11315                                    source: diagnostic.source.clone(),
11316                                    source_kind,
11317                                    code: diagnostic.code.clone(),
11318                                    code_description: diagnostic
11319                                        .code_description
11320                                        .as_ref()
11321                                        .and_then(|d| d.href.clone()),
11322                                    severity: DiagnosticSeverity::INFORMATION,
11323                                    markdown: adapter.as_ref().and_then(|adapter| {
11324                                        adapter.diagnostic_message_to_markdown(&info.message)
11325                                    }),
11326                                    message: info.message.trim().to_string(),
11327                                    group_id,
11328                                    is_primary: false,
11329                                    is_disk_based,
11330                                    is_unnecessary: false,
11331                                    underline,
11332                                    data: diagnostic.data.clone(),
11333                                    registration_id: registration_id.clone(),
11334                                },
11335                            });
11336                        }
11337                    }
11338                }
11339            }
11340        }
11341
11342        for entry in &mut diagnostics {
11343            let diagnostic = &mut entry.diagnostic;
11344            if !diagnostic.is_primary {
11345                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11346                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11347                    source,
11348                    diagnostic.code.clone(),
11349                    entry.range.clone(),
11350                )) {
11351                    if let Some(severity) = severity {
11352                        diagnostic.severity = severity;
11353                    }
11354                    diagnostic.is_unnecessary = is_unnecessary;
11355                }
11356            }
11357        }
11358
11359        DocumentDiagnostics {
11360            diagnostics,
11361            document_abs_path,
11362            version: lsp_diagnostics.version,
11363        }
11364    }
11365
11366    fn insert_newly_running_language_server(
11367        &mut self,
11368        adapter: Arc<CachedLspAdapter>,
11369        language_server: Arc<LanguageServer>,
11370        server_id: LanguageServerId,
11371        key: LanguageServerSeed,
11372        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11373        cx: &mut Context<Self>,
11374    ) {
11375        let Some(local) = self.as_local_mut() else {
11376            return;
11377        };
11378        // If the language server for this key doesn't match the server id, don't store the
11379        // server. Which will cause it to be dropped, killing the process
11380        if local
11381            .language_server_ids
11382            .get(&key)
11383            .map(|state| state.id != server_id)
11384            .unwrap_or(false)
11385        {
11386            return;
11387        }
11388
11389        // Update language_servers collection with Running variant of LanguageServerState
11390        // indicating that the server is up and running and ready
11391        let workspace_folders = workspace_folders.lock().clone();
11392        language_server.set_workspace_folders(workspace_folders);
11393
11394        let workspace_diagnostics_refresh_tasks = language_server
11395            .capabilities()
11396            .diagnostic_provider
11397            .and_then(|provider| {
11398                local
11399                    .language_server_dynamic_registrations
11400                    .entry(server_id)
11401                    .or_default()
11402                    .diagnostics
11403                    .entry(None)
11404                    .or_insert(provider.clone());
11405                let workspace_refresher =
11406                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11407
11408                Some((None, workspace_refresher))
11409            })
11410            .into_iter()
11411            .collect();
11412        local.language_servers.insert(
11413            server_id,
11414            LanguageServerState::Running {
11415                workspace_diagnostics_refresh_tasks,
11416                adapter: adapter.clone(),
11417                server: language_server.clone(),
11418                simulate_disk_based_diagnostics_completion: None,
11419            },
11420        );
11421        local
11422            .languages
11423            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11424        if let Some(file_ops_caps) = language_server
11425            .capabilities()
11426            .workspace
11427            .as_ref()
11428            .and_then(|ws| ws.file_operations.as_ref())
11429        {
11430            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11431            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11432            if did_rename_caps.or(will_rename_caps).is_some() {
11433                let watcher = RenamePathsWatchedForServer::default()
11434                    .with_did_rename_patterns(did_rename_caps)
11435                    .with_will_rename_patterns(will_rename_caps);
11436                local
11437                    .language_server_paths_watched_for_rename
11438                    .insert(server_id, watcher);
11439            }
11440        }
11441
11442        self.language_server_statuses.insert(
11443            server_id,
11444            LanguageServerStatus {
11445                name: language_server.name(),
11446                server_version: language_server.version(),
11447                server_readable_version: language_server.readable_version(),
11448                pending_work: Default::default(),
11449                has_pending_diagnostic_updates: false,
11450                progress_tokens: Default::default(),
11451                worktree: Some(key.worktree_id),
11452                binary: Some(language_server.binary().clone()),
11453                configuration: Some(language_server.configuration().clone()),
11454                workspace_folders: language_server.workspace_folders(),
11455                process_id: language_server.process_id(),
11456            },
11457        );
11458
11459        cx.emit(LspStoreEvent::LanguageServerAdded(
11460            server_id,
11461            language_server.name(),
11462            Some(key.worktree_id),
11463        ));
11464
11465        let server_capabilities = language_server.capabilities();
11466        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11467            downstream_client
11468                .send(proto::StartLanguageServer {
11469                    project_id: *project_id,
11470                    server: Some(proto::LanguageServer {
11471                        id: server_id.to_proto(),
11472                        name: language_server.name().to_string(),
11473                        worktree_id: Some(key.worktree_id.to_proto()),
11474                    }),
11475                    capabilities: serde_json::to_string(&server_capabilities)
11476                        .expect("serializing server LSP capabilities"),
11477                })
11478                .log_err();
11479        }
11480        self.lsp_server_capabilities
11481            .insert(server_id, server_capabilities);
11482
11483        // Tell the language server about every open buffer in the worktree that matches the language.
11484        // Also check for buffers in worktrees that reused this server
11485        let mut worktrees_using_server = vec![key.worktree_id];
11486        if let Some(local) = self.as_local() {
11487            // Find all worktrees that have this server in their language server tree
11488            for (worktree_id, servers) in &local.lsp_tree.instances {
11489                if *worktree_id != key.worktree_id {
11490                    for server_map in servers.roots.values() {
11491                        if server_map
11492                            .values()
11493                            .any(|(node, _)| node.id() == Some(server_id))
11494                        {
11495                            worktrees_using_server.push(*worktree_id);
11496                        }
11497                    }
11498                }
11499            }
11500        }
11501
11502        let mut buffer_paths_registered = Vec::new();
11503        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11504            let mut lsp_adapters = HashMap::default();
11505            for buffer_handle in buffer_store.buffers() {
11506                let buffer = buffer_handle.read(cx);
11507                let file = match File::from_dyn(buffer.file()) {
11508                    Some(file) => file,
11509                    None => continue,
11510                };
11511                let language = match buffer.language() {
11512                    Some(language) => language,
11513                    None => continue,
11514                };
11515
11516                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11517                    || !lsp_adapters
11518                        .entry(language.name())
11519                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11520                        .iter()
11521                        .any(|a| a.name == key.name)
11522                {
11523                    continue;
11524                }
11525                // didOpen
11526                let file = match file.as_local() {
11527                    Some(file) => file,
11528                    None => continue,
11529                };
11530
11531                let local = self.as_local_mut().unwrap();
11532
11533                let buffer_id = buffer.remote_id();
11534                if local.registered_buffers.contains_key(&buffer_id) {
11535                    let abs_path = file.abs_path(cx);
11536                    let uri = match lsp::Uri::from_file_path(&abs_path) {
11537                        Ok(uri) => uri,
11538                        Err(()) => {
11539                            log::error!("failed to convert path to URI: {:?}", abs_path);
11540                            continue;
11541                        }
11542                    };
11543
11544                    let versions = local
11545                        .buffer_snapshots
11546                        .entry(buffer_id)
11547                        .or_default()
11548                        .entry(server_id)
11549                        .and_modify(|_| {
11550                            assert!(
11551                            false,
11552                            "There should not be an existing snapshot for a newly inserted buffer"
11553                        )
11554                        })
11555                        .or_insert_with(|| {
11556                            vec![LspBufferSnapshot {
11557                                version: 0,
11558                                snapshot: buffer.text_snapshot(),
11559                            }]
11560                        });
11561
11562                    let snapshot = versions.last().unwrap();
11563                    let version = snapshot.version;
11564                    let initial_snapshot = &snapshot.snapshot;
11565                    language_server.register_buffer(
11566                        uri,
11567                        adapter.language_id(&language.name()),
11568                        version,
11569                        initial_snapshot.text(),
11570                    );
11571                    buffer_paths_registered.push((buffer_id, abs_path));
11572                    local
11573                        .buffers_opened_in_servers
11574                        .entry(buffer_id)
11575                        .or_default()
11576                        .insert(server_id);
11577                }
11578                buffer_handle.update(cx, |buffer, cx| {
11579                    buffer.set_completion_triggers(
11580                        server_id,
11581                        language_server
11582                            .capabilities()
11583                            .completion_provider
11584                            .as_ref()
11585                            .and_then(|provider| {
11586                                provider
11587                                    .trigger_characters
11588                                    .as_ref()
11589                                    .map(|characters| characters.iter().cloned().collect())
11590                            })
11591                            .unwrap_or_default(),
11592                        cx,
11593                    )
11594                });
11595            }
11596        });
11597
11598        for (buffer_id, abs_path) in buffer_paths_registered {
11599            cx.emit(LspStoreEvent::LanguageServerUpdate {
11600                language_server_id: server_id,
11601                name: Some(adapter.name()),
11602                message: proto::update_language_server::Variant::RegisteredForBuffer(
11603                    proto::RegisteredForBuffer {
11604                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11605                        buffer_id: buffer_id.to_proto(),
11606                    },
11607                ),
11608            });
11609        }
11610
11611        cx.notify();
11612    }
11613
11614    pub fn language_servers_running_disk_based_diagnostics(
11615        &self,
11616    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11617        self.language_server_statuses
11618            .iter()
11619            .filter_map(|(id, status)| {
11620                if status.has_pending_diagnostic_updates {
11621                    Some(*id)
11622                } else {
11623                    None
11624                }
11625            })
11626    }
11627
11628    pub(crate) fn cancel_language_server_work_for_buffers(
11629        &mut self,
11630        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11631        cx: &mut Context<Self>,
11632    ) {
11633        if let Some((client, project_id)) = self.upstream_client() {
11634            let request = client.request(proto::CancelLanguageServerWork {
11635                project_id,
11636                work: Some(proto::cancel_language_server_work::Work::Buffers(
11637                    proto::cancel_language_server_work::Buffers {
11638                        buffer_ids: buffers
11639                            .into_iter()
11640                            .map(|b| b.read(cx).remote_id().to_proto())
11641                            .collect(),
11642                    },
11643                )),
11644            });
11645            cx.background_spawn(request).detach_and_log_err(cx);
11646        } else if let Some(local) = self.as_local() {
11647            let servers = buffers
11648                .into_iter()
11649                .flat_map(|buffer| {
11650                    buffer.update(cx, |buffer, cx| {
11651                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11652                    })
11653                })
11654                .collect::<HashSet<_>>();
11655            for server_id in servers {
11656                self.cancel_language_server_work(server_id, None, cx);
11657            }
11658        }
11659    }
11660
11661    pub(crate) fn cancel_language_server_work(
11662        &mut self,
11663        server_id: LanguageServerId,
11664        token_to_cancel: Option<ProgressToken>,
11665        cx: &mut Context<Self>,
11666    ) {
11667        if let Some(local) = self.as_local() {
11668            let status = self.language_server_statuses.get(&server_id);
11669            let server = local.language_servers.get(&server_id);
11670            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11671            {
11672                for (token, progress) in &status.pending_work {
11673                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11674                        && token != token_to_cancel
11675                    {
11676                        continue;
11677                    }
11678                    if progress.is_cancellable {
11679                        server
11680                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11681                                WorkDoneProgressCancelParams {
11682                                    token: token.to_lsp(),
11683                                },
11684                            )
11685                            .ok();
11686                    }
11687                }
11688            }
11689        } else if let Some((client, project_id)) = self.upstream_client() {
11690            let request = client.request(proto::CancelLanguageServerWork {
11691                project_id,
11692                work: Some(
11693                    proto::cancel_language_server_work::Work::LanguageServerWork(
11694                        proto::cancel_language_server_work::LanguageServerWork {
11695                            language_server_id: server_id.to_proto(),
11696                            token: token_to_cancel.map(|token| token.to_proto()),
11697                        },
11698                    ),
11699                ),
11700            });
11701            cx.background_spawn(request).detach_and_log_err(cx);
11702        }
11703    }
11704
11705    fn register_supplementary_language_server(
11706        &mut self,
11707        id: LanguageServerId,
11708        name: LanguageServerName,
11709        server: Arc<LanguageServer>,
11710        cx: &mut Context<Self>,
11711    ) {
11712        if let Some(local) = self.as_local_mut() {
11713            local
11714                .supplementary_language_servers
11715                .insert(id, (name.clone(), server));
11716            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11717        }
11718    }
11719
11720    fn unregister_supplementary_language_server(
11721        &mut self,
11722        id: LanguageServerId,
11723        cx: &mut Context<Self>,
11724    ) {
11725        if let Some(local) = self.as_local_mut() {
11726            local.supplementary_language_servers.remove(&id);
11727            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11728        }
11729    }
11730
11731    pub(crate) fn supplementary_language_servers(
11732        &self,
11733    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11734        self.as_local().into_iter().flat_map(|local| {
11735            local
11736                .supplementary_language_servers
11737                .iter()
11738                .map(|(id, (name, _))| (*id, name.clone()))
11739        })
11740    }
11741
11742    pub fn language_server_adapter_for_id(
11743        &self,
11744        id: LanguageServerId,
11745    ) -> Option<Arc<CachedLspAdapter>> {
11746        self.as_local()
11747            .and_then(|local| local.language_servers.get(&id))
11748            .and_then(|language_server_state| match language_server_state {
11749                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11750                _ => None,
11751            })
11752    }
11753
11754    pub(super) fn update_local_worktree_language_servers(
11755        &mut self,
11756        worktree_handle: &Entity<Worktree>,
11757        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11758        cx: &mut Context<Self>,
11759    ) {
11760        if changes.is_empty() {
11761            return;
11762        }
11763
11764        let Some(local) = self.as_local() else { return };
11765
11766        local.prettier_store.update(cx, |prettier_store, cx| {
11767            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11768        });
11769
11770        let worktree_id = worktree_handle.read(cx).id();
11771        let mut language_server_ids = local
11772            .language_server_ids
11773            .iter()
11774            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11775            .collect::<Vec<_>>();
11776        language_server_ids.sort();
11777        language_server_ids.dedup();
11778
11779        // let abs_path = worktree_handle.read(cx).abs_path();
11780        for server_id in &language_server_ids {
11781            if let Some(LanguageServerState::Running { server, .. }) =
11782                local.language_servers.get(server_id)
11783                && let Some(watched_paths) = local
11784                    .language_server_watched_paths
11785                    .get(server_id)
11786                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11787            {
11788                let params = lsp::DidChangeWatchedFilesParams {
11789                    changes: changes
11790                        .iter()
11791                        .filter_map(|(path, _, change)| {
11792                            if !watched_paths.is_match(path.as_std_path()) {
11793                                return None;
11794                            }
11795                            let typ = match change {
11796                                PathChange::Loaded => return None,
11797                                PathChange::Added => lsp::FileChangeType::CREATED,
11798                                PathChange::Removed => lsp::FileChangeType::DELETED,
11799                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11800                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11801                            };
11802                            let uri = lsp::Uri::from_file_path(
11803                                worktree_handle.read(cx).absolutize(&path),
11804                            )
11805                            .ok()?;
11806                            Some(lsp::FileEvent { uri, typ })
11807                        })
11808                        .collect(),
11809                };
11810                if !params.changes.is_empty() {
11811                    server
11812                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11813                        .ok();
11814                }
11815            }
11816        }
11817        for (path, _, _) in changes {
11818            if let Some(file_name) = path.file_name()
11819                && local.watched_manifest_filenames.contains(file_name)
11820            {
11821                self.request_workspace_config_refresh();
11822                break;
11823            }
11824        }
11825    }
11826
11827    pub fn wait_for_remote_buffer(
11828        &mut self,
11829        id: BufferId,
11830        cx: &mut Context<Self>,
11831    ) -> Task<Result<Entity<Buffer>>> {
11832        self.buffer_store.update(cx, |buffer_store, cx| {
11833            buffer_store.wait_for_remote_buffer(id, cx)
11834        })
11835    }
11836
11837    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11838        let mut result = proto::Symbol {
11839            language_server_name: symbol.language_server_name.0.to_string(),
11840            source_worktree_id: symbol.source_worktree_id.to_proto(),
11841            language_server_id: symbol.source_language_server_id.to_proto(),
11842            name: symbol.name.clone(),
11843            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11844            start: Some(proto::PointUtf16 {
11845                row: symbol.range.start.0.row,
11846                column: symbol.range.start.0.column,
11847            }),
11848            end: Some(proto::PointUtf16 {
11849                row: symbol.range.end.0.row,
11850                column: symbol.range.end.0.column,
11851            }),
11852            worktree_id: Default::default(),
11853            path: Default::default(),
11854            signature: Default::default(),
11855            container_name: symbol.container_name.clone(),
11856        };
11857        match &symbol.path {
11858            SymbolLocation::InProject(path) => {
11859                result.worktree_id = path.worktree_id.to_proto();
11860                result.path = path.path.to_proto();
11861            }
11862            SymbolLocation::OutsideProject {
11863                abs_path,
11864                signature,
11865            } => {
11866                result.path = abs_path.to_string_lossy().into_owned();
11867                result.signature = signature.to_vec();
11868            }
11869        }
11870        result
11871    }
11872
11873    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11874        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11875        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11876        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11877
11878        let path = if serialized_symbol.signature.is_empty() {
11879            SymbolLocation::InProject(ProjectPath {
11880                worktree_id,
11881                path: RelPath::from_proto(&serialized_symbol.path)
11882                    .context("invalid symbol path")?,
11883            })
11884        } else {
11885            SymbolLocation::OutsideProject {
11886                abs_path: Path::new(&serialized_symbol.path).into(),
11887                signature: serialized_symbol
11888                    .signature
11889                    .try_into()
11890                    .map_err(|_| anyhow!("invalid signature"))?,
11891            }
11892        };
11893
11894        let start = serialized_symbol.start.context("invalid start")?;
11895        let end = serialized_symbol.end.context("invalid end")?;
11896        Ok(CoreSymbol {
11897            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11898            source_worktree_id,
11899            source_language_server_id: LanguageServerId::from_proto(
11900                serialized_symbol.language_server_id,
11901            ),
11902            path,
11903            name: serialized_symbol.name,
11904            range: Unclipped(PointUtf16::new(start.row, start.column))
11905                ..Unclipped(PointUtf16::new(end.row, end.column)),
11906            kind,
11907            container_name: serialized_symbol.container_name,
11908        })
11909    }
11910
11911    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11912        let mut serialized_completion = proto::Completion {
11913            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11914            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11915            new_text: completion.new_text.clone(),
11916            ..proto::Completion::default()
11917        };
11918        match &completion.source {
11919            CompletionSource::Lsp {
11920                insert_range,
11921                server_id,
11922                lsp_completion,
11923                lsp_defaults,
11924                resolved,
11925            } => {
11926                let (old_insert_start, old_insert_end) = insert_range
11927                    .as_ref()
11928                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11929                    .unzip();
11930
11931                serialized_completion.old_insert_start = old_insert_start;
11932                serialized_completion.old_insert_end = old_insert_end;
11933                serialized_completion.source = proto::completion::Source::Lsp as i32;
11934                serialized_completion.server_id = server_id.0 as u64;
11935                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11936                serialized_completion.lsp_defaults = lsp_defaults
11937                    .as_deref()
11938                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11939                serialized_completion.resolved = *resolved;
11940            }
11941            CompletionSource::BufferWord {
11942                word_range,
11943                resolved,
11944            } => {
11945                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11946                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11947                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11948                serialized_completion.resolved = *resolved;
11949            }
11950            CompletionSource::Custom => {
11951                serialized_completion.source = proto::completion::Source::Custom as i32;
11952                serialized_completion.resolved = true;
11953            }
11954            CompletionSource::Dap { sort_text } => {
11955                serialized_completion.source = proto::completion::Source::Dap as i32;
11956                serialized_completion.sort_text = Some(sort_text.clone());
11957            }
11958        }
11959
11960        serialized_completion
11961    }
11962
11963    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11964        let old_replace_start = completion
11965            .old_replace_start
11966            .and_then(deserialize_anchor)
11967            .context("invalid old start")?;
11968        let old_replace_end = completion
11969            .old_replace_end
11970            .and_then(deserialize_anchor)
11971            .context("invalid old end")?;
11972        let insert_range = {
11973            match completion.old_insert_start.zip(completion.old_insert_end) {
11974                Some((start, end)) => {
11975                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11976                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11977                    Some(start..end)
11978                }
11979                None => None,
11980            }
11981        };
11982        Ok(CoreCompletion {
11983            replace_range: old_replace_start..old_replace_end,
11984            new_text: completion.new_text,
11985            source: match proto::completion::Source::from_i32(completion.source) {
11986                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11987                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11988                    insert_range,
11989                    server_id: LanguageServerId::from_proto(completion.server_id),
11990                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11991                    lsp_defaults: completion
11992                        .lsp_defaults
11993                        .as_deref()
11994                        .map(serde_json::from_slice)
11995                        .transpose()?,
11996                    resolved: completion.resolved,
11997                },
11998                Some(proto::completion::Source::BufferWord) => {
11999                    let word_range = completion
12000                        .buffer_word_start
12001                        .and_then(deserialize_anchor)
12002                        .context("invalid buffer word start")?
12003                        ..completion
12004                            .buffer_word_end
12005                            .and_then(deserialize_anchor)
12006                            .context("invalid buffer word end")?;
12007                    CompletionSource::BufferWord {
12008                        word_range,
12009                        resolved: completion.resolved,
12010                    }
12011                }
12012                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12013                    sort_text: completion
12014                        .sort_text
12015                        .context("expected sort text to exist")?,
12016                },
12017                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12018            },
12019        })
12020    }
12021
12022    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12023        let (kind, lsp_action) = match &action.lsp_action {
12024            LspAction::Action(code_action) => (
12025                proto::code_action::Kind::Action as i32,
12026                serde_json::to_vec(code_action).unwrap(),
12027            ),
12028            LspAction::Command(command) => (
12029                proto::code_action::Kind::Command as i32,
12030                serde_json::to_vec(command).unwrap(),
12031            ),
12032            LspAction::CodeLens(code_lens) => (
12033                proto::code_action::Kind::CodeLens as i32,
12034                serde_json::to_vec(code_lens).unwrap(),
12035            ),
12036        };
12037
12038        proto::CodeAction {
12039            server_id: action.server_id.0 as u64,
12040            start: Some(serialize_anchor(&action.range.start)),
12041            end: Some(serialize_anchor(&action.range.end)),
12042            lsp_action,
12043            kind,
12044            resolved: action.resolved,
12045        }
12046    }
12047
12048    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12049        let start = action
12050            .start
12051            .and_then(deserialize_anchor)
12052            .context("invalid start")?;
12053        let end = action
12054            .end
12055            .and_then(deserialize_anchor)
12056            .context("invalid end")?;
12057        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12058            Some(proto::code_action::Kind::Action) => {
12059                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12060            }
12061            Some(proto::code_action::Kind::Command) => {
12062                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12063            }
12064            Some(proto::code_action::Kind::CodeLens) => {
12065                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12066            }
12067            None => anyhow::bail!("Unknown action kind {}", action.kind),
12068        };
12069        Ok(CodeAction {
12070            server_id: LanguageServerId(action.server_id as usize),
12071            range: start..end,
12072            resolved: action.resolved,
12073            lsp_action,
12074        })
12075    }
12076
12077    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12078        match &formatting_result {
12079            Ok(_) => self.last_formatting_failure = None,
12080            Err(error) => {
12081                let error_string = format!("{error:#}");
12082                log::error!("Formatting failed: {error_string}");
12083                self.last_formatting_failure
12084                    .replace(error_string.lines().join(" "));
12085            }
12086        }
12087    }
12088
12089    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12090        self.lsp_server_capabilities.remove(&for_server);
12091        self.semantic_token_config.remove_server_data(for_server);
12092        for lsp_data in self.lsp_data.values_mut() {
12093            lsp_data.remove_server_data(for_server);
12094        }
12095        if let Some(local) = self.as_local_mut() {
12096            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12097            local
12098                .workspace_pull_diagnostics_result_ids
12099                .remove(&for_server);
12100            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12101                buffer_servers.remove(&for_server);
12102            }
12103        }
12104    }
12105
12106    pub fn result_id_for_buffer_pull(
12107        &self,
12108        server_id: LanguageServerId,
12109        buffer_id: BufferId,
12110        registration_id: &Option<SharedString>,
12111        cx: &App,
12112    ) -> Option<SharedString> {
12113        let abs_path = self
12114            .buffer_store
12115            .read(cx)
12116            .get(buffer_id)
12117            .and_then(|b| File::from_dyn(b.read(cx).file()))
12118            .map(|f| f.abs_path(cx))?;
12119        self.as_local()?
12120            .buffer_pull_diagnostics_result_ids
12121            .get(&server_id)?
12122            .get(registration_id)?
12123            .get(&abs_path)?
12124            .clone()
12125    }
12126
12127    /// Gets all result_ids for a workspace diagnostics pull request.
12128    /// 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.
12129    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12130    pub fn result_ids_for_workspace_refresh(
12131        &self,
12132        server_id: LanguageServerId,
12133        registration_id: &Option<SharedString>,
12134    ) -> HashMap<PathBuf, SharedString> {
12135        let Some(local) = self.as_local() else {
12136            return HashMap::default();
12137        };
12138        local
12139            .workspace_pull_diagnostics_result_ids
12140            .get(&server_id)
12141            .into_iter()
12142            .filter_map(|diagnostics| diagnostics.get(registration_id))
12143            .flatten()
12144            .filter_map(|(abs_path, result_id)| {
12145                let result_id = local
12146                    .buffer_pull_diagnostics_result_ids
12147                    .get(&server_id)
12148                    .and_then(|buffer_ids_result_ids| {
12149                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12150                    })
12151                    .cloned()
12152                    .flatten()
12153                    .or_else(|| result_id.clone())?;
12154                Some((abs_path.clone(), result_id))
12155            })
12156            .collect()
12157    }
12158
12159    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12160        if let Some(LanguageServerState::Running {
12161            workspace_diagnostics_refresh_tasks,
12162            ..
12163        }) = self
12164            .as_local_mut()
12165            .and_then(|local| local.language_servers.get_mut(&server_id))
12166        {
12167            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12168                diagnostics.refresh_tx.try_send(()).ok();
12169            }
12170        }
12171    }
12172
12173    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12174    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12175    /// which requires refreshing both workspace and document diagnostics.
12176    pub fn pull_document_diagnostics_for_server(
12177        &mut self,
12178        server_id: LanguageServerId,
12179        source_buffer_id: Option<BufferId>,
12180        cx: &mut Context<Self>,
12181    ) -> Shared<Task<()>> {
12182        let Some(local) = self.as_local_mut() else {
12183            return Task::ready(()).shared();
12184        };
12185        let mut buffers_to_refresh = HashSet::default();
12186        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12187            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12188                buffers_to_refresh.insert(*buffer_id);
12189            }
12190        }
12191
12192        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12193    }
12194
12195    pub fn pull_document_diagnostics_for_buffer_edit(
12196        &mut self,
12197        buffer_id: BufferId,
12198        cx: &mut Context<Self>,
12199    ) {
12200        let Some(local) = self.as_local_mut() else {
12201            return;
12202        };
12203        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12204        else {
12205            return;
12206        };
12207        for server_id in languages_servers {
12208            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12209        }
12210    }
12211
12212    fn apply_workspace_diagnostic_report(
12213        &mut self,
12214        server_id: LanguageServerId,
12215        report: lsp::WorkspaceDiagnosticReportResult,
12216        registration_id: Option<SharedString>,
12217        cx: &mut Context<Self>,
12218    ) {
12219        let mut workspace_diagnostics =
12220            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12221                report,
12222                server_id,
12223                registration_id,
12224            );
12225        workspace_diagnostics.retain(|d| match &d.diagnostics {
12226            LspPullDiagnostics::Response {
12227                server_id,
12228                registration_id,
12229                ..
12230            } => self.diagnostic_registration_exists(*server_id, registration_id),
12231            LspPullDiagnostics::Default => false,
12232        });
12233        let mut unchanged_buffers = HashMap::default();
12234        let workspace_diagnostics_updates = workspace_diagnostics
12235            .into_iter()
12236            .filter_map(
12237                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12238                    LspPullDiagnostics::Response {
12239                        server_id,
12240                        uri,
12241                        diagnostics,
12242                        registration_id,
12243                    } => Some((
12244                        server_id,
12245                        uri,
12246                        diagnostics,
12247                        workspace_diagnostics.version,
12248                        registration_id,
12249                    )),
12250                    LspPullDiagnostics::Default => None,
12251                },
12252            )
12253            .fold(
12254                HashMap::default(),
12255                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12256                    let (result_id, diagnostics) = match diagnostics {
12257                        PulledDiagnostics::Unchanged { result_id } => {
12258                            unchanged_buffers
12259                                .entry(new_registration_id.clone())
12260                                .or_insert_with(HashSet::default)
12261                                .insert(uri.clone());
12262                            (Some(result_id), Vec::new())
12263                        }
12264                        PulledDiagnostics::Changed {
12265                            result_id,
12266                            diagnostics,
12267                        } => (result_id, diagnostics),
12268                    };
12269                    let disk_based_sources = Cow::Owned(
12270                        self.language_server_adapter_for_id(server_id)
12271                            .as_ref()
12272                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12273                            .unwrap_or(&[])
12274                            .to_vec(),
12275                    );
12276
12277                    let Some(abs_path) = uri.to_file_path().ok() else {
12278                        return acc;
12279                    };
12280                    let Some((worktree, relative_path)) =
12281                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12282                    else {
12283                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12284                        return acc;
12285                    };
12286                    let worktree_id = worktree.read(cx).id();
12287                    let project_path = ProjectPath {
12288                        worktree_id,
12289                        path: relative_path,
12290                    };
12291                    if let Some(local_lsp_store) = self.as_local_mut() {
12292                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12293                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12294                    }
12295                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12296                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12297                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12298                        acc.entry(server_id)
12299                            .or_insert_with(HashMap::default)
12300                            .entry(new_registration_id.clone())
12301                            .or_insert_with(Vec::new)
12302                            .push(DocumentDiagnosticsUpdate {
12303                                server_id,
12304                                diagnostics: lsp::PublishDiagnosticsParams {
12305                                    uri,
12306                                    diagnostics,
12307                                    version,
12308                                },
12309                                result_id: result_id.map(SharedString::new),
12310                                disk_based_sources,
12311                                registration_id: new_registration_id,
12312                            });
12313                    }
12314                    acc
12315                },
12316            );
12317
12318        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12319            for (registration_id, diagnostic_updates) in diagnostic_updates {
12320                self.merge_lsp_diagnostics(
12321                    DiagnosticSourceKind::Pulled,
12322                    diagnostic_updates,
12323                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12324                        DiagnosticSourceKind::Pulled => {
12325                            old_diagnostic.registration_id != registration_id
12326                                || unchanged_buffers
12327                                    .get(&old_diagnostic.registration_id)
12328                                    .is_some_and(|unchanged_buffers| {
12329                                        unchanged_buffers.contains(&document_uri)
12330                                    })
12331                        }
12332                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12333                    },
12334                    cx,
12335                )
12336                .log_err();
12337            }
12338        }
12339    }
12340
12341    fn register_server_capabilities(
12342        &mut self,
12343        server_id: LanguageServerId,
12344        params: lsp::RegistrationParams,
12345        cx: &mut Context<Self>,
12346    ) -> anyhow::Result<()> {
12347        let server = self
12348            .language_server_for_id(server_id)
12349            .with_context(|| format!("no server {server_id} found"))?;
12350        for reg in params.registrations {
12351            match reg.method.as_str() {
12352                "workspace/didChangeWatchedFiles" => {
12353                    if let Some(options) = reg.register_options {
12354                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12355                            let caps = serde_json::from_value(options)?;
12356                            local_lsp_store
12357                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12358                            true
12359                        } else {
12360                            false
12361                        };
12362                        if notify {
12363                            notify_server_capabilities_updated(&server, cx);
12364                        }
12365                    }
12366                }
12367                "workspace/didChangeConfiguration" => {
12368                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12369                }
12370                "workspace/didChangeWorkspaceFolders" => {
12371                    // In this case register options is an empty object, we can ignore it
12372                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12373                        supported: Some(true),
12374                        change_notifications: Some(OneOf::Right(reg.id)),
12375                    };
12376                    server.update_capabilities(|capabilities| {
12377                        capabilities
12378                            .workspace
12379                            .get_or_insert_default()
12380                            .workspace_folders = Some(caps);
12381                    });
12382                    notify_server_capabilities_updated(&server, cx);
12383                }
12384                "workspace/symbol" => {
12385                    let options = parse_register_capabilities(reg)?;
12386                    server.update_capabilities(|capabilities| {
12387                        capabilities.workspace_symbol_provider = Some(options);
12388                    });
12389                    notify_server_capabilities_updated(&server, cx);
12390                }
12391                "workspace/fileOperations" => {
12392                    if let Some(options) = reg.register_options {
12393                        let caps = serde_json::from_value(options)?;
12394                        server.update_capabilities(|capabilities| {
12395                            capabilities
12396                                .workspace
12397                                .get_or_insert_default()
12398                                .file_operations = Some(caps);
12399                        });
12400                        notify_server_capabilities_updated(&server, cx);
12401                    }
12402                }
12403                "workspace/executeCommand" => {
12404                    if let Some(options) = reg.register_options {
12405                        let options = serde_json::from_value(options)?;
12406                        server.update_capabilities(|capabilities| {
12407                            capabilities.execute_command_provider = Some(options);
12408                        });
12409                        notify_server_capabilities_updated(&server, cx);
12410                    }
12411                }
12412                "textDocument/rangeFormatting" => {
12413                    let options = parse_register_capabilities(reg)?;
12414                    server.update_capabilities(|capabilities| {
12415                        capabilities.document_range_formatting_provider = Some(options);
12416                    });
12417                    notify_server_capabilities_updated(&server, cx);
12418                }
12419                "textDocument/onTypeFormatting" => {
12420                    if let Some(options) = reg
12421                        .register_options
12422                        .map(serde_json::from_value)
12423                        .transpose()?
12424                    {
12425                        server.update_capabilities(|capabilities| {
12426                            capabilities.document_on_type_formatting_provider = Some(options);
12427                        });
12428                        notify_server_capabilities_updated(&server, cx);
12429                    }
12430                }
12431                "textDocument/formatting" => {
12432                    let options = parse_register_capabilities(reg)?;
12433                    server.update_capabilities(|capabilities| {
12434                        capabilities.document_formatting_provider = Some(options);
12435                    });
12436                    notify_server_capabilities_updated(&server, cx);
12437                }
12438                "textDocument/rename" => {
12439                    let options = parse_register_capabilities(reg)?;
12440                    server.update_capabilities(|capabilities| {
12441                        capabilities.rename_provider = Some(options);
12442                    });
12443                    notify_server_capabilities_updated(&server, cx);
12444                }
12445                "textDocument/inlayHint" => {
12446                    let options = parse_register_capabilities(reg)?;
12447                    server.update_capabilities(|capabilities| {
12448                        capabilities.inlay_hint_provider = Some(options);
12449                    });
12450                    notify_server_capabilities_updated(&server, cx);
12451                }
12452                "textDocument/documentSymbol" => {
12453                    let options = parse_register_capabilities(reg)?;
12454                    server.update_capabilities(|capabilities| {
12455                        capabilities.document_symbol_provider = Some(options);
12456                    });
12457                    notify_server_capabilities_updated(&server, cx);
12458                }
12459                "textDocument/codeAction" => {
12460                    let options = parse_register_capabilities(reg)?;
12461                    let provider = match options {
12462                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12463                        OneOf::Right(caps) => caps,
12464                    };
12465                    server.update_capabilities(|capabilities| {
12466                        capabilities.code_action_provider = Some(provider);
12467                    });
12468                    notify_server_capabilities_updated(&server, cx);
12469                }
12470                "textDocument/definition" => {
12471                    let options = parse_register_capabilities(reg)?;
12472                    server.update_capabilities(|capabilities| {
12473                        capabilities.definition_provider = Some(options);
12474                    });
12475                    notify_server_capabilities_updated(&server, cx);
12476                }
12477                "textDocument/completion" => {
12478                    if let Some(caps) = reg
12479                        .register_options
12480                        .map(serde_json::from_value::<CompletionOptions>)
12481                        .transpose()?
12482                    {
12483                        server.update_capabilities(|capabilities| {
12484                            capabilities.completion_provider = Some(caps.clone());
12485                        });
12486
12487                        if let Some(local) = self.as_local() {
12488                            let mut buffers_with_language_server = Vec::new();
12489                            for handle in self.buffer_store.read(cx).buffers() {
12490                                let buffer_id = handle.read(cx).remote_id();
12491                                if local
12492                                    .buffers_opened_in_servers
12493                                    .get(&buffer_id)
12494                                    .filter(|s| s.contains(&server_id))
12495                                    .is_some()
12496                                {
12497                                    buffers_with_language_server.push(handle);
12498                                }
12499                            }
12500                            let triggers = caps
12501                                .trigger_characters
12502                                .unwrap_or_default()
12503                                .into_iter()
12504                                .collect::<BTreeSet<_>>();
12505                            for handle in buffers_with_language_server {
12506                                let triggers = triggers.clone();
12507                                let _ = handle.update(cx, move |buffer, cx| {
12508                                    buffer.set_completion_triggers(server_id, triggers, cx);
12509                                });
12510                            }
12511                        }
12512                        notify_server_capabilities_updated(&server, cx);
12513                    }
12514                }
12515                "textDocument/hover" => {
12516                    let options = parse_register_capabilities(reg)?;
12517                    let provider = match options {
12518                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12519                        OneOf::Right(caps) => caps,
12520                    };
12521                    server.update_capabilities(|capabilities| {
12522                        capabilities.hover_provider = Some(provider);
12523                    });
12524                    notify_server_capabilities_updated(&server, cx);
12525                }
12526                "textDocument/signatureHelp" => {
12527                    if let Some(caps) = reg
12528                        .register_options
12529                        .map(serde_json::from_value)
12530                        .transpose()?
12531                    {
12532                        server.update_capabilities(|capabilities| {
12533                            capabilities.signature_help_provider = Some(caps);
12534                        });
12535                        notify_server_capabilities_updated(&server, cx);
12536                    }
12537                }
12538                "textDocument/didChange" => {
12539                    if let Some(sync_kind) = reg
12540                        .register_options
12541                        .and_then(|opts| opts.get("syncKind").cloned())
12542                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12543                        .transpose()?
12544                    {
12545                        server.update_capabilities(|capabilities| {
12546                            let mut sync_options =
12547                                Self::take_text_document_sync_options(capabilities);
12548                            sync_options.change = Some(sync_kind);
12549                            capabilities.text_document_sync =
12550                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12551                        });
12552                        notify_server_capabilities_updated(&server, cx);
12553                    }
12554                }
12555                "textDocument/didSave" => {
12556                    if let Some(include_text) = reg
12557                        .register_options
12558                        .map(|opts| {
12559                            let transpose = opts
12560                                .get("includeText")
12561                                .cloned()
12562                                .map(serde_json::from_value::<Option<bool>>)
12563                                .transpose();
12564                            match transpose {
12565                                Ok(value) => Ok(value.flatten()),
12566                                Err(e) => Err(e),
12567                            }
12568                        })
12569                        .transpose()?
12570                    {
12571                        server.update_capabilities(|capabilities| {
12572                            let mut sync_options =
12573                                Self::take_text_document_sync_options(capabilities);
12574                            sync_options.save =
12575                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12576                                    include_text,
12577                                }));
12578                            capabilities.text_document_sync =
12579                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12580                        });
12581                        notify_server_capabilities_updated(&server, cx);
12582                    }
12583                }
12584                "textDocument/codeLens" => {
12585                    if let Some(caps) = reg
12586                        .register_options
12587                        .map(serde_json::from_value)
12588                        .transpose()?
12589                    {
12590                        server.update_capabilities(|capabilities| {
12591                            capabilities.code_lens_provider = Some(caps);
12592                        });
12593                        notify_server_capabilities_updated(&server, cx);
12594                    }
12595                }
12596                "textDocument/diagnostic" => {
12597                    if let Some(caps) = reg
12598                        .register_options
12599                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12600                        .transpose()?
12601                    {
12602                        let local = self
12603                            .as_local_mut()
12604                            .context("Expected LSP Store to be local")?;
12605                        let state = local
12606                            .language_servers
12607                            .get_mut(&server_id)
12608                            .context("Could not obtain Language Servers state")?;
12609                        local
12610                            .language_server_dynamic_registrations
12611                            .entry(server_id)
12612                            .or_default()
12613                            .diagnostics
12614                            .insert(Some(reg.id.clone()), caps.clone());
12615
12616                        let supports_workspace_diagnostics =
12617                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12618                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12619                                    diagnostic_options.workspace_diagnostics
12620                                }
12621                                DiagnosticServerCapabilities::RegistrationOptions(
12622                                    diagnostic_registration_options,
12623                                ) => {
12624                                    diagnostic_registration_options
12625                                        .diagnostic_options
12626                                        .workspace_diagnostics
12627                                }
12628                            };
12629
12630                        if supports_workspace_diagnostics(&caps) {
12631                            if let LanguageServerState::Running {
12632                                workspace_diagnostics_refresh_tasks,
12633                                ..
12634                            } = state
12635                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12636                                    Some(reg.id.clone()),
12637                                    caps.clone(),
12638                                    server.clone(),
12639                                    cx,
12640                                )
12641                            {
12642                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12643                            }
12644                        }
12645
12646                        server.update_capabilities(|capabilities| {
12647                            capabilities.diagnostic_provider = Some(caps);
12648                        });
12649
12650                        notify_server_capabilities_updated(&server, cx);
12651
12652                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12653                    }
12654                }
12655                "textDocument/documentColor" => {
12656                    let options = parse_register_capabilities(reg)?;
12657                    let provider = match options {
12658                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12659                        OneOf::Right(caps) => caps,
12660                    };
12661                    server.update_capabilities(|capabilities| {
12662                        capabilities.color_provider = Some(provider);
12663                    });
12664                    notify_server_capabilities_updated(&server, cx);
12665                }
12666                "textDocument/foldingRange" => {
12667                    let options = parse_register_capabilities(reg)?;
12668                    let provider = match options {
12669                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12670                        OneOf::Right(caps) => caps,
12671                    };
12672                    server.update_capabilities(|capabilities| {
12673                        capabilities.folding_range_provider = Some(provider);
12674                    });
12675                    notify_server_capabilities_updated(&server, cx);
12676                }
12677                _ => log::warn!("unhandled capability registration: {reg:?}"),
12678            }
12679        }
12680
12681        Ok(())
12682    }
12683
12684    fn unregister_server_capabilities(
12685        &mut self,
12686        server_id: LanguageServerId,
12687        params: lsp::UnregistrationParams,
12688        cx: &mut Context<Self>,
12689    ) -> anyhow::Result<()> {
12690        let server = self
12691            .language_server_for_id(server_id)
12692            .with_context(|| format!("no server {server_id} found"))?;
12693        for unreg in params.unregisterations.iter() {
12694            match unreg.method.as_str() {
12695                "workspace/didChangeWatchedFiles" => {
12696                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12697                        local_lsp_store
12698                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12699                        true
12700                    } else {
12701                        false
12702                    };
12703                    if notify {
12704                        notify_server_capabilities_updated(&server, cx);
12705                    }
12706                }
12707                "workspace/didChangeConfiguration" => {
12708                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12709                }
12710                "workspace/didChangeWorkspaceFolders" => {
12711                    server.update_capabilities(|capabilities| {
12712                        capabilities
12713                            .workspace
12714                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12715                                workspace_folders: None,
12716                                file_operations: None,
12717                            })
12718                            .workspace_folders = None;
12719                    });
12720                    notify_server_capabilities_updated(&server, cx);
12721                }
12722                "workspace/symbol" => {
12723                    server.update_capabilities(|capabilities| {
12724                        capabilities.workspace_symbol_provider = None
12725                    });
12726                    notify_server_capabilities_updated(&server, cx);
12727                }
12728                "workspace/fileOperations" => {
12729                    server.update_capabilities(|capabilities| {
12730                        capabilities
12731                            .workspace
12732                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12733                                workspace_folders: None,
12734                                file_operations: None,
12735                            })
12736                            .file_operations = None;
12737                    });
12738                    notify_server_capabilities_updated(&server, cx);
12739                }
12740                "workspace/executeCommand" => {
12741                    server.update_capabilities(|capabilities| {
12742                        capabilities.execute_command_provider = None;
12743                    });
12744                    notify_server_capabilities_updated(&server, cx);
12745                }
12746                "textDocument/rangeFormatting" => {
12747                    server.update_capabilities(|capabilities| {
12748                        capabilities.document_range_formatting_provider = None
12749                    });
12750                    notify_server_capabilities_updated(&server, cx);
12751                }
12752                "textDocument/onTypeFormatting" => {
12753                    server.update_capabilities(|capabilities| {
12754                        capabilities.document_on_type_formatting_provider = None;
12755                    });
12756                    notify_server_capabilities_updated(&server, cx);
12757                }
12758                "textDocument/formatting" => {
12759                    server.update_capabilities(|capabilities| {
12760                        capabilities.document_formatting_provider = None;
12761                    });
12762                    notify_server_capabilities_updated(&server, cx);
12763                }
12764                "textDocument/rename" => {
12765                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12766                    notify_server_capabilities_updated(&server, cx);
12767                }
12768                "textDocument/codeAction" => {
12769                    server.update_capabilities(|capabilities| {
12770                        capabilities.code_action_provider = None;
12771                    });
12772                    notify_server_capabilities_updated(&server, cx);
12773                }
12774                "textDocument/definition" => {
12775                    server.update_capabilities(|capabilities| {
12776                        capabilities.definition_provider = None;
12777                    });
12778                    notify_server_capabilities_updated(&server, cx);
12779                }
12780                "textDocument/completion" => {
12781                    server.update_capabilities(|capabilities| {
12782                        capabilities.completion_provider = None;
12783                    });
12784                    notify_server_capabilities_updated(&server, cx);
12785                }
12786                "textDocument/hover" => {
12787                    server.update_capabilities(|capabilities| {
12788                        capabilities.hover_provider = None;
12789                    });
12790                    notify_server_capabilities_updated(&server, cx);
12791                }
12792                "textDocument/signatureHelp" => {
12793                    server.update_capabilities(|capabilities| {
12794                        capabilities.signature_help_provider = None;
12795                    });
12796                    notify_server_capabilities_updated(&server, cx);
12797                }
12798                "textDocument/didChange" => {
12799                    server.update_capabilities(|capabilities| {
12800                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12801                        sync_options.change = None;
12802                        capabilities.text_document_sync =
12803                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12804                    });
12805                    notify_server_capabilities_updated(&server, cx);
12806                }
12807                "textDocument/didSave" => {
12808                    server.update_capabilities(|capabilities| {
12809                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12810                        sync_options.save = None;
12811                        capabilities.text_document_sync =
12812                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12813                    });
12814                    notify_server_capabilities_updated(&server, cx);
12815                }
12816                "textDocument/codeLens" => {
12817                    server.update_capabilities(|capabilities| {
12818                        capabilities.code_lens_provider = None;
12819                    });
12820                    notify_server_capabilities_updated(&server, cx);
12821                }
12822                "textDocument/diagnostic" => {
12823                    let local = self
12824                        .as_local_mut()
12825                        .context("Expected LSP Store to be local")?;
12826
12827                    let state = local
12828                        .language_servers
12829                        .get_mut(&server_id)
12830                        .context("Could not obtain Language Servers state")?;
12831                    let registrations = local
12832                        .language_server_dynamic_registrations
12833                        .get_mut(&server_id)
12834                        .with_context(|| {
12835                            format!("Expected dynamic registration to exist for server {server_id}")
12836                        })?;
12837                    registrations.diagnostics
12838                        .remove(&Some(unreg.id.clone()))
12839                        .with_context(|| format!(
12840                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12841                            unreg.id)
12842                        )?;
12843                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12844
12845                    if let LanguageServerState::Running {
12846                        workspace_diagnostics_refresh_tasks,
12847                        ..
12848                    } = state
12849                    {
12850                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12851                    }
12852
12853                    self.clear_unregistered_diagnostics(
12854                        server_id,
12855                        SharedString::from(unreg.id.clone()),
12856                        cx,
12857                    )?;
12858
12859                    if removed_last_diagnostic_provider {
12860                        server.update_capabilities(|capabilities| {
12861                            debug_assert!(capabilities.diagnostic_provider.is_some());
12862                            capabilities.diagnostic_provider = None;
12863                        });
12864                    }
12865
12866                    notify_server_capabilities_updated(&server, cx);
12867                }
12868                "textDocument/documentColor" => {
12869                    server.update_capabilities(|capabilities| {
12870                        capabilities.color_provider = None;
12871                    });
12872                    notify_server_capabilities_updated(&server, cx);
12873                }
12874                "textDocument/foldingRange" => {
12875                    server.update_capabilities(|capabilities| {
12876                        capabilities.folding_range_provider = None;
12877                    });
12878                    notify_server_capabilities_updated(&server, cx);
12879                }
12880                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12881            }
12882        }
12883
12884        Ok(())
12885    }
12886
12887    fn clear_unregistered_diagnostics(
12888        &mut self,
12889        server_id: LanguageServerId,
12890        cleared_registration_id: SharedString,
12891        cx: &mut Context<Self>,
12892    ) -> anyhow::Result<()> {
12893        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12894
12895        self.buffer_store.update(cx, |buffer_store, cx| {
12896            for buffer_handle in buffer_store.buffers() {
12897                let buffer = buffer_handle.read(cx);
12898                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12899                let Some(abs_path) = abs_path else {
12900                    continue;
12901                };
12902                affected_abs_paths.insert(abs_path);
12903            }
12904        });
12905
12906        let local = self.as_local().context("Expected LSP Store to be local")?;
12907        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12908            let Some(worktree) = self
12909                .worktree_store
12910                .read(cx)
12911                .worktree_for_id(*worktree_id, cx)
12912            else {
12913                continue;
12914            };
12915
12916            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
12917                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
12918                    let has_matching_registration =
12919                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
12920                            entry.diagnostic.registration_id.as_ref()
12921                                == Some(&cleared_registration_id)
12922                        });
12923                    if has_matching_registration {
12924                        let abs_path = worktree.read(cx).absolutize(rel_path);
12925                        affected_abs_paths.insert(abs_path);
12926                    }
12927                }
12928            }
12929        }
12930
12931        if affected_abs_paths.is_empty() {
12932            return Ok(());
12933        }
12934
12935        // Send a fake diagnostic update which clears the state for the registration ID
12936        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
12937            affected_abs_paths
12938                .into_iter()
12939                .map(|abs_path| DocumentDiagnosticsUpdate {
12940                    diagnostics: DocumentDiagnostics {
12941                        diagnostics: Vec::new(),
12942                        document_abs_path: abs_path,
12943                        version: None,
12944                    },
12945                    result_id: None,
12946                    registration_id: Some(cleared_registration_id.clone()),
12947                    server_id,
12948                    disk_based_sources: Cow::Borrowed(&[]),
12949                })
12950                .collect();
12951
12952        let merge_registration_id = cleared_registration_id.clone();
12953        self.merge_diagnostic_entries(
12954            clears,
12955            move |_, diagnostic, _| {
12956                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
12957                    diagnostic.registration_id != Some(merge_registration_id.clone())
12958                } else {
12959                    true
12960                }
12961            },
12962            cx,
12963        )?;
12964
12965        Ok(())
12966    }
12967
12968    async fn deduplicate_range_based_lsp_requests<T>(
12969        lsp_store: &Entity<Self>,
12970        server_id: Option<LanguageServerId>,
12971        lsp_request_id: LspRequestId,
12972        proto_request: &T::ProtoRequest,
12973        range: Range<Anchor>,
12974        cx: &mut AsyncApp,
12975    ) -> Result<()>
12976    where
12977        T: LspCommand,
12978        T::ProtoRequest: proto::LspRequestMessage,
12979    {
12980        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12981        let version = deserialize_version(proto_request.buffer_version());
12982        let buffer = lsp_store.update(cx, |this, cx| {
12983            this.buffer_store.read(cx).get_existing(buffer_id)
12984        })?;
12985        buffer
12986            .update(cx, |buffer, _| buffer.wait_for_version(version))
12987            .await?;
12988        lsp_store.update(cx, |lsp_store, cx| {
12989            let buffer_snapshot = buffer.read(cx).snapshot();
12990            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12991            let chunks_queried_for = lsp_data
12992                .inlay_hints
12993                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12994                .collect::<Vec<_>>();
12995            match chunks_queried_for.as_slice() {
12996                &[chunk] => {
12997                    let key = LspKey {
12998                        request_type: TypeId::of::<T>(),
12999                        server_queried: server_id,
13000                    };
13001                    let previous_request = lsp_data
13002                        .chunk_lsp_requests
13003                        .entry(key)
13004                        .or_default()
13005                        .insert(chunk, lsp_request_id);
13006                    if let Some((previous_request, running_requests)) =
13007                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13008                    {
13009                        running_requests.remove(&previous_request);
13010                    }
13011                }
13012                _ambiguous_chunks => {
13013                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13014                    // there, a buffer version-based check will be performed and outdated requests discarded.
13015                }
13016            }
13017            anyhow::Ok(())
13018        })?;
13019
13020        Ok(())
13021    }
13022
13023    async fn query_lsp_locally<T>(
13024        lsp_store: Entity<Self>,
13025        for_server_id: Option<LanguageServerId>,
13026        sender_id: proto::PeerId,
13027        lsp_request_id: LspRequestId,
13028        proto_request: T::ProtoRequest,
13029        position: Option<Anchor>,
13030        cx: &mut AsyncApp,
13031    ) -> Result<()>
13032    where
13033        T: LspCommand + Clone,
13034        T::ProtoRequest: proto::LspRequestMessage,
13035        <T::ProtoRequest as proto::RequestMessage>::Response:
13036            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13037    {
13038        let (buffer_version, buffer) =
13039            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
13040        let request =
13041            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13042        let key = LspKey {
13043            request_type: TypeId::of::<T>(),
13044            server_queried: for_server_id,
13045        };
13046        lsp_store.update(cx, |lsp_store, cx| {
13047            let request_task = match for_server_id {
13048                Some(server_id) => {
13049                    let server_task = lsp_store.request_lsp(
13050                        buffer.clone(),
13051                        LanguageServerToQuery::Other(server_id),
13052                        request.clone(),
13053                        cx,
13054                    );
13055                    cx.background_spawn(async move {
13056                        let mut responses = Vec::new();
13057                        match server_task.await {
13058                            Ok(response) => responses.push((server_id, response)),
13059                            // rust-analyzer likes to error with this when its still loading up
13060                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13061                            Err(e) => log::error!(
13062                                "Error handling response for request {request:?}: {e:#}"
13063                            ),
13064                        }
13065                        responses
13066                    })
13067                }
13068                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13069            };
13070            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13071            if T::ProtoRequest::stop_previous_requests() {
13072                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13073                    lsp_requests.clear();
13074                }
13075            }
13076            lsp_data.lsp_requests.entry(key).or_default().insert(
13077                lsp_request_id,
13078                cx.spawn(async move |lsp_store, cx| {
13079                    let response = request_task.await;
13080                    lsp_store
13081                        .update(cx, |lsp_store, cx| {
13082                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13083                            {
13084                                let response = response
13085                                    .into_iter()
13086                                    .map(|(server_id, response)| {
13087                                        (
13088                                            server_id.to_proto(),
13089                                            T::response_to_proto(
13090                                                response,
13091                                                lsp_store,
13092                                                sender_id,
13093                                                &buffer_version,
13094                                                cx,
13095                                            )
13096                                            .into(),
13097                                        )
13098                                    })
13099                                    .collect::<HashMap<_, _>>();
13100                                match client.send_lsp_response::<T::ProtoRequest>(
13101                                    project_id,
13102                                    lsp_request_id,
13103                                    response,
13104                                ) {
13105                                    Ok(()) => {}
13106                                    Err(e) => {
13107                                        log::error!("Failed to send LSP response: {e:#}",)
13108                                    }
13109                                }
13110                            }
13111                        })
13112                        .ok();
13113                }),
13114            );
13115        });
13116        Ok(())
13117    }
13118
13119    async fn wait_for_buffer_version<T>(
13120        lsp_store: &Entity<Self>,
13121        proto_request: &T::ProtoRequest,
13122        cx: &mut AsyncApp,
13123    ) -> Result<(Global, Entity<Buffer>)>
13124    where
13125        T: LspCommand,
13126        T::ProtoRequest: proto::LspRequestMessage,
13127    {
13128        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13129        let version = deserialize_version(proto_request.buffer_version());
13130        let buffer = lsp_store.update(cx, |this, cx| {
13131            this.buffer_store.read(cx).get_existing(buffer_id)
13132        })?;
13133        buffer
13134            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13135            .await?;
13136        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13137        Ok((buffer_version, buffer))
13138    }
13139
13140    fn take_text_document_sync_options(
13141        capabilities: &mut lsp::ServerCapabilities,
13142    ) -> lsp::TextDocumentSyncOptions {
13143        match capabilities.text_document_sync.take() {
13144            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13145            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13146                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13147                sync_options.change = Some(sync_kind);
13148                sync_options
13149            }
13150            None => lsp::TextDocumentSyncOptions::default(),
13151        }
13152    }
13153
13154    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13155        self.downstream_client.clone()
13156    }
13157
13158    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13159        self.worktree_store.clone()
13160    }
13161
13162    /// Gets what's stored in the LSP data for the given buffer.
13163    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13164        self.lsp_data.get_mut(&buffer_id)
13165    }
13166
13167    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13168    /// new [`BufferLspData`] will be created to replace the previous state.
13169    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13170        let (buffer_id, buffer_version) =
13171            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13172        let lsp_data = self
13173            .lsp_data
13174            .entry(buffer_id)
13175            .or_insert_with(|| BufferLspData::new(buffer, cx));
13176        if buffer_version.changed_since(&lsp_data.buffer_version) {
13177            // To send delta requests for semantic tokens, the previous tokens
13178            // need to be kept between buffer changes.
13179            let semantic_tokens = lsp_data.semantic_tokens.take();
13180            *lsp_data = BufferLspData::new(buffer, cx);
13181            lsp_data.semantic_tokens = semantic_tokens;
13182        }
13183        lsp_data
13184    }
13185}
13186
13187// Registration with registerOptions as null, should fallback to true.
13188// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13189fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13190    reg: lsp::Registration,
13191) -> Result<OneOf<bool, T>> {
13192    Ok(match reg.register_options {
13193        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13194        None => OneOf::Left(true),
13195    })
13196}
13197
13198fn subscribe_to_binary_statuses(
13199    languages: &Arc<LanguageRegistry>,
13200    cx: &mut Context<'_, LspStore>,
13201) -> Task<()> {
13202    let mut server_statuses = languages.language_server_binary_statuses();
13203    cx.spawn(async move |lsp_store, cx| {
13204        while let Some((server_name, binary_status)) = server_statuses.next().await {
13205            if lsp_store
13206                .update(cx, |_, cx| {
13207                    let mut message = None;
13208                    let binary_status = match binary_status {
13209                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13210                        BinaryStatus::CheckingForUpdate => {
13211                            proto::ServerBinaryStatus::CheckingForUpdate
13212                        }
13213                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13214                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13215                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13216                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13217                        BinaryStatus::Failed { error } => {
13218                            message = Some(error);
13219                            proto::ServerBinaryStatus::Failed
13220                        }
13221                    };
13222                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13223                        // Binary updates are about the binary that might not have any language server id at that point.
13224                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13225                        language_server_id: LanguageServerId(0),
13226                        name: Some(server_name),
13227                        message: proto::update_language_server::Variant::StatusUpdate(
13228                            proto::StatusUpdate {
13229                                message,
13230                                status: Some(proto::status_update::Status::Binary(
13231                                    binary_status as i32,
13232                                )),
13233                            },
13234                        ),
13235                    });
13236                })
13237                .is_err()
13238            {
13239                break;
13240            }
13241        }
13242    })
13243}
13244
13245fn lsp_workspace_diagnostics_refresh(
13246    registration_id: Option<String>,
13247    options: DiagnosticServerCapabilities,
13248    server: Arc<LanguageServer>,
13249    cx: &mut Context<'_, LspStore>,
13250) -> Option<WorkspaceRefreshTask> {
13251    let identifier = workspace_diagnostic_identifier(&options)?;
13252    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13253
13254    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13255    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13256    refresh_tx.try_send(()).ok();
13257
13258    let request_timeout = ProjectSettings::get_global(cx)
13259        .global_lsp_settings
13260        .get_request_timeout();
13261
13262    // 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.
13263    // This allows users to increase the duration if need be
13264    let timeout = if request_timeout != Duration::ZERO {
13265        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13266    } else {
13267        request_timeout
13268    };
13269
13270    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13271        let mut attempts = 0;
13272        let max_attempts = 50;
13273        let mut requests = 0;
13274
13275        loop {
13276            let Some(()) = refresh_rx.recv().await else {
13277                return;
13278            };
13279
13280            'request: loop {
13281                requests += 1;
13282                if attempts > max_attempts {
13283                    log::error!(
13284                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13285                    );
13286                    return;
13287                }
13288                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13289                cx.background_executor()
13290                    .timer(Duration::from_millis(backoff_millis))
13291                    .await;
13292                attempts += 1;
13293
13294                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13295                    lsp_store
13296                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13297                        .into_iter()
13298                        .filter_map(|(abs_path, result_id)| {
13299                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13300                            Some(lsp::PreviousResultId {
13301                                uri,
13302                                value: result_id.to_string(),
13303                            })
13304                        })
13305                        .collect()
13306                }) else {
13307                    return;
13308                };
13309
13310                let token = if let Some(registration_id) = &registration_id {
13311                    format!(
13312                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13313                        server.server_id(),
13314                    )
13315                } else {
13316                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13317                };
13318
13319                progress_rx.try_recv().ok();
13320                let timer = server.request_timer(timeout).fuse();
13321                let progress = pin!(progress_rx.recv().fuse());
13322                let response_result = server
13323                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13324                        lsp::WorkspaceDiagnosticParams {
13325                            previous_result_ids,
13326                            identifier: identifier.clone(),
13327                            work_done_progress_params: Default::default(),
13328                            partial_result_params: lsp::PartialResultParams {
13329                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13330                            },
13331                        },
13332                        select(timer, progress).then(|either| match either {
13333                            Either::Left((message, ..)) => ready(message).left_future(),
13334                            Either::Right(..) => pending::<String>().right_future(),
13335                        }),
13336                    )
13337                    .await;
13338
13339                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13340                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13341                match response_result {
13342                    ConnectionResult::Timeout => {
13343                        log::error!("Timeout during workspace diagnostics pull");
13344                        continue 'request;
13345                    }
13346                    ConnectionResult::ConnectionReset => {
13347                        log::error!("Server closed a workspace diagnostics pull request");
13348                        continue 'request;
13349                    }
13350                    ConnectionResult::Result(Err(e)) => {
13351                        log::error!("Error during workspace diagnostics pull: {e:#}");
13352                        break 'request;
13353                    }
13354                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13355                        attempts = 0;
13356                        if lsp_store
13357                            .update(cx, |lsp_store, cx| {
13358                                lsp_store.apply_workspace_diagnostic_report(
13359                                    server.server_id(),
13360                                    pulled_diagnostics,
13361                                    registration_id_shared.clone(),
13362                                    cx,
13363                                )
13364                            })
13365                            .is_err()
13366                        {
13367                            return;
13368                        }
13369                        break 'request;
13370                    }
13371                }
13372            }
13373        }
13374    });
13375
13376    Some(WorkspaceRefreshTask {
13377        refresh_tx,
13378        progress_tx,
13379        task: workspace_query_language_server,
13380    })
13381}
13382
13383fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13384    match &options {
13385        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13386            .identifier
13387            .as_deref()
13388            .map(SharedString::new),
13389        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13390            let diagnostic_options = &registration_options.diagnostic_options;
13391            diagnostic_options
13392                .identifier
13393                .as_deref()
13394                .map(SharedString::new)
13395        }
13396    }
13397}
13398
13399fn workspace_diagnostic_identifier(
13400    options: &DiagnosticServerCapabilities,
13401) -> Option<Option<String>> {
13402    match &options {
13403        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13404            if !diagnostic_options.workspace_diagnostics {
13405                return None;
13406            }
13407            Some(diagnostic_options.identifier.clone())
13408        }
13409        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13410            let diagnostic_options = &registration_options.diagnostic_options;
13411            if !diagnostic_options.workspace_diagnostics {
13412                return None;
13413            }
13414            Some(diagnostic_options.identifier.clone())
13415        }
13416    }
13417}
13418
13419fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13420    let CompletionSource::BufferWord {
13421        word_range,
13422        resolved,
13423    } = &mut completion.source
13424    else {
13425        return;
13426    };
13427    if *resolved {
13428        return;
13429    }
13430
13431    if completion.new_text
13432        != snapshot
13433            .text_for_range(word_range.clone())
13434            .collect::<String>()
13435    {
13436        return;
13437    }
13438
13439    let mut offset = 0;
13440    for chunk in snapshot.chunks(word_range.clone(), true) {
13441        let end_offset = offset + chunk.text.len();
13442        if let Some(highlight_id) = chunk.syntax_highlight_id {
13443            completion
13444                .label
13445                .runs
13446                .push((offset..end_offset, highlight_id));
13447        }
13448        offset = end_offset;
13449    }
13450    *resolved = true;
13451}
13452
13453impl EventEmitter<LspStoreEvent> for LspStore {}
13454
13455fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13456    hover
13457        .contents
13458        .retain(|hover_block| !hover_block.text.trim().is_empty());
13459    if hover.contents.is_empty() {
13460        None
13461    } else {
13462        Some(hover)
13463    }
13464}
13465
13466async fn populate_labels_for_completions(
13467    new_completions: Vec<CoreCompletion>,
13468    language: Option<Arc<Language>>,
13469    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13470) -> Vec<Completion> {
13471    let lsp_completions = new_completions
13472        .iter()
13473        .filter_map(|new_completion| {
13474            new_completion
13475                .source
13476                .lsp_completion(true)
13477                .map(|lsp_completion| lsp_completion.into_owned())
13478        })
13479        .collect::<Vec<_>>();
13480
13481    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13482        lsp_adapter
13483            .labels_for_completions(&lsp_completions, language)
13484            .await
13485            .log_err()
13486            .unwrap_or_default()
13487    } else {
13488        Vec::new()
13489    }
13490    .into_iter()
13491    .fuse();
13492
13493    let mut completions = Vec::new();
13494    for completion in new_completions {
13495        match completion.source.lsp_completion(true) {
13496            Some(lsp_completion) => {
13497                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13498
13499                let mut label = labels.next().flatten().unwrap_or_else(|| {
13500                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13501                });
13502                ensure_uniform_list_compatible_label(&mut label);
13503                completions.push(Completion {
13504                    label,
13505                    documentation,
13506                    replace_range: completion.replace_range,
13507                    new_text: completion.new_text,
13508                    insert_text_mode: lsp_completion.insert_text_mode,
13509                    source: completion.source,
13510                    icon_path: None,
13511                    confirm: None,
13512                    match_start: None,
13513                    snippet_deduplication_key: None,
13514                });
13515            }
13516            None => {
13517                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13518                ensure_uniform_list_compatible_label(&mut label);
13519                completions.push(Completion {
13520                    label,
13521                    documentation: None,
13522                    replace_range: completion.replace_range,
13523                    new_text: completion.new_text,
13524                    source: completion.source,
13525                    insert_text_mode: None,
13526                    icon_path: None,
13527                    confirm: None,
13528                    match_start: None,
13529                    snippet_deduplication_key: None,
13530                });
13531            }
13532        }
13533    }
13534    completions
13535}
13536
13537#[derive(Debug)]
13538pub enum LanguageServerToQuery {
13539    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13540    FirstCapable,
13541    /// Query a specific language server.
13542    Other(LanguageServerId),
13543}
13544
13545#[derive(Default)]
13546struct RenamePathsWatchedForServer {
13547    did_rename: Vec<RenameActionPredicate>,
13548    will_rename: Vec<RenameActionPredicate>,
13549}
13550
13551impl RenamePathsWatchedForServer {
13552    fn with_did_rename_patterns(
13553        mut self,
13554        did_rename: Option<&FileOperationRegistrationOptions>,
13555    ) -> Self {
13556        if let Some(did_rename) = did_rename {
13557            self.did_rename = did_rename
13558                .filters
13559                .iter()
13560                .filter_map(|filter| filter.try_into().log_err())
13561                .collect();
13562        }
13563        self
13564    }
13565    fn with_will_rename_patterns(
13566        mut self,
13567        will_rename: Option<&FileOperationRegistrationOptions>,
13568    ) -> Self {
13569        if let Some(will_rename) = will_rename {
13570            self.will_rename = will_rename
13571                .filters
13572                .iter()
13573                .filter_map(|filter| filter.try_into().log_err())
13574                .collect();
13575        }
13576        self
13577    }
13578
13579    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13580        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13581    }
13582    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13583        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13584    }
13585}
13586
13587impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13588    type Error = globset::Error;
13589    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13590        Ok(Self {
13591            kind: ops.pattern.matches.clone(),
13592            glob: GlobBuilder::new(&ops.pattern.glob)
13593                .case_insensitive(
13594                    ops.pattern
13595                        .options
13596                        .as_ref()
13597                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13598                )
13599                .build()?
13600                .compile_matcher(),
13601        })
13602    }
13603}
13604struct RenameActionPredicate {
13605    glob: GlobMatcher,
13606    kind: Option<FileOperationPatternKind>,
13607}
13608
13609impl RenameActionPredicate {
13610    // Returns true if language server should be notified
13611    fn eval(&self, path: &str, is_dir: bool) -> bool {
13612        self.kind.as_ref().is_none_or(|kind| {
13613            let expected_kind = if is_dir {
13614                FileOperationPatternKind::Folder
13615            } else {
13616                FileOperationPatternKind::File
13617            };
13618            kind == &expected_kind
13619        }) && self.glob.is_match(path)
13620    }
13621}
13622
13623#[derive(Default)]
13624struct LanguageServerWatchedPaths {
13625    worktree_paths: HashMap<WorktreeId, GlobSet>,
13626    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13627}
13628
13629#[derive(Default)]
13630struct LanguageServerWatchedPathsBuilder {
13631    worktree_paths: HashMap<WorktreeId, GlobSet>,
13632    abs_paths: HashMap<Arc<Path>, GlobSet>,
13633}
13634
13635impl LanguageServerWatchedPathsBuilder {
13636    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13637        self.worktree_paths.insert(worktree_id, glob_set);
13638    }
13639    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13640        self.abs_paths.insert(path, glob_set);
13641    }
13642    fn build(
13643        self,
13644        fs: Arc<dyn Fs>,
13645        language_server_id: LanguageServerId,
13646        cx: &mut Context<LspStore>,
13647    ) -> LanguageServerWatchedPaths {
13648        let lsp_store = cx.weak_entity();
13649
13650        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13651        let abs_paths = self
13652            .abs_paths
13653            .into_iter()
13654            .map(|(abs_path, globset)| {
13655                let task = cx.spawn({
13656                    let abs_path = abs_path.clone();
13657                    let fs = fs.clone();
13658
13659                    let lsp_store = lsp_store.clone();
13660                    async move |_, cx| {
13661                        maybe!(async move {
13662                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13663                            while let Some(update) = push_updates.0.next().await {
13664                                let action = lsp_store
13665                                    .update(cx, |this, _| {
13666                                        let Some(local) = this.as_local() else {
13667                                            return ControlFlow::Break(());
13668                                        };
13669                                        let Some(watcher) = local
13670                                            .language_server_watched_paths
13671                                            .get(&language_server_id)
13672                                        else {
13673                                            return ControlFlow::Break(());
13674                                        };
13675                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13676                                            "Watched abs path is not registered with a watcher",
13677                                        );
13678                                        let matching_entries = update
13679                                            .into_iter()
13680                                            .filter(|event| globs.is_match(&event.path))
13681                                            .collect::<Vec<_>>();
13682                                        this.lsp_notify_abs_paths_changed(
13683                                            language_server_id,
13684                                            matching_entries,
13685                                        );
13686                                        ControlFlow::Continue(())
13687                                    })
13688                                    .ok()?;
13689
13690                                if action.is_break() {
13691                                    break;
13692                                }
13693                            }
13694                            Some(())
13695                        })
13696                        .await;
13697                    }
13698                });
13699                (abs_path, (globset, task))
13700            })
13701            .collect();
13702        LanguageServerWatchedPaths {
13703            worktree_paths: self.worktree_paths,
13704            abs_paths,
13705        }
13706    }
13707}
13708
13709struct LspBufferSnapshot {
13710    version: i32,
13711    snapshot: TextBufferSnapshot,
13712}
13713
13714/// A prompt requested by LSP server.
13715#[derive(Clone, Debug)]
13716pub struct LanguageServerPromptRequest {
13717    pub id: usize,
13718    pub level: PromptLevel,
13719    pub message: String,
13720    pub actions: Vec<MessageActionItem>,
13721    pub lsp_name: String,
13722    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13723}
13724
13725impl LanguageServerPromptRequest {
13726    pub fn new(
13727        level: PromptLevel,
13728        message: String,
13729        actions: Vec<MessageActionItem>,
13730        lsp_name: String,
13731        response_channel: smol::channel::Sender<MessageActionItem>,
13732    ) -> Self {
13733        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13734        LanguageServerPromptRequest {
13735            id,
13736            level,
13737            message,
13738            actions,
13739            lsp_name,
13740            response_channel,
13741        }
13742    }
13743    pub async fn respond(self, index: usize) -> Option<()> {
13744        if let Some(response) = self.actions.into_iter().nth(index) {
13745            self.response_channel.send(response).await.ok()
13746        } else {
13747            None
13748        }
13749    }
13750
13751    #[cfg(any(test, feature = "test-support"))]
13752    pub fn test(
13753        level: PromptLevel,
13754        message: String,
13755        actions: Vec<MessageActionItem>,
13756        lsp_name: String,
13757    ) -> Self {
13758        let (tx, _rx) = smol::channel::unbounded();
13759        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13760    }
13761}
13762impl PartialEq for LanguageServerPromptRequest {
13763    fn eq(&self, other: &Self) -> bool {
13764        self.message == other.message && self.actions == other.actions
13765    }
13766}
13767
13768#[derive(Clone, Debug, PartialEq)]
13769pub enum LanguageServerLogType {
13770    Log(MessageType),
13771    Trace { verbose_info: Option<String> },
13772    Rpc { received: bool },
13773}
13774
13775impl LanguageServerLogType {
13776    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13777        match self {
13778            Self::Log(log_type) => {
13779                use proto::log_message::LogLevel;
13780                let level = match *log_type {
13781                    MessageType::ERROR => LogLevel::Error,
13782                    MessageType::WARNING => LogLevel::Warning,
13783                    MessageType::INFO => LogLevel::Info,
13784                    MessageType::LOG => LogLevel::Log,
13785                    other => {
13786                        log::warn!("Unknown lsp log message type: {other:?}");
13787                        LogLevel::Log
13788                    }
13789                };
13790                proto::language_server_log::LogType::Log(proto::LogMessage {
13791                    level: level as i32,
13792                })
13793            }
13794            Self::Trace { verbose_info } => {
13795                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13796                    verbose_info: verbose_info.to_owned(),
13797                })
13798            }
13799            Self::Rpc { received } => {
13800                let kind = if *received {
13801                    proto::rpc_message::Kind::Received
13802                } else {
13803                    proto::rpc_message::Kind::Sent
13804                };
13805                let kind = kind as i32;
13806                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13807            }
13808        }
13809    }
13810
13811    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13812        use proto::log_message::LogLevel;
13813        use proto::rpc_message;
13814        match log_type {
13815            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13816                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13817                    LogLevel::Error => MessageType::ERROR,
13818                    LogLevel::Warning => MessageType::WARNING,
13819                    LogLevel::Info => MessageType::INFO,
13820                    LogLevel::Log => MessageType::LOG,
13821                },
13822            ),
13823            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13824                verbose_info: trace_message.verbose_info,
13825            },
13826            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13827                received: match rpc_message::Kind::from_i32(message.kind)
13828                    .unwrap_or(rpc_message::Kind::Received)
13829                {
13830                    rpc_message::Kind::Received => true,
13831                    rpc_message::Kind::Sent => false,
13832                },
13833            },
13834        }
13835    }
13836}
13837
13838pub struct WorkspaceRefreshTask {
13839    refresh_tx: mpsc::Sender<()>,
13840    progress_tx: mpsc::Sender<()>,
13841    #[allow(dead_code)]
13842    task: Task<()>,
13843}
13844
13845pub enum LanguageServerState {
13846    Starting {
13847        startup: Task<Option<Arc<LanguageServer>>>,
13848        /// List of language servers that will be added to the workspace once it's initialization completes.
13849        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13850    },
13851
13852    Running {
13853        adapter: Arc<CachedLspAdapter>,
13854        server: Arc<LanguageServer>,
13855        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13856        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13857    },
13858}
13859
13860impl LanguageServerState {
13861    fn add_workspace_folder(&self, uri: Uri) {
13862        match self {
13863            LanguageServerState::Starting {
13864                pending_workspace_folders,
13865                ..
13866            } => {
13867                pending_workspace_folders.lock().insert(uri);
13868            }
13869            LanguageServerState::Running { server, .. } => {
13870                server.add_workspace_folder(uri);
13871            }
13872        }
13873    }
13874    fn _remove_workspace_folder(&self, uri: Uri) {
13875        match self {
13876            LanguageServerState::Starting {
13877                pending_workspace_folders,
13878                ..
13879            } => {
13880                pending_workspace_folders.lock().remove(&uri);
13881            }
13882            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13883        }
13884    }
13885}
13886
13887impl std::fmt::Debug for LanguageServerState {
13888    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13889        match self {
13890            LanguageServerState::Starting { .. } => {
13891                f.debug_struct("LanguageServerState::Starting").finish()
13892            }
13893            LanguageServerState::Running { .. } => {
13894                f.debug_struct("LanguageServerState::Running").finish()
13895            }
13896        }
13897    }
13898}
13899
13900#[derive(Clone, Debug, Serialize)]
13901pub struct LanguageServerProgress {
13902    pub is_disk_based_diagnostics_progress: bool,
13903    pub is_cancellable: bool,
13904    pub title: Option<String>,
13905    pub message: Option<String>,
13906    pub percentage: Option<usize>,
13907    #[serde(skip_serializing)]
13908    pub last_update_at: Instant,
13909}
13910
13911#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13912pub struct DiagnosticSummary {
13913    pub error_count: usize,
13914    pub warning_count: usize,
13915}
13916
13917impl DiagnosticSummary {
13918    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13919        let mut this = Self {
13920            error_count: 0,
13921            warning_count: 0,
13922        };
13923
13924        for entry in diagnostics {
13925            if entry.diagnostic.is_primary {
13926                match entry.diagnostic.severity {
13927                    DiagnosticSeverity::ERROR => this.error_count += 1,
13928                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13929                    _ => {}
13930                }
13931            }
13932        }
13933
13934        this
13935    }
13936
13937    pub fn is_empty(&self) -> bool {
13938        self.error_count == 0 && self.warning_count == 0
13939    }
13940
13941    pub fn to_proto(
13942        self,
13943        language_server_id: LanguageServerId,
13944        path: &RelPath,
13945    ) -> proto::DiagnosticSummary {
13946        proto::DiagnosticSummary {
13947            path: path.to_proto(),
13948            language_server_id: language_server_id.0 as u64,
13949            error_count: self.error_count as u32,
13950            warning_count: self.warning_count as u32,
13951        }
13952    }
13953}
13954
13955#[derive(Clone, Debug)]
13956pub enum CompletionDocumentation {
13957    /// There is no documentation for this completion.
13958    Undocumented,
13959    /// A single line of documentation.
13960    SingleLine(SharedString),
13961    /// Multiple lines of plain text documentation.
13962    MultiLinePlainText(SharedString),
13963    /// Markdown documentation.
13964    MultiLineMarkdown(SharedString),
13965    /// Both single line and multiple lines of plain text documentation.
13966    SingleLineAndMultiLinePlainText {
13967        single_line: SharedString,
13968        plain_text: Option<SharedString>,
13969    },
13970}
13971
13972impl CompletionDocumentation {
13973    #[cfg(any(test, feature = "test-support"))]
13974    pub fn text(&self) -> SharedString {
13975        match self {
13976            CompletionDocumentation::Undocumented => "".into(),
13977            CompletionDocumentation::SingleLine(s) => s.clone(),
13978            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13979            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13980            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13981                single_line.clone()
13982            }
13983        }
13984    }
13985}
13986
13987impl From<lsp::Documentation> for CompletionDocumentation {
13988    fn from(docs: lsp::Documentation) -> Self {
13989        match docs {
13990            lsp::Documentation::String(text) => {
13991                if text.lines().count() <= 1 {
13992                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
13993                } else {
13994                    CompletionDocumentation::MultiLinePlainText(text.into())
13995                }
13996            }
13997
13998            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13999                lsp::MarkupKind::PlainText => {
14000                    if value.lines().count() <= 1 {
14001                        CompletionDocumentation::SingleLine(value.into())
14002                    } else {
14003                        CompletionDocumentation::MultiLinePlainText(value.into())
14004                    }
14005                }
14006
14007                lsp::MarkupKind::Markdown => {
14008                    CompletionDocumentation::MultiLineMarkdown(value.into())
14009                }
14010            },
14011        }
14012    }
14013}
14014
14015pub enum ResolvedHint {
14016    Resolved(InlayHint),
14017    Resolving(Shared<Task<()>>),
14018}
14019
14020pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
14021    glob.components()
14022        .take_while(|component| match component {
14023            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
14024            _ => true,
14025        })
14026        .collect()
14027}
14028
14029pub struct SshLspAdapter {
14030    name: LanguageServerName,
14031    binary: LanguageServerBinary,
14032    initialization_options: Option<String>,
14033    code_action_kinds: Option<Vec<CodeActionKind>>,
14034}
14035
14036impl SshLspAdapter {
14037    pub fn new(
14038        name: LanguageServerName,
14039        binary: LanguageServerBinary,
14040        initialization_options: Option<String>,
14041        code_action_kinds: Option<String>,
14042    ) -> Self {
14043        Self {
14044            name,
14045            binary,
14046            initialization_options,
14047            code_action_kinds: code_action_kinds
14048                .as_ref()
14049                .and_then(|c| serde_json::from_str(c).ok()),
14050        }
14051    }
14052}
14053
14054impl LspInstaller for SshLspAdapter {
14055    type BinaryVersion = ();
14056    async fn check_if_user_installed(
14057        &self,
14058        _: &dyn LspAdapterDelegate,
14059        _: Option<Toolchain>,
14060        _: &AsyncApp,
14061    ) -> Option<LanguageServerBinary> {
14062        Some(self.binary.clone())
14063    }
14064
14065    async fn cached_server_binary(
14066        &self,
14067        _: PathBuf,
14068        _: &dyn LspAdapterDelegate,
14069    ) -> Option<LanguageServerBinary> {
14070        None
14071    }
14072
14073    async fn fetch_latest_server_version(
14074        &self,
14075        _: &dyn LspAdapterDelegate,
14076        _: bool,
14077        _: &mut AsyncApp,
14078    ) -> Result<()> {
14079        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14080    }
14081
14082    async fn fetch_server_binary(
14083        &self,
14084        _: (),
14085        _: PathBuf,
14086        _: &dyn LspAdapterDelegate,
14087    ) -> Result<LanguageServerBinary> {
14088        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14089    }
14090}
14091
14092#[async_trait(?Send)]
14093impl LspAdapter for SshLspAdapter {
14094    fn name(&self) -> LanguageServerName {
14095        self.name.clone()
14096    }
14097
14098    async fn initialization_options(
14099        self: Arc<Self>,
14100        _: &Arc<dyn LspAdapterDelegate>,
14101        _: &mut AsyncApp,
14102    ) -> Result<Option<serde_json::Value>> {
14103        let Some(options) = &self.initialization_options else {
14104            return Ok(None);
14105        };
14106        let result = serde_json::from_str(options)?;
14107        Ok(result)
14108    }
14109
14110    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14111        self.code_action_kinds.clone()
14112    }
14113}
14114
14115pub fn language_server_settings<'a>(
14116    delegate: &'a dyn LspAdapterDelegate,
14117    language: &LanguageServerName,
14118    cx: &'a App,
14119) -> Option<&'a LspSettings> {
14120    language_server_settings_for(
14121        SettingsLocation {
14122            worktree_id: delegate.worktree_id(),
14123            path: RelPath::empty(),
14124        },
14125        language,
14126        cx,
14127    )
14128}
14129
14130pub fn language_server_settings_for<'a>(
14131    location: SettingsLocation<'a>,
14132    language: &LanguageServerName,
14133    cx: &'a App,
14134) -> Option<&'a LspSettings> {
14135    ProjectSettings::get(Some(location), cx).lsp.get(language)
14136}
14137
14138pub struct LocalLspAdapterDelegate {
14139    lsp_store: WeakEntity<LspStore>,
14140    worktree: worktree::Snapshot,
14141    fs: Arc<dyn Fs>,
14142    http_client: Arc<dyn HttpClient>,
14143    language_registry: Arc<LanguageRegistry>,
14144    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14145}
14146
14147impl LocalLspAdapterDelegate {
14148    pub fn new(
14149        language_registry: Arc<LanguageRegistry>,
14150        environment: &Entity<ProjectEnvironment>,
14151        lsp_store: WeakEntity<LspStore>,
14152        worktree: &Entity<Worktree>,
14153        http_client: Arc<dyn HttpClient>,
14154        fs: Arc<dyn Fs>,
14155        cx: &mut App,
14156    ) -> Arc<Self> {
14157        let load_shell_env_task =
14158            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14159
14160        Arc::new(Self {
14161            lsp_store,
14162            worktree: worktree.read(cx).snapshot(),
14163            fs,
14164            http_client,
14165            language_registry,
14166            load_shell_env_task,
14167        })
14168    }
14169
14170    pub fn from_local_lsp(
14171        local: &LocalLspStore,
14172        worktree: &Entity<Worktree>,
14173        cx: &mut App,
14174    ) -> Arc<Self> {
14175        Self::new(
14176            local.languages.clone(),
14177            &local.environment,
14178            local.weak.clone(),
14179            worktree,
14180            local.http_client.clone(),
14181            local.fs.clone(),
14182            cx,
14183        )
14184    }
14185}
14186
14187#[async_trait]
14188impl LspAdapterDelegate for LocalLspAdapterDelegate {
14189    fn show_notification(&self, message: &str, cx: &mut App) {
14190        self.lsp_store
14191            .update(cx, |_, cx| {
14192                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14193            })
14194            .ok();
14195    }
14196
14197    fn http_client(&self) -> Arc<dyn HttpClient> {
14198        self.http_client.clone()
14199    }
14200
14201    fn worktree_id(&self) -> WorktreeId {
14202        self.worktree.id()
14203    }
14204
14205    fn worktree_root_path(&self) -> &Path {
14206        self.worktree.abs_path().as_ref()
14207    }
14208
14209    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14210        self.worktree.resolve_relative_path(path)
14211    }
14212
14213    async fn shell_env(&self) -> HashMap<String, String> {
14214        let task = self.load_shell_env_task.clone();
14215        task.await.unwrap_or_default()
14216    }
14217
14218    async fn npm_package_installed_version(
14219        &self,
14220        package_name: &str,
14221    ) -> Result<Option<(PathBuf, Version)>> {
14222        let local_package_directory = self.worktree_root_path();
14223        let node_modules_directory = local_package_directory.join("node_modules");
14224
14225        if let Some(version) =
14226            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14227        {
14228            return Ok(Some((node_modules_directory, version)));
14229        }
14230        let Some(npm) = self.which("npm".as_ref()).await else {
14231            log::warn!(
14232                "Failed to find npm executable for {:?}",
14233                local_package_directory
14234            );
14235            return Ok(None);
14236        };
14237
14238        let env = self.shell_env().await;
14239        let output = util::command::new_command(&npm)
14240            .args(["root", "-g"])
14241            .envs(env)
14242            .current_dir(local_package_directory)
14243            .output()
14244            .await?;
14245        let global_node_modules =
14246            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14247
14248        if let Some(version) =
14249            read_package_installed_version(global_node_modules.clone(), package_name).await?
14250        {
14251            return Ok(Some((global_node_modules, version)));
14252        }
14253        return Ok(None);
14254    }
14255
14256    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14257        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14258        if self.fs.is_file(&worktree_abs_path).await {
14259            worktree_abs_path.pop();
14260        }
14261
14262        let env = self.shell_env().await;
14263
14264        let shell_path = env.get("PATH").cloned();
14265
14266        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14267    }
14268
14269    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14270        let mut working_dir = self.worktree_root_path().to_path_buf();
14271        if self.fs.is_file(&working_dir).await {
14272            working_dir.pop();
14273        }
14274        let output = util::command::new_command(&command.path)
14275            .args(command.arguments)
14276            .envs(command.env.clone().unwrap_or_default())
14277            .current_dir(working_dir)
14278            .output()
14279            .await?;
14280
14281        anyhow::ensure!(
14282            output.status.success(),
14283            "{}, stdout: {:?}, stderr: {:?}",
14284            output.status,
14285            String::from_utf8_lossy(&output.stdout),
14286            String::from_utf8_lossy(&output.stderr)
14287        );
14288        Ok(())
14289    }
14290
14291    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14292        self.language_registry
14293            .update_lsp_binary_status(server_name, status);
14294    }
14295
14296    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14297        self.language_registry
14298            .all_lsp_adapters()
14299            .into_iter()
14300            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14301            .collect()
14302    }
14303
14304    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14305        let dir = self.language_registry.language_server_download_dir(name)?;
14306
14307        if !dir.exists() {
14308            smol::fs::create_dir_all(&dir)
14309                .await
14310                .context("failed to create container directory")
14311                .log_err()?;
14312        }
14313
14314        Some(dir)
14315    }
14316
14317    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14318        let entry = self
14319            .worktree
14320            .entry_for_path(path)
14321            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14322        let abs_path = self.worktree.absolutize(&entry.path);
14323        self.fs.load(&abs_path).await
14324    }
14325}
14326
14327async fn populate_labels_for_symbols(
14328    symbols: Vec<CoreSymbol>,
14329    language_registry: &Arc<LanguageRegistry>,
14330    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14331    output: &mut Vec<Symbol>,
14332) {
14333    #[allow(clippy::mutable_key_type)]
14334    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14335
14336    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14337    for symbol in symbols {
14338        let Some(file_name) = symbol.path.file_name() else {
14339            continue;
14340        };
14341        let language = language_registry
14342            .load_language_for_file_path(Path::new(file_name))
14343            .await
14344            .ok()
14345            .or_else(|| {
14346                unknown_paths.insert(file_name.into());
14347                None
14348            });
14349        symbols_by_language
14350            .entry(language)
14351            .or_default()
14352            .push(symbol);
14353    }
14354
14355    for unknown_path in unknown_paths {
14356        log::info!("no language found for symbol in file {unknown_path:?}");
14357    }
14358
14359    let mut label_params = Vec::new();
14360    for (language, mut symbols) in symbols_by_language {
14361        label_params.clear();
14362        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14363            name: mem::take(&mut symbol.name),
14364            kind: symbol.kind,
14365            container_name: symbol.container_name.take(),
14366        }));
14367
14368        let mut labels = Vec::new();
14369        if let Some(language) = language {
14370            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14371                language_registry
14372                    .lsp_adapters(&language.name())
14373                    .first()
14374                    .cloned()
14375            });
14376            if let Some(lsp_adapter) = lsp_adapter {
14377                labels = lsp_adapter
14378                    .labels_for_symbols(&label_params, &language)
14379                    .await
14380                    .log_err()
14381                    .unwrap_or_default();
14382            }
14383        }
14384
14385        for (
14386            (
14387                symbol,
14388                language::Symbol {
14389                    name,
14390                    container_name,
14391                    ..
14392                },
14393            ),
14394            label,
14395        ) in symbols
14396            .into_iter()
14397            .zip(label_params.drain(..))
14398            .zip(labels.into_iter().chain(iter::repeat(None)))
14399        {
14400            output.push(Symbol {
14401                language_server_name: symbol.language_server_name,
14402                source_worktree_id: symbol.source_worktree_id,
14403                source_language_server_id: symbol.source_language_server_id,
14404                path: symbol.path,
14405                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14406                name,
14407                kind: symbol.kind,
14408                range: symbol.range,
14409                container_name,
14410            });
14411        }
14412    }
14413}
14414
14415pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String {
14416    text.lines()
14417        .map(|line| line.trim())
14418        .filter(|line| !line.is_empty())
14419        .join(separator)
14420}
14421
14422fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14423    match server.capabilities().text_document_sync.as_ref()? {
14424        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14425            // Server wants didSave but didn't specify includeText.
14426            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14427            // Server doesn't want didSave at all.
14428            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14429            // Server provided SaveOptions.
14430            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14431                Some(save_options.include_text.unwrap_or(false))
14432            }
14433        },
14434        // We do not have any save info. Kind affects didChange only.
14435        lsp::TextDocumentSyncCapability::Kind(_) => None,
14436    }
14437}
14438
14439/// Completion items are displayed in a `UniformList`.
14440/// Usually, those items are single-line strings, but in LSP responses,
14441/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14442/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14443/// 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,
14444/// breaking the completions menu presentation.
14445///
14446/// 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.
14447pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14448    let mut new_text = String::with_capacity(label.text.len());
14449    let mut offset_map = vec![0; label.text.len() + 1];
14450    let mut last_char_was_space = false;
14451    let mut new_idx = 0;
14452    let chars = label.text.char_indices().fuse();
14453    let mut newlines_removed = false;
14454
14455    for (idx, c) in chars {
14456        offset_map[idx] = new_idx;
14457
14458        match c {
14459            '\n' if last_char_was_space => {
14460                newlines_removed = true;
14461            }
14462            '\t' | ' ' if last_char_was_space => {}
14463            '\n' if !last_char_was_space => {
14464                new_text.push(' ');
14465                new_idx += 1;
14466                last_char_was_space = true;
14467                newlines_removed = true;
14468            }
14469            ' ' | '\t' => {
14470                new_text.push(' ');
14471                new_idx += 1;
14472                last_char_was_space = true;
14473            }
14474            _ => {
14475                new_text.push(c);
14476                new_idx += c.len_utf8();
14477                last_char_was_space = false;
14478            }
14479        }
14480    }
14481    offset_map[label.text.len()] = new_idx;
14482
14483    // Only modify the label if newlines were removed.
14484    if !newlines_removed {
14485        return;
14486    }
14487
14488    let last_index = new_idx;
14489    let mut run_ranges_errors = Vec::new();
14490    label.runs.retain_mut(|(range, _)| {
14491        match offset_map.get(range.start) {
14492            Some(&start) => range.start = start,
14493            None => {
14494                run_ranges_errors.push(range.clone());
14495                return false;
14496            }
14497        }
14498
14499        match offset_map.get(range.end) {
14500            Some(&end) => range.end = end,
14501            None => {
14502                run_ranges_errors.push(range.clone());
14503                range.end = last_index;
14504            }
14505        }
14506        true
14507    });
14508    if !run_ranges_errors.is_empty() {
14509        log::error!(
14510            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14511            label.text
14512        );
14513    }
14514
14515    let mut wrong_filter_range = None;
14516    if label.filter_range == (0..label.text.len()) {
14517        label.filter_range = 0..new_text.len();
14518    } else {
14519        let mut original_filter_range = Some(label.filter_range.clone());
14520        match offset_map.get(label.filter_range.start) {
14521            Some(&start) => label.filter_range.start = start,
14522            None => {
14523                wrong_filter_range = original_filter_range.take();
14524                label.filter_range.start = last_index;
14525            }
14526        }
14527
14528        match offset_map.get(label.filter_range.end) {
14529            Some(&end) => label.filter_range.end = end,
14530            None => {
14531                wrong_filter_range = original_filter_range.take();
14532                label.filter_range.end = last_index;
14533            }
14534        }
14535    }
14536    if let Some(wrong_filter_range) = wrong_filter_range {
14537        log::error!(
14538            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14539            label.text
14540        );
14541    }
14542
14543    label.text = new_text;
14544}